]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blob - sound/pci/hda/patch_realtek.c
ALSA: hda - Use macros to check array overflow
[mirror_ubuntu-bionic-kernel.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_patch.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 #ifdef CONFIG_SND_DEBUG
82 ALC260_TEST,
83 #endif
84 ALC260_AUTO,
85 ALC260_MODEL_LAST /* last tag */
86 };
87
88 /* ALC262 models */
89 enum {
90 ALC262_BASIC,
91 ALC262_HIPPO,
92 ALC262_HIPPO_1,
93 ALC262_FUJITSU,
94 ALC262_HP_BPC,
95 ALC262_HP_BPC_D7000_WL,
96 ALC262_HP_BPC_D7000_WF,
97 ALC262_HP_TC_T5735,
98 ALC262_HP_RP5700,
99 ALC262_BENQ_ED8,
100 ALC262_SONY_ASSAMD,
101 ALC262_BENQ_T31,
102 ALC262_ULTRA,
103 ALC262_LENOVO_3000,
104 ALC262_NEC,
105 ALC262_TOSHIBA_S06,
106 ALC262_TOSHIBA_RX1,
107 ALC262_AUTO,
108 ALC262_MODEL_LAST /* last tag */
109 };
110
111 /* ALC268 models */
112 enum {
113 ALC267_QUANTA_IL1,
114 ALC268_3ST,
115 ALC268_TOSHIBA,
116 ALC268_ACER,
117 ALC268_ACER_ASPIRE_ONE,
118 ALC268_DELL,
119 ALC268_ZEPTO,
120 #ifdef CONFIG_SND_DEBUG
121 ALC268_TEST,
122 #endif
123 ALC268_AUTO,
124 ALC268_MODEL_LAST /* last tag */
125 };
126
127 /* ALC269 models */
128 enum {
129 ALC269_BASIC,
130 ALC269_QUANTA_FL1,
131 ALC269_ASUS_EEEPC_P703,
132 ALC269_ASUS_EEEPC_P901,
133 ALC269_AUTO,
134 ALC269_MODEL_LAST /* last tag */
135 };
136
137 /* ALC861 models */
138 enum {
139 ALC861_3ST,
140 ALC660_3ST,
141 ALC861_3ST_DIG,
142 ALC861_6ST_DIG,
143 ALC861_UNIWILL_M31,
144 ALC861_TOSHIBA,
145 ALC861_ASUS,
146 ALC861_ASUS_LAPTOP,
147 ALC861_AUTO,
148 ALC861_MODEL_LAST,
149 };
150
151 /* ALC861-VD models */
152 enum {
153 ALC660VD_3ST,
154 ALC660VD_3ST_DIG,
155 ALC861VD_3ST,
156 ALC861VD_3ST_DIG,
157 ALC861VD_6ST_DIG,
158 ALC861VD_LENOVO,
159 ALC861VD_DALLAS,
160 ALC861VD_HP,
161 ALC861VD_AUTO,
162 ALC861VD_MODEL_LAST,
163 };
164
165 /* ALC662 models */
166 enum {
167 ALC662_3ST_2ch_DIG,
168 ALC662_3ST_6ch_DIG,
169 ALC662_3ST_6ch,
170 ALC662_5ST_DIG,
171 ALC662_LENOVO_101E,
172 ALC662_ASUS_EEEPC_P701,
173 ALC662_ASUS_EEEPC_EP20,
174 ALC663_ASUS_M51VA,
175 ALC663_ASUS_G71V,
176 ALC663_ASUS_H13,
177 ALC663_ASUS_G50V,
178 ALC662_ECS,
179 ALC663_ASUS_MODE1,
180 ALC662_ASUS_MODE2,
181 ALC663_ASUS_MODE3,
182 ALC663_ASUS_MODE4,
183 ALC663_ASUS_MODE5,
184 ALC663_ASUS_MODE6,
185 ALC662_AUTO,
186 ALC662_MODEL_LAST,
187 };
188
189 /* ALC882 models */
190 enum {
191 ALC882_3ST_DIG,
192 ALC882_6ST_DIG,
193 ALC882_ARIMA,
194 ALC882_W2JC,
195 ALC882_TARGA,
196 ALC882_ASUS_A7J,
197 ALC882_ASUS_A7M,
198 ALC885_MACPRO,
199 ALC885_MBP3,
200 ALC885_IMAC24,
201 ALC882_AUTO,
202 ALC882_MODEL_LAST,
203 };
204
205 /* ALC883 models */
206 enum {
207 ALC883_3ST_2ch_DIG,
208 ALC883_3ST_6ch_DIG,
209 ALC883_3ST_6ch,
210 ALC883_6ST_DIG,
211 ALC883_TARGA_DIG,
212 ALC883_TARGA_2ch_DIG,
213 ALC883_ACER,
214 ALC883_ACER_ASPIRE,
215 ALC883_MEDION,
216 ALC883_MEDION_MD2,
217 ALC883_LAPTOP_EAPD,
218 ALC883_LENOVO_101E_2ch,
219 ALC883_LENOVO_NB0763,
220 ALC888_LENOVO_MS7195_DIG,
221 ALC888_LENOVO_SKY,
222 ALC883_HAIER_W66,
223 ALC888_3ST_HP,
224 ALC888_6ST_DELL,
225 ALC883_MITAC,
226 ALC883_CLEVO_M720,
227 ALC883_FUJITSU_PI2515,
228 ALC883_3ST_6ch_INTEL,
229 ALC888_ASUS_M90V,
230 ALC888_ASUS_EEE1601,
231 ALC883_AUTO,
232 ALC883_MODEL_LAST,
233 };
234
235 /* for GPIO Poll */
236 #define GPIO_MASK 0x03
237
238 struct alc_spec {
239 /* codec parameterization */
240 struct snd_kcontrol_new *mixers[5]; /* mixer arrays */
241 unsigned int num_mixers;
242
243 const struct hda_verb *init_verbs[5]; /* initialization verbs
244 * don't forget NULL
245 * termination!
246 */
247 unsigned int num_init_verbs;
248
249 char *stream_name_analog; /* analog PCM stream */
250 struct hda_pcm_stream *stream_analog_playback;
251 struct hda_pcm_stream *stream_analog_capture;
252 struct hda_pcm_stream *stream_analog_alt_playback;
253 struct hda_pcm_stream *stream_analog_alt_capture;
254
255 char *stream_name_digital; /* digital PCM stream */
256 struct hda_pcm_stream *stream_digital_playback;
257 struct hda_pcm_stream *stream_digital_capture;
258
259 /* playback */
260 struct hda_multi_out multiout; /* playback set-up
261 * max_channels, dacs must be set
262 * dig_out_nid and hp_nid are optional
263 */
264 hda_nid_t alt_dac_nid;
265
266 /* capture */
267 unsigned int num_adc_nids;
268 hda_nid_t *adc_nids;
269 hda_nid_t *capsrc_nids;
270 hda_nid_t dig_in_nid; /* digital-in NID; optional */
271
272 /* capture source */
273 unsigned int num_mux_defs;
274 const struct hda_input_mux *input_mux;
275 unsigned int cur_mux[3];
276
277 /* channel model */
278 const struct hda_channel_mode *channel_mode;
279 int num_channel_mode;
280 int need_dac_fix;
281
282 /* PCM information */
283 struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */
284
285 /* dynamic controls, init_verbs and input_mux */
286 struct auto_pin_cfg autocfg;
287 struct snd_array kctls;
288 struct hda_input_mux private_imux;
289 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
290
291 /* hooks */
292 void (*init_hook)(struct hda_codec *codec);
293 void (*unsol_event)(struct hda_codec *codec, unsigned int res);
294
295 /* for pin sensing */
296 unsigned int sense_updated: 1;
297 unsigned int jack_present: 1;
298 unsigned int master_sw: 1;
299
300 /* for virtual master */
301 hda_nid_t vmaster_nid;
302 #ifdef CONFIG_SND_HDA_POWER_SAVE
303 struct hda_loopback_check loopback;
304 #endif
305
306 /* for PLL fix */
307 hda_nid_t pll_nid;
308 unsigned int pll_coef_idx, pll_coef_bit;
309
310 #ifdef SND_HDA_NEEDS_RESUME
311 #define ALC_MAX_PINS 16
312 unsigned int num_pins;
313 hda_nid_t pin_nids[ALC_MAX_PINS];
314 unsigned int pin_cfgs[ALC_MAX_PINS];
315 #endif
316 };
317
318 /*
319 * configuration template - to be copied to the spec instance
320 */
321 struct alc_config_preset {
322 struct snd_kcontrol_new *mixers[5]; /* should be identical size
323 * with spec
324 */
325 const struct hda_verb *init_verbs[5];
326 unsigned int num_dacs;
327 hda_nid_t *dac_nids;
328 hda_nid_t dig_out_nid; /* optional */
329 hda_nid_t hp_nid; /* optional */
330 unsigned int num_adc_nids;
331 hda_nid_t *adc_nids;
332 hda_nid_t *capsrc_nids;
333 hda_nid_t dig_in_nid;
334 unsigned int num_channel_mode;
335 const struct hda_channel_mode *channel_mode;
336 int need_dac_fix;
337 unsigned int num_mux_defs;
338 const struct hda_input_mux *input_mux;
339 void (*unsol_event)(struct hda_codec *, unsigned int);
340 void (*init_hook)(struct hda_codec *);
341 #ifdef CONFIG_SND_HDA_POWER_SAVE
342 struct hda_amp_list *loopbacks;
343 #endif
344 };
345
346
347 /*
348 * input MUX handling
349 */
350 static int alc_mux_enum_info(struct snd_kcontrol *kcontrol,
351 struct snd_ctl_elem_info *uinfo)
352 {
353 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
354 struct alc_spec *spec = codec->spec;
355 unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id);
356 if (mux_idx >= spec->num_mux_defs)
357 mux_idx = 0;
358 return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo);
359 }
360
361 static int alc_mux_enum_get(struct snd_kcontrol *kcontrol,
362 struct snd_ctl_elem_value *ucontrol)
363 {
364 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
365 struct alc_spec *spec = codec->spec;
366 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
367
368 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
369 return 0;
370 }
371
372 static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
373 struct snd_ctl_elem_value *ucontrol)
374 {
375 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
376 struct alc_spec *spec = codec->spec;
377 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
378 unsigned int mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
379 hda_nid_t nid = spec->capsrc_nids ?
380 spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx];
381 return snd_hda_input_mux_put(codec, &spec->input_mux[mux_idx], ucontrol,
382 nid, &spec->cur_mux[adc_idx]);
383 }
384
385
386 /*
387 * channel mode setting
388 */
389 static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
390 struct snd_ctl_elem_info *uinfo)
391 {
392 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
393 struct alc_spec *spec = codec->spec;
394 return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
395 spec->num_channel_mode);
396 }
397
398 static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
399 struct snd_ctl_elem_value *ucontrol)
400 {
401 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
402 struct alc_spec *spec = codec->spec;
403 return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
404 spec->num_channel_mode,
405 spec->multiout.max_channels);
406 }
407
408 static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
409 struct snd_ctl_elem_value *ucontrol)
410 {
411 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
412 struct alc_spec *spec = codec->spec;
413 int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
414 spec->num_channel_mode,
415 &spec->multiout.max_channels);
416 if (err >= 0 && spec->need_dac_fix)
417 spec->multiout.num_dacs = spec->multiout.max_channels / 2;
418 return err;
419 }
420
421 /*
422 * Control the mode of pin widget settings via the mixer. "pc" is used
423 * instead of "%" to avoid consequences of accidently treating the % as
424 * being part of a format specifier. Maximum allowed length of a value is
425 * 63 characters plus NULL terminator.
426 *
427 * Note: some retasking pin complexes seem to ignore requests for input
428 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
429 * are requested. Therefore order this list so that this behaviour will not
430 * cause problems when mixer clients move through the enum sequentially.
431 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
432 * March 2006.
433 */
434 static char *alc_pin_mode_names[] = {
435 "Mic 50pc bias", "Mic 80pc bias",
436 "Line in", "Line out", "Headphone out",
437 };
438 static unsigned char alc_pin_mode_values[] = {
439 PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
440 };
441 /* The control can present all 5 options, or it can limit the options based
442 * in the pin being assumed to be exclusively an input or an output pin. In
443 * addition, "input" pins may or may not process the mic bias option
444 * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
445 * accept requests for bias as of chip versions up to March 2006) and/or
446 * wiring in the computer.
447 */
448 #define ALC_PIN_DIR_IN 0x00
449 #define ALC_PIN_DIR_OUT 0x01
450 #define ALC_PIN_DIR_INOUT 0x02
451 #define ALC_PIN_DIR_IN_NOMICBIAS 0x03
452 #define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
453
454 /* Info about the pin modes supported by the different pin direction modes.
455 * For each direction the minimum and maximum values are given.
456 */
457 static signed char alc_pin_mode_dir_info[5][2] = {
458 { 0, 2 }, /* ALC_PIN_DIR_IN */
459 { 3, 4 }, /* ALC_PIN_DIR_OUT */
460 { 0, 4 }, /* ALC_PIN_DIR_INOUT */
461 { 2, 2 }, /* ALC_PIN_DIR_IN_NOMICBIAS */
462 { 2, 4 }, /* ALC_PIN_DIR_INOUT_NOMICBIAS */
463 };
464 #define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
465 #define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
466 #define alc_pin_mode_n_items(_dir) \
467 (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
468
469 static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
470 struct snd_ctl_elem_info *uinfo)
471 {
472 unsigned int item_num = uinfo->value.enumerated.item;
473 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
474
475 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
476 uinfo->count = 1;
477 uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
478
479 if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
480 item_num = alc_pin_mode_min(dir);
481 strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
482 return 0;
483 }
484
485 static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
486 struct snd_ctl_elem_value *ucontrol)
487 {
488 unsigned int i;
489 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
490 hda_nid_t nid = kcontrol->private_value & 0xffff;
491 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
492 long *valp = ucontrol->value.integer.value;
493 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
494 AC_VERB_GET_PIN_WIDGET_CONTROL,
495 0x00);
496
497 /* Find enumerated value for current pinctl setting */
498 i = alc_pin_mode_min(dir);
499 while (alc_pin_mode_values[i] != pinctl && i <= alc_pin_mode_max(dir))
500 i++;
501 *valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
502 return 0;
503 }
504
505 static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
506 struct snd_ctl_elem_value *ucontrol)
507 {
508 signed int change;
509 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
510 hda_nid_t nid = kcontrol->private_value & 0xffff;
511 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
512 long val = *ucontrol->value.integer.value;
513 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
514 AC_VERB_GET_PIN_WIDGET_CONTROL,
515 0x00);
516
517 if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
518 val = alc_pin_mode_min(dir);
519
520 change = pinctl != alc_pin_mode_values[val];
521 if (change) {
522 /* Set pin mode to that requested */
523 snd_hda_codec_write_cache(codec, nid, 0,
524 AC_VERB_SET_PIN_WIDGET_CONTROL,
525 alc_pin_mode_values[val]);
526
527 /* Also enable the retasking pin's input/output as required
528 * for the requested pin mode. Enum values of 2 or less are
529 * input modes.
530 *
531 * Dynamically switching the input/output buffers probably
532 * reduces noise slightly (particularly on input) so we'll
533 * do it. However, having both input and output buffers
534 * enabled simultaneously doesn't seem to be problematic if
535 * this turns out to be necessary in the future.
536 */
537 if (val <= 2) {
538 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
539 HDA_AMP_MUTE, HDA_AMP_MUTE);
540 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
541 HDA_AMP_MUTE, 0);
542 } else {
543 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
544 HDA_AMP_MUTE, HDA_AMP_MUTE);
545 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
546 HDA_AMP_MUTE, 0);
547 }
548 }
549 return change;
550 }
551
552 #define ALC_PIN_MODE(xname, nid, dir) \
553 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
554 .info = alc_pin_mode_info, \
555 .get = alc_pin_mode_get, \
556 .put = alc_pin_mode_put, \
557 .private_value = nid | (dir<<16) }
558
559 /* A switch control for ALC260 GPIO pins. Multiple GPIOs can be ganged
560 * together using a mask with more than one bit set. This control is
561 * currently used only by the ALC260 test model. At this stage they are not
562 * needed for any "production" models.
563 */
564 #ifdef CONFIG_SND_DEBUG
565 #define alc_gpio_data_info snd_ctl_boolean_mono_info
566
567 static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
568 struct snd_ctl_elem_value *ucontrol)
569 {
570 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
571 hda_nid_t nid = kcontrol->private_value & 0xffff;
572 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
573 long *valp = ucontrol->value.integer.value;
574 unsigned int val = snd_hda_codec_read(codec, nid, 0,
575 AC_VERB_GET_GPIO_DATA, 0x00);
576
577 *valp = (val & mask) != 0;
578 return 0;
579 }
580 static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
581 struct snd_ctl_elem_value *ucontrol)
582 {
583 signed int change;
584 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
585 hda_nid_t nid = kcontrol->private_value & 0xffff;
586 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
587 long val = *ucontrol->value.integer.value;
588 unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
589 AC_VERB_GET_GPIO_DATA,
590 0x00);
591
592 /* Set/unset the masked GPIO bit(s) as needed */
593 change = (val == 0 ? 0 : mask) != (gpio_data & mask);
594 if (val == 0)
595 gpio_data &= ~mask;
596 else
597 gpio_data |= mask;
598 snd_hda_codec_write_cache(codec, nid, 0,
599 AC_VERB_SET_GPIO_DATA, gpio_data);
600
601 return change;
602 }
603 #define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
604 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
605 .info = alc_gpio_data_info, \
606 .get = alc_gpio_data_get, \
607 .put = alc_gpio_data_put, \
608 .private_value = nid | (mask<<16) }
609 #endif /* CONFIG_SND_DEBUG */
610
611 /* A switch control to allow the enabling of the digital IO pins on the
612 * ALC260. This is incredibly simplistic; the intention of this control is
613 * to provide something in the test model allowing digital outputs to be
614 * identified if present. If models are found which can utilise these
615 * outputs a more complete mixer control can be devised for those models if
616 * necessary.
617 */
618 #ifdef CONFIG_SND_DEBUG
619 #define alc_spdif_ctrl_info snd_ctl_boolean_mono_info
620
621 static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
622 struct snd_ctl_elem_value *ucontrol)
623 {
624 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
625 hda_nid_t nid = kcontrol->private_value & 0xffff;
626 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
627 long *valp = ucontrol->value.integer.value;
628 unsigned int val = snd_hda_codec_read(codec, nid, 0,
629 AC_VERB_GET_DIGI_CONVERT_1, 0x00);
630
631 *valp = (val & mask) != 0;
632 return 0;
633 }
634 static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
635 struct snd_ctl_elem_value *ucontrol)
636 {
637 signed int change;
638 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
639 hda_nid_t nid = kcontrol->private_value & 0xffff;
640 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
641 long val = *ucontrol->value.integer.value;
642 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
643 AC_VERB_GET_DIGI_CONVERT_1,
644 0x00);
645
646 /* Set/unset the masked control bit(s) as needed */
647 change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
648 if (val==0)
649 ctrl_data &= ~mask;
650 else
651 ctrl_data |= mask;
652 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
653 ctrl_data);
654
655 return change;
656 }
657 #define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
658 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
659 .info = alc_spdif_ctrl_info, \
660 .get = alc_spdif_ctrl_get, \
661 .put = alc_spdif_ctrl_put, \
662 .private_value = nid | (mask<<16) }
663 #endif /* CONFIG_SND_DEBUG */
664
665 /* A switch control to allow the enabling EAPD digital outputs on the ALC26x.
666 * Again, this is only used in the ALC26x test models to help identify when
667 * the EAPD line must be asserted for features to work.
668 */
669 #ifdef CONFIG_SND_DEBUG
670 #define alc_eapd_ctrl_info snd_ctl_boolean_mono_info
671
672 static int alc_eapd_ctrl_get(struct snd_kcontrol *kcontrol,
673 struct snd_ctl_elem_value *ucontrol)
674 {
675 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
676 hda_nid_t nid = kcontrol->private_value & 0xffff;
677 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
678 long *valp = ucontrol->value.integer.value;
679 unsigned int val = snd_hda_codec_read(codec, nid, 0,
680 AC_VERB_GET_EAPD_BTLENABLE, 0x00);
681
682 *valp = (val & mask) != 0;
683 return 0;
684 }
685
686 static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol,
687 struct snd_ctl_elem_value *ucontrol)
688 {
689 int change;
690 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
691 hda_nid_t nid = kcontrol->private_value & 0xffff;
692 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
693 long val = *ucontrol->value.integer.value;
694 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
695 AC_VERB_GET_EAPD_BTLENABLE,
696 0x00);
697
698 /* Set/unset the masked control bit(s) as needed */
699 change = (!val ? 0 : mask) != (ctrl_data & mask);
700 if (!val)
701 ctrl_data &= ~mask;
702 else
703 ctrl_data |= mask;
704 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
705 ctrl_data);
706
707 return change;
708 }
709
710 #define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \
711 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
712 .info = alc_eapd_ctrl_info, \
713 .get = alc_eapd_ctrl_get, \
714 .put = alc_eapd_ctrl_put, \
715 .private_value = nid | (mask<<16) }
716 #endif /* CONFIG_SND_DEBUG */
717
718 /*
719 */
720 static void add_mixer(struct alc_spec *spec, struct snd_kcontrol_new *mix)
721 {
722 if (snd_BUG_ON(spec->num_mixers >= ARRAY_SIZE(spec->mixers)))
723 return;
724 spec->mixers[spec->num_mixers++] = mix;
725 }
726
727 static void add_verb(struct alc_spec *spec, const struct hda_verb *verb)
728 {
729 if (snd_BUG_ON(spec->num_init_verbs >= ARRAY_SIZE(spec->init_verbs)))
730 return;
731 spec->init_verbs[spec->num_init_verbs++] = verb;
732 }
733
734 /*
735 * set up from the preset table
736 */
737 static void setup_preset(struct alc_spec *spec,
738 const struct alc_config_preset *preset)
739 {
740 int i;
741
742 for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
743 add_mixer(spec, preset->mixers[i]);
744 for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
745 i++)
746 add_verb(spec, preset->init_verbs[i]);
747
748 spec->channel_mode = preset->channel_mode;
749 spec->num_channel_mode = preset->num_channel_mode;
750 spec->need_dac_fix = preset->need_dac_fix;
751
752 spec->multiout.max_channels = spec->channel_mode[0].channels;
753
754 spec->multiout.num_dacs = preset->num_dacs;
755 spec->multiout.dac_nids = preset->dac_nids;
756 spec->multiout.dig_out_nid = preset->dig_out_nid;
757 spec->multiout.hp_nid = preset->hp_nid;
758
759 spec->num_mux_defs = preset->num_mux_defs;
760 if (!spec->num_mux_defs)
761 spec->num_mux_defs = 1;
762 spec->input_mux = preset->input_mux;
763
764 spec->num_adc_nids = preset->num_adc_nids;
765 spec->adc_nids = preset->adc_nids;
766 spec->capsrc_nids = preset->capsrc_nids;
767 spec->dig_in_nid = preset->dig_in_nid;
768
769 spec->unsol_event = preset->unsol_event;
770 spec->init_hook = preset->init_hook;
771 #ifdef CONFIG_SND_HDA_POWER_SAVE
772 spec->loopback.amplist = preset->loopbacks;
773 #endif
774 }
775
776 /* Enable GPIO mask and set output */
777 static struct hda_verb alc_gpio1_init_verbs[] = {
778 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
779 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
780 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
781 { }
782 };
783
784 static struct hda_verb alc_gpio2_init_verbs[] = {
785 {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
786 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
787 {0x01, AC_VERB_SET_GPIO_DATA, 0x02},
788 { }
789 };
790
791 static struct hda_verb alc_gpio3_init_verbs[] = {
792 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
793 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
794 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
795 { }
796 };
797
798 /*
799 * Fix hardware PLL issue
800 * On some codecs, the analog PLL gating control must be off while
801 * the default value is 1.
802 */
803 static void alc_fix_pll(struct hda_codec *codec)
804 {
805 struct alc_spec *spec = codec->spec;
806 unsigned int val;
807
808 if (!spec->pll_nid)
809 return;
810 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
811 spec->pll_coef_idx);
812 val = snd_hda_codec_read(codec, spec->pll_nid, 0,
813 AC_VERB_GET_PROC_COEF, 0);
814 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
815 spec->pll_coef_idx);
816 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_PROC_COEF,
817 val & ~(1 << spec->pll_coef_bit));
818 }
819
820 static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,
821 unsigned int coef_idx, unsigned int coef_bit)
822 {
823 struct alc_spec *spec = codec->spec;
824 spec->pll_nid = nid;
825 spec->pll_coef_idx = coef_idx;
826 spec->pll_coef_bit = coef_bit;
827 alc_fix_pll(codec);
828 }
829
830 static void alc_sku_automute(struct hda_codec *codec)
831 {
832 struct alc_spec *spec = codec->spec;
833 unsigned int present;
834 unsigned int hp_nid = spec->autocfg.hp_pins[0];
835 unsigned int sp_nid = spec->autocfg.speaker_pins[0];
836
837 /* need to execute and sync at first */
838 snd_hda_codec_read(codec, hp_nid, 0, AC_VERB_SET_PIN_SENSE, 0);
839 present = snd_hda_codec_read(codec, hp_nid, 0,
840 AC_VERB_GET_PIN_SENSE, 0);
841 spec->jack_present = (present & 0x80000000) != 0;
842 snd_hda_codec_write(codec, sp_nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
843 spec->jack_present ? 0 : PIN_OUT);
844 }
845
846 #if 0 /* it's broken in some acses -- temporarily disabled */
847 static void alc_mic_automute(struct hda_codec *codec)
848 {
849 struct alc_spec *spec = codec->spec;
850 unsigned int present;
851 unsigned int mic_nid = spec->autocfg.input_pins[AUTO_PIN_MIC];
852 unsigned int fmic_nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC];
853 unsigned int mix_nid = spec->capsrc_nids[0];
854 unsigned int capsrc_idx_mic, capsrc_idx_fmic;
855
856 capsrc_idx_mic = mic_nid - 0x18;
857 capsrc_idx_fmic = fmic_nid - 0x18;
858 present = snd_hda_codec_read(codec, mic_nid, 0,
859 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
860 snd_hda_codec_write(codec, mix_nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
861 0x7000 | (capsrc_idx_mic << 8) | (present ? 0 : 0x80));
862 snd_hda_codec_write(codec, mix_nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
863 0x7000 | (capsrc_idx_fmic << 8) | (present ? 0x80 : 0));
864 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, capsrc_idx_fmic,
865 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
866 }
867 #else
868 #define alc_mic_automute(codec) /* NOP */
869 #endif /* disabled */
870
871 /* unsolicited event for HP jack sensing */
872 static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
873 {
874 if (codec->vendor_id == 0x10ec0880)
875 res >>= 28;
876 else
877 res >>= 26;
878 if (res == ALC880_HP_EVENT)
879 alc_sku_automute(codec);
880
881 if (res == ALC880_MIC_EVENT)
882 alc_mic_automute(codec);
883 }
884
885 static void alc_inithook(struct hda_codec *codec)
886 {
887 alc_sku_automute(codec);
888 alc_mic_automute(codec);
889 }
890
891 /* additional initialization for ALC888 variants */
892 static void alc888_coef_init(struct hda_codec *codec)
893 {
894 unsigned int tmp;
895
896 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0);
897 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
898 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
899 if ((tmp & 0xf0) == 2)
900 /* alc888S-VC */
901 snd_hda_codec_read(codec, 0x20, 0,
902 AC_VERB_SET_PROC_COEF, 0x830);
903 else
904 /* alc888-VB */
905 snd_hda_codec_read(codec, 0x20, 0,
906 AC_VERB_SET_PROC_COEF, 0x3030);
907 }
908
909 /* 32-bit subsystem ID for BIOS loading in HD Audio codec.
910 * 31 ~ 16 : Manufacture ID
911 * 15 ~ 8 : SKU ID
912 * 7 ~ 0 : Assembly ID
913 * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
914 */
915 static void alc_subsystem_id(struct hda_codec *codec,
916 unsigned int porta, unsigned int porte,
917 unsigned int portd)
918 {
919 unsigned int ass, tmp, i;
920 unsigned nid;
921 struct alc_spec *spec = codec->spec;
922
923 ass = codec->subsystem_id & 0xffff;
924 if ((ass != codec->bus->pci->subsystem_device) && (ass & 1))
925 goto do_sku;
926
927 /*
928 * 31~30 : port conetcivity
929 * 29~21 : reserve
930 * 20 : PCBEEP input
931 * 19~16 : Check sum (15:1)
932 * 15~1 : Custom
933 * 0 : override
934 */
935 nid = 0x1d;
936 if (codec->vendor_id == 0x10ec0260)
937 nid = 0x17;
938 ass = snd_hda_codec_read(codec, nid, 0,
939 AC_VERB_GET_CONFIG_DEFAULT, 0);
940 if (!(ass & 1) && !(ass & 0x100000))
941 return;
942 if ((ass >> 30) != 1) /* no physical connection */
943 return;
944
945 /* check sum */
946 tmp = 0;
947 for (i = 1; i < 16; i++) {
948 if ((ass >> i) & 1)
949 tmp++;
950 }
951 if (((ass >> 16) & 0xf) != tmp)
952 return;
953 do_sku:
954 /*
955 * 0 : override
956 * 1 : Swap Jack
957 * 2 : 0 --> Desktop, 1 --> Laptop
958 * 3~5 : External Amplifier control
959 * 7~6 : Reserved
960 */
961 tmp = (ass & 0x38) >> 3; /* external Amp control */
962 switch (tmp) {
963 case 1:
964 snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
965 break;
966 case 3:
967 snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
968 break;
969 case 7:
970 snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
971 break;
972 case 5: /* set EAPD output high */
973 switch (codec->vendor_id) {
974 case 0x10ec0260:
975 snd_hda_codec_write(codec, 0x0f, 0,
976 AC_VERB_SET_EAPD_BTLENABLE, 2);
977 snd_hda_codec_write(codec, 0x10, 0,
978 AC_VERB_SET_EAPD_BTLENABLE, 2);
979 break;
980 case 0x10ec0262:
981 case 0x10ec0267:
982 case 0x10ec0268:
983 case 0x10ec0269:
984 case 0x10ec0660:
985 case 0x10ec0662:
986 case 0x10ec0663:
987 case 0x10ec0862:
988 case 0x10ec0889:
989 snd_hda_codec_write(codec, 0x14, 0,
990 AC_VERB_SET_EAPD_BTLENABLE, 2);
991 snd_hda_codec_write(codec, 0x15, 0,
992 AC_VERB_SET_EAPD_BTLENABLE, 2);
993 break;
994 }
995 switch (codec->vendor_id) {
996 case 0x10ec0260:
997 snd_hda_codec_write(codec, 0x1a, 0,
998 AC_VERB_SET_COEF_INDEX, 7);
999 tmp = snd_hda_codec_read(codec, 0x1a, 0,
1000 AC_VERB_GET_PROC_COEF, 0);
1001 snd_hda_codec_write(codec, 0x1a, 0,
1002 AC_VERB_SET_COEF_INDEX, 7);
1003 snd_hda_codec_write(codec, 0x1a, 0,
1004 AC_VERB_SET_PROC_COEF,
1005 tmp | 0x2010);
1006 break;
1007 case 0x10ec0262:
1008 case 0x10ec0880:
1009 case 0x10ec0882:
1010 case 0x10ec0883:
1011 case 0x10ec0885:
1012 case 0x10ec0889:
1013 snd_hda_codec_write(codec, 0x20, 0,
1014 AC_VERB_SET_COEF_INDEX, 7);
1015 tmp = snd_hda_codec_read(codec, 0x20, 0,
1016 AC_VERB_GET_PROC_COEF, 0);
1017 snd_hda_codec_write(codec, 0x20, 0,
1018 AC_VERB_SET_COEF_INDEX, 7);
1019 snd_hda_codec_write(codec, 0x20, 0,
1020 AC_VERB_SET_PROC_COEF,
1021 tmp | 0x2010);
1022 break;
1023 case 0x10ec0888:
1024 /*alc888_coef_init(codec);*/ /* called in alc_init() */
1025 break;
1026 case 0x10ec0267:
1027 case 0x10ec0268:
1028 snd_hda_codec_write(codec, 0x20, 0,
1029 AC_VERB_SET_COEF_INDEX, 7);
1030 tmp = snd_hda_codec_read(codec, 0x20, 0,
1031 AC_VERB_GET_PROC_COEF, 0);
1032 snd_hda_codec_write(codec, 0x20, 0,
1033 AC_VERB_SET_COEF_INDEX, 7);
1034 snd_hda_codec_write(codec, 0x20, 0,
1035 AC_VERB_SET_PROC_COEF,
1036 tmp | 0x3000);
1037 break;
1038 }
1039 default:
1040 break;
1041 }
1042
1043 /* is laptop or Desktop and enable the function "Mute internal speaker
1044 * when the external headphone out jack is plugged"
1045 */
1046 if (!(ass & 0x8000))
1047 return;
1048 /*
1049 * 10~8 : Jack location
1050 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
1051 * 14~13: Resvered
1052 * 15 : 1 --> enable the function "Mute internal speaker
1053 * when the external headphone out jack is plugged"
1054 */
1055 if (!spec->autocfg.speaker_pins[0]) {
1056 if (spec->autocfg.line_out_pins[0])
1057 spec->autocfg.speaker_pins[0] =
1058 spec->autocfg.line_out_pins[0];
1059 else
1060 return;
1061 }
1062
1063 if (!spec->autocfg.hp_pins[0]) {
1064 tmp = (ass >> 11) & 0x3; /* HP to chassis */
1065 if (tmp == 0)
1066 spec->autocfg.hp_pins[0] = porta;
1067 else if (tmp == 1)
1068 spec->autocfg.hp_pins[0] = porte;
1069 else if (tmp == 2)
1070 spec->autocfg.hp_pins[0] = portd;
1071 else
1072 return;
1073 }
1074 if (spec->autocfg.hp_pins[0])
1075 snd_hda_codec_write(codec, spec->autocfg.hp_pins[0], 0,
1076 AC_VERB_SET_UNSOLICITED_ENABLE,
1077 AC_USRSP_EN | ALC880_HP_EVENT);
1078
1079 #if 0 /* it's broken in some acses -- temporarily disabled */
1080 if (spec->autocfg.input_pins[AUTO_PIN_MIC] &&
1081 spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC])
1082 snd_hda_codec_write(codec,
1083 spec->autocfg.input_pins[AUTO_PIN_MIC], 0,
1084 AC_VERB_SET_UNSOLICITED_ENABLE,
1085 AC_USRSP_EN | ALC880_MIC_EVENT);
1086 #endif /* disabled */
1087
1088 spec->unsol_event = alc_sku_unsol_event;
1089 }
1090
1091 /*
1092 * Fix-up pin default configurations
1093 */
1094
1095 struct alc_pincfg {
1096 hda_nid_t nid;
1097 u32 val;
1098 };
1099
1100 static void alc_fix_pincfg(struct hda_codec *codec,
1101 const struct snd_pci_quirk *quirk,
1102 const struct alc_pincfg **pinfix)
1103 {
1104 const struct alc_pincfg *cfg;
1105
1106 quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
1107 if (!quirk)
1108 return;
1109
1110 cfg = pinfix[quirk->value];
1111 for (; cfg->nid; cfg++) {
1112 int i;
1113 u32 val = cfg->val;
1114 for (i = 0; i < 4; i++) {
1115 snd_hda_codec_write(codec, cfg->nid, 0,
1116 AC_VERB_SET_CONFIG_DEFAULT_BYTES_0 + i,
1117 val & 0xff);
1118 val >>= 8;
1119 }
1120 }
1121 }
1122
1123 /*
1124 * ALC880 3-stack model
1125 *
1126 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
1127 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
1128 * F-Mic = 0x1b, HP = 0x19
1129 */
1130
1131 static hda_nid_t alc880_dac_nids[4] = {
1132 /* front, rear, clfe, rear_surr */
1133 0x02, 0x05, 0x04, 0x03
1134 };
1135
1136 static hda_nid_t alc880_adc_nids[3] = {
1137 /* ADC0-2 */
1138 0x07, 0x08, 0x09,
1139 };
1140
1141 /* The datasheet says the node 0x07 is connected from inputs,
1142 * but it shows zero connection in the real implementation on some devices.
1143 * Note: this is a 915GAV bug, fixed on 915GLV
1144 */
1145 static hda_nid_t alc880_adc_nids_alt[2] = {
1146 /* ADC1-2 */
1147 0x08, 0x09,
1148 };
1149
1150 #define ALC880_DIGOUT_NID 0x06
1151 #define ALC880_DIGIN_NID 0x0a
1152
1153 static struct hda_input_mux alc880_capture_source = {
1154 .num_items = 4,
1155 .items = {
1156 { "Mic", 0x0 },
1157 { "Front Mic", 0x3 },
1158 { "Line", 0x2 },
1159 { "CD", 0x4 },
1160 },
1161 };
1162
1163 /* channel source setting (2/6 channel selection for 3-stack) */
1164 /* 2ch mode */
1165 static struct hda_verb alc880_threestack_ch2_init[] = {
1166 /* set line-in to input, mute it */
1167 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1168 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1169 /* set mic-in to input vref 80%, mute it */
1170 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1171 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1172 { } /* end */
1173 };
1174
1175 /* 6ch mode */
1176 static struct hda_verb alc880_threestack_ch6_init[] = {
1177 /* set line-in to output, unmute it */
1178 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1179 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1180 /* set mic-in to output, unmute it */
1181 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1182 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1183 { } /* end */
1184 };
1185
1186 static struct hda_channel_mode alc880_threestack_modes[2] = {
1187 { 2, alc880_threestack_ch2_init },
1188 { 6, alc880_threestack_ch6_init },
1189 };
1190
1191 static struct snd_kcontrol_new alc880_three_stack_mixer[] = {
1192 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1193 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1194 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1195 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
1196 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1197 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1198 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1199 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1200 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1201 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1202 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1203 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1204 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1205 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1206 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
1207 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
1208 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1209 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1210 HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
1211 {
1212 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1213 .name = "Channel Mode",
1214 .info = alc_ch_mode_info,
1215 .get = alc_ch_mode_get,
1216 .put = alc_ch_mode_put,
1217 },
1218 { } /* end */
1219 };
1220
1221 /* capture mixer elements */
1222 static struct snd_kcontrol_new alc880_capture_mixer[] = {
1223 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
1224 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
1225 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
1226 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
1227 HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
1228 HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
1229 {
1230 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1231 /* The multiple "Capture Source" controls confuse alsamixer
1232 * So call somewhat different..
1233 */
1234 /* .name = "Capture Source", */
1235 .name = "Input Source",
1236 .count = 3,
1237 .info = alc_mux_enum_info,
1238 .get = alc_mux_enum_get,
1239 .put = alc_mux_enum_put,
1240 },
1241 { } /* end */
1242 };
1243
1244 /* capture mixer elements (in case NID 0x07 not available) */
1245 static struct snd_kcontrol_new alc880_capture_alt_mixer[] = {
1246 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
1247 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
1248 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
1249 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
1250 {
1251 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1252 /* The multiple "Capture Source" controls confuse alsamixer
1253 * So call somewhat different..
1254 */
1255 /* .name = "Capture Source", */
1256 .name = "Input Source",
1257 .count = 2,
1258 .info = alc_mux_enum_info,
1259 .get = alc_mux_enum_get,
1260 .put = alc_mux_enum_put,
1261 },
1262 };
1263
1264
1265
1266 /*
1267 * ALC880 5-stack model
1268 *
1269 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
1270 * Side = 0x02 (0xd)
1271 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
1272 * Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
1273 */
1274
1275 /* additional mixers to alc880_three_stack_mixer */
1276 static struct snd_kcontrol_new alc880_five_stack_mixer[] = {
1277 HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1278 HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
1279 { } /* end */
1280 };
1281
1282 /* channel source setting (6/8 channel selection for 5-stack) */
1283 /* 6ch mode */
1284 static struct hda_verb alc880_fivestack_ch6_init[] = {
1285 /* set line-in to input, mute it */
1286 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1287 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1288 { } /* end */
1289 };
1290
1291 /* 8ch mode */
1292 static struct hda_verb alc880_fivestack_ch8_init[] = {
1293 /* set line-in to output, unmute it */
1294 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1295 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1296 { } /* end */
1297 };
1298
1299 static struct hda_channel_mode alc880_fivestack_modes[2] = {
1300 { 6, alc880_fivestack_ch6_init },
1301 { 8, alc880_fivestack_ch8_init },
1302 };
1303
1304
1305 /*
1306 * ALC880 6-stack model
1307 *
1308 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
1309 * Side = 0x05 (0x0f)
1310 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
1311 * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
1312 */
1313
1314 static hda_nid_t alc880_6st_dac_nids[4] = {
1315 /* front, rear, clfe, rear_surr */
1316 0x02, 0x03, 0x04, 0x05
1317 };
1318
1319 static struct hda_input_mux alc880_6stack_capture_source = {
1320 .num_items = 4,
1321 .items = {
1322 { "Mic", 0x0 },
1323 { "Front Mic", 0x1 },
1324 { "Line", 0x2 },
1325 { "CD", 0x4 },
1326 },
1327 };
1328
1329 /* fixed 8-channels */
1330 static struct hda_channel_mode alc880_sixstack_modes[1] = {
1331 { 8, NULL },
1332 };
1333
1334 static struct snd_kcontrol_new alc880_six_stack_mixer[] = {
1335 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1336 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1337 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1338 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1339 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1340 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1341 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1342 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1343 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1344 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1345 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1346 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1347 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1348 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1349 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1350 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1351 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1352 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1353 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1354 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1355 {
1356 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1357 .name = "Channel Mode",
1358 .info = alc_ch_mode_info,
1359 .get = alc_ch_mode_get,
1360 .put = alc_ch_mode_put,
1361 },
1362 { } /* end */
1363 };
1364
1365
1366 /*
1367 * ALC880 W810 model
1368 *
1369 * W810 has rear IO for:
1370 * Front (DAC 02)
1371 * Surround (DAC 03)
1372 * Center/LFE (DAC 04)
1373 * Digital out (06)
1374 *
1375 * The system also has a pair of internal speakers, and a headphone jack.
1376 * These are both connected to Line2 on the codec, hence to DAC 02.
1377 *
1378 * There is a variable resistor to control the speaker or headphone
1379 * volume. This is a hardware-only device without a software API.
1380 *
1381 * Plugging headphones in will disable the internal speakers. This is
1382 * implemented in hardware, not via the driver using jack sense. In
1383 * a similar fashion, plugging into the rear socket marked "front" will
1384 * disable both the speakers and headphones.
1385 *
1386 * For input, there's a microphone jack, and an "audio in" jack.
1387 * These may not do anything useful with this driver yet, because I
1388 * haven't setup any initialization verbs for these yet...
1389 */
1390
1391 static hda_nid_t alc880_w810_dac_nids[3] = {
1392 /* front, rear/surround, clfe */
1393 0x02, 0x03, 0x04
1394 };
1395
1396 /* fixed 6 channels */
1397 static struct hda_channel_mode alc880_w810_modes[1] = {
1398 { 6, NULL }
1399 };
1400
1401 /* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
1402 static struct snd_kcontrol_new alc880_w810_base_mixer[] = {
1403 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1404 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1405 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1406 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1407 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1408 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1409 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1410 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1411 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1412 { } /* end */
1413 };
1414
1415
1416 /*
1417 * Z710V model
1418 *
1419 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
1420 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
1421 * Line = 0x1a
1422 */
1423
1424 static hda_nid_t alc880_z71v_dac_nids[1] = {
1425 0x02
1426 };
1427 #define ALC880_Z71V_HP_DAC 0x03
1428
1429 /* fixed 2 channels */
1430 static struct hda_channel_mode alc880_2_jack_modes[1] = {
1431 { 2, NULL }
1432 };
1433
1434 static struct snd_kcontrol_new alc880_z71v_mixer[] = {
1435 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1436 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1437 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1438 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
1439 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1440 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1441 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1442 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1443 { } /* end */
1444 };
1445
1446
1447 /*
1448 * ALC880 F1734 model
1449 *
1450 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
1451 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
1452 */
1453
1454 static hda_nid_t alc880_f1734_dac_nids[1] = {
1455 0x03
1456 };
1457 #define ALC880_F1734_HP_DAC 0x02
1458
1459 static struct snd_kcontrol_new alc880_f1734_mixer[] = {
1460 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1461 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1462 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1463 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1464 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1465 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1466 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1467 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1468 { } /* end */
1469 };
1470
1471 static struct hda_input_mux alc880_f1734_capture_source = {
1472 .num_items = 2,
1473 .items = {
1474 { "Mic", 0x1 },
1475 { "CD", 0x4 },
1476 },
1477 };
1478
1479
1480 /*
1481 * ALC880 ASUS model
1482 *
1483 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1484 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1485 * Mic = 0x18, Line = 0x1a
1486 */
1487
1488 #define alc880_asus_dac_nids alc880_w810_dac_nids /* identical with w810 */
1489 #define alc880_asus_modes alc880_threestack_modes /* 2/6 channel mode */
1490
1491 static struct snd_kcontrol_new alc880_asus_mixer[] = {
1492 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1493 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1494 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1495 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1496 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1497 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1498 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1499 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1500 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1501 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1502 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1503 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1504 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1505 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1506 {
1507 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1508 .name = "Channel Mode",
1509 .info = alc_ch_mode_info,
1510 .get = alc_ch_mode_get,
1511 .put = alc_ch_mode_put,
1512 },
1513 { } /* end */
1514 };
1515
1516 /*
1517 * ALC880 ASUS W1V model
1518 *
1519 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1520 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1521 * Mic = 0x18, Line = 0x1a, Line2 = 0x1b
1522 */
1523
1524 /* additional mixers to alc880_asus_mixer */
1525 static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
1526 HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
1527 HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
1528 { } /* end */
1529 };
1530
1531 /* additional mixers to alc880_asus_mixer */
1532 static struct snd_kcontrol_new alc880_pcbeep_mixer[] = {
1533 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1534 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1535 { } /* end */
1536 };
1537
1538 /* TCL S700 */
1539 static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
1540 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1541 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1542 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
1543 HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
1544 HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
1545 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
1546 HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
1547 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
1548 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
1549 {
1550 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1551 /* The multiple "Capture Source" controls confuse alsamixer
1552 * So call somewhat different..
1553 */
1554 /* .name = "Capture Source", */
1555 .name = "Input Source",
1556 .count = 1,
1557 .info = alc_mux_enum_info,
1558 .get = alc_mux_enum_get,
1559 .put = alc_mux_enum_put,
1560 },
1561 { } /* end */
1562 };
1563
1564 /* Uniwill */
1565 static struct snd_kcontrol_new alc880_uniwill_mixer[] = {
1566 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1567 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1568 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1569 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1570 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1571 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1572 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1573 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1574 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1575 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1576 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1577 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1578 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1579 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1580 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1581 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1582 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1583 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1584 {
1585 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1586 .name = "Channel Mode",
1587 .info = alc_ch_mode_info,
1588 .get = alc_ch_mode_get,
1589 .put = alc_ch_mode_put,
1590 },
1591 { } /* end */
1592 };
1593
1594 static struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
1595 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1596 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1597 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1598 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1599 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1600 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1601 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1602 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1603 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1604 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1605 { } /* end */
1606 };
1607
1608 static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
1609 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1610 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1611 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1612 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1613 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1614 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1615 { } /* end */
1616 };
1617
1618 /*
1619 * virtual master controls
1620 */
1621
1622 /*
1623 * slave controls for virtual master
1624 */
1625 static const char *alc_slave_vols[] = {
1626 "Front Playback Volume",
1627 "Surround Playback Volume",
1628 "Center Playback Volume",
1629 "LFE Playback Volume",
1630 "Side Playback Volume",
1631 "Headphone Playback Volume",
1632 "Speaker Playback Volume",
1633 "Mono Playback Volume",
1634 "Line-Out Playback Volume",
1635 NULL,
1636 };
1637
1638 static const char *alc_slave_sws[] = {
1639 "Front Playback Switch",
1640 "Surround Playback Switch",
1641 "Center Playback Switch",
1642 "LFE Playback Switch",
1643 "Side Playback Switch",
1644 "Headphone Playback Switch",
1645 "Speaker Playback Switch",
1646 "Mono Playback Switch",
1647 "IEC958 Playback Switch",
1648 NULL,
1649 };
1650
1651 /*
1652 * build control elements
1653 */
1654
1655 static void alc_free_kctls(struct hda_codec *codec);
1656
1657 static int alc_build_controls(struct hda_codec *codec)
1658 {
1659 struct alc_spec *spec = codec->spec;
1660 int err;
1661 int i;
1662
1663 for (i = 0; i < spec->num_mixers; i++) {
1664 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
1665 if (err < 0)
1666 return err;
1667 }
1668
1669 if (spec->multiout.dig_out_nid) {
1670 err = snd_hda_create_spdif_out_ctls(codec,
1671 spec->multiout.dig_out_nid);
1672 if (err < 0)
1673 return err;
1674 err = snd_hda_create_spdif_share_sw(codec,
1675 &spec->multiout);
1676 if (err < 0)
1677 return err;
1678 spec->multiout.share_spdif = 1;
1679 }
1680 if (spec->dig_in_nid) {
1681 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
1682 if (err < 0)
1683 return err;
1684 }
1685
1686 /* if we have no master control, let's create it */
1687 if (!snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
1688 unsigned int vmaster_tlv[4];
1689 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
1690 HDA_OUTPUT, vmaster_tlv);
1691 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
1692 vmaster_tlv, alc_slave_vols);
1693 if (err < 0)
1694 return err;
1695 }
1696 if (!snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
1697 err = snd_hda_add_vmaster(codec, "Master Playback Switch",
1698 NULL, alc_slave_sws);
1699 if (err < 0)
1700 return err;
1701 }
1702
1703 alc_free_kctls(codec); /* no longer needed */
1704 return 0;
1705 }
1706
1707
1708 /*
1709 * initialize the codec volumes, etc
1710 */
1711
1712 /*
1713 * generic initialization of ADC, input mixers and output mixers
1714 */
1715 static struct hda_verb alc880_volume_init_verbs[] = {
1716 /*
1717 * Unmute ADC0-2 and set the default input to mic-in
1718 */
1719 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
1720 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1721 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
1722 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1723 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
1724 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1725
1726 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
1727 * mixer widget
1728 * Note: PASD motherboards uses the Line In 2 as the input for front
1729 * panel mic (mic 2)
1730 */
1731 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
1732 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1733 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1734 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
1735 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
1736 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1737 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
1738 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
1739
1740 /*
1741 * Set up output mixers (0x0c - 0x0f)
1742 */
1743 /* set vol=0 to output mixers */
1744 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1745 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1746 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1747 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1748 /* set up input amps for analog loopback */
1749 /* Amp Indices: DAC = 0, mixer = 1 */
1750 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1751 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1752 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1753 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1754 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1755 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1756 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1757 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1758
1759 { }
1760 };
1761
1762 /*
1763 * 3-stack pin configuration:
1764 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
1765 */
1766 static struct hda_verb alc880_pin_3stack_init_verbs[] = {
1767 /*
1768 * preset connection lists of input pins
1769 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1770 */
1771 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
1772 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1773 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
1774
1775 /*
1776 * Set pin mode and muting
1777 */
1778 /* set front pin widgets 0x14 for output */
1779 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1780 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1781 /* Mic1 (rear panel) pin widget for input and vref at 80% */
1782 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1783 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1784 /* Mic2 (as headphone out) for HP output */
1785 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1786 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1787 /* Line In pin widget for input */
1788 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1789 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1790 /* Line2 (as front mic) pin widget for input and vref at 80% */
1791 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1792 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1793 /* CD pin widget for input */
1794 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1795
1796 { }
1797 };
1798
1799 /*
1800 * 5-stack pin configuration:
1801 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
1802 * line-in/side = 0x1a, f-mic = 0x1b
1803 */
1804 static struct hda_verb alc880_pin_5stack_init_verbs[] = {
1805 /*
1806 * preset connection lists of input pins
1807 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1808 */
1809 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1810 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
1811
1812 /*
1813 * Set pin mode and muting
1814 */
1815 /* set pin widgets 0x14-0x17 for output */
1816 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1817 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1818 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1819 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1820 /* unmute pins for output (no gain on this amp) */
1821 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1822 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1823 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1824 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1825
1826 /* Mic1 (rear panel) pin widget for input and vref at 80% */
1827 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1828 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1829 /* Mic2 (as headphone out) for HP output */
1830 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1831 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1832 /* Line In pin widget for input */
1833 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1834 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1835 /* Line2 (as front mic) pin widget for input and vref at 80% */
1836 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1837 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1838 /* CD pin widget for input */
1839 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1840
1841 { }
1842 };
1843
1844 /*
1845 * W810 pin configuration:
1846 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
1847 */
1848 static struct hda_verb alc880_pin_w810_init_verbs[] = {
1849 /* hphone/speaker input selector: front DAC */
1850 {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
1851
1852 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1853 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1854 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1855 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1856 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1857 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1858
1859 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1860 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1861
1862 { }
1863 };
1864
1865 /*
1866 * Z71V pin configuration:
1867 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
1868 */
1869 static struct hda_verb alc880_pin_z71v_init_verbs[] = {
1870 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1871 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1872 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1873 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1874
1875 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1876 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1877 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1878 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1879
1880 { }
1881 };
1882
1883 /*
1884 * 6-stack pin configuration:
1885 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
1886 * f-mic = 0x19, line = 0x1a, HP = 0x1b
1887 */
1888 static struct hda_verb alc880_pin_6stack_init_verbs[] = {
1889 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1890
1891 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1892 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1893 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1894 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1895 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1896 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1897 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1898 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1899
1900 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1901 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1902 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1903 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1904 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1905 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1906 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1907 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1908 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1909
1910 { }
1911 };
1912
1913 /*
1914 * Uniwill pin configuration:
1915 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
1916 * line = 0x1a
1917 */
1918 static struct hda_verb alc880_uniwill_init_verbs[] = {
1919 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1920
1921 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1922 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1923 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1924 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1925 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1926 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1927 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1928 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1929 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1930 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1931 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1932 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1933 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1934 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1935
1936 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1937 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1938 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1939 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1940 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1941 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1942 /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
1943 /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
1944 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1945
1946 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
1947 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
1948
1949 { }
1950 };
1951
1952 /*
1953 * Uniwill P53
1954 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
1955 */
1956 static struct hda_verb alc880_uniwill_p53_init_verbs[] = {
1957 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1958
1959 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1960 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1961 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1962 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1963 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1964 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1965 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1966 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1967 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1968 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1969 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1970 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1971
1972 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1973 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1974 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1975 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1976 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1977 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1978
1979 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
1980 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
1981
1982 { }
1983 };
1984
1985 static struct hda_verb alc880_beep_init_verbs[] = {
1986 { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
1987 { }
1988 };
1989
1990 /* toggle speaker-output according to the hp-jack state */
1991 static void alc880_uniwill_hp_automute(struct hda_codec *codec)
1992 {
1993 unsigned int present;
1994 unsigned char bits;
1995
1996 present = snd_hda_codec_read(codec, 0x14, 0,
1997 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1998 bits = present ? HDA_AMP_MUTE : 0;
1999 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
2000 HDA_AMP_MUTE, bits);
2001 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
2002 HDA_AMP_MUTE, bits);
2003 }
2004
2005 /* auto-toggle front mic */
2006 static void alc880_uniwill_mic_automute(struct hda_codec *codec)
2007 {
2008 unsigned int present;
2009 unsigned char bits;
2010
2011 present = snd_hda_codec_read(codec, 0x18, 0,
2012 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2013 bits = present ? HDA_AMP_MUTE : 0;
2014 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
2015 }
2016
2017 static void alc880_uniwill_automute(struct hda_codec *codec)
2018 {
2019 alc880_uniwill_hp_automute(codec);
2020 alc880_uniwill_mic_automute(codec);
2021 }
2022
2023 static void alc880_uniwill_unsol_event(struct hda_codec *codec,
2024 unsigned int res)
2025 {
2026 /* Looks like the unsol event is incompatible with the standard
2027 * definition. 4bit tag is placed at 28 bit!
2028 */
2029 switch (res >> 28) {
2030 case ALC880_HP_EVENT:
2031 alc880_uniwill_hp_automute(codec);
2032 break;
2033 case ALC880_MIC_EVENT:
2034 alc880_uniwill_mic_automute(codec);
2035 break;
2036 }
2037 }
2038
2039 static void alc880_uniwill_p53_hp_automute(struct hda_codec *codec)
2040 {
2041 unsigned int present;
2042 unsigned char bits;
2043
2044 present = snd_hda_codec_read(codec, 0x14, 0,
2045 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2046 bits = present ? HDA_AMP_MUTE : 0;
2047 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, HDA_AMP_MUTE, bits);
2048 }
2049
2050 static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
2051 {
2052 unsigned int present;
2053
2054 present = snd_hda_codec_read(codec, 0x21, 0,
2055 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
2056 present &= HDA_AMP_VOLMASK;
2057 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
2058 HDA_AMP_VOLMASK, present);
2059 snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
2060 HDA_AMP_VOLMASK, present);
2061 }
2062
2063 static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
2064 unsigned int res)
2065 {
2066 /* Looks like the unsol event is incompatible with the standard
2067 * definition. 4bit tag is placed at 28 bit!
2068 */
2069 if ((res >> 28) == ALC880_HP_EVENT)
2070 alc880_uniwill_p53_hp_automute(codec);
2071 if ((res >> 28) == ALC880_DCVOL_EVENT)
2072 alc880_uniwill_p53_dcvol_automute(codec);
2073 }
2074
2075 /*
2076 * F1734 pin configuration:
2077 * HP = 0x14, speaker-out = 0x15, mic = 0x18
2078 */
2079 static struct hda_verb alc880_pin_f1734_init_verbs[] = {
2080 {0x07, AC_VERB_SET_CONNECT_SEL, 0x01},
2081 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
2082 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
2083 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
2084 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
2085
2086 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2087 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2088 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2089 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2090
2091 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2092 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2093 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
2094 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2095 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2096 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2097 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2098 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2099 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2100
2101 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
2102 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_DCVOL_EVENT},
2103
2104 { }
2105 };
2106
2107 /*
2108 * ASUS pin configuration:
2109 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
2110 */
2111 static struct hda_verb alc880_pin_asus_init_verbs[] = {
2112 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
2113 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
2114 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
2115 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
2116
2117 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2118 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2119 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2120 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2121 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2122 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2123 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2124 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2125
2126 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2127 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2128 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2129 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2130 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2131 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2132 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2133 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2134 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2135
2136 { }
2137 };
2138
2139 /* Enable GPIO mask and set output */
2140 #define alc880_gpio1_init_verbs alc_gpio1_init_verbs
2141 #define alc880_gpio2_init_verbs alc_gpio2_init_verbs
2142
2143 /* Clevo m520g init */
2144 static struct hda_verb alc880_pin_clevo_init_verbs[] = {
2145 /* headphone output */
2146 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
2147 /* line-out */
2148 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2149 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2150 /* Line-in */
2151 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2152 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2153 /* CD */
2154 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2155 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2156 /* Mic1 (rear panel) */
2157 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2158 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2159 /* Mic2 (front panel) */
2160 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2161 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2162 /* headphone */
2163 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2164 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2165 /* change to EAPD mode */
2166 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2167 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
2168
2169 { }
2170 };
2171
2172 static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
2173 /* change to EAPD mode */
2174 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2175 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
2176
2177 /* Headphone output */
2178 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2179 /* Front output*/
2180 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2181 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
2182
2183 /* Line In pin widget for input */
2184 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2185 /* CD pin widget for input */
2186 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2187 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2188 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2189
2190 /* change to EAPD mode */
2191 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2192 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
2193
2194 { }
2195 };
2196
2197 /*
2198 * LG m1 express dual
2199 *
2200 * Pin assignment:
2201 * Rear Line-In/Out (blue): 0x14
2202 * Build-in Mic-In: 0x15
2203 * Speaker-out: 0x17
2204 * HP-Out (green): 0x1b
2205 * Mic-In/Out (red): 0x19
2206 * SPDIF-Out: 0x1e
2207 */
2208
2209 /* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
2210 static hda_nid_t alc880_lg_dac_nids[3] = {
2211 0x05, 0x02, 0x03
2212 };
2213
2214 /* seems analog CD is not working */
2215 static struct hda_input_mux alc880_lg_capture_source = {
2216 .num_items = 3,
2217 .items = {
2218 { "Mic", 0x1 },
2219 { "Line", 0x5 },
2220 { "Internal Mic", 0x6 },
2221 },
2222 };
2223
2224 /* 2,4,6 channel modes */
2225 static struct hda_verb alc880_lg_ch2_init[] = {
2226 /* set line-in and mic-in to input */
2227 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2228 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2229 { }
2230 };
2231
2232 static struct hda_verb alc880_lg_ch4_init[] = {
2233 /* set line-in to out and mic-in to input */
2234 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2235 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2236 { }
2237 };
2238
2239 static struct hda_verb alc880_lg_ch6_init[] = {
2240 /* set line-in and mic-in to output */
2241 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2242 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
2243 { }
2244 };
2245
2246 static struct hda_channel_mode alc880_lg_ch_modes[3] = {
2247 { 2, alc880_lg_ch2_init },
2248 { 4, alc880_lg_ch4_init },
2249 { 6, alc880_lg_ch6_init },
2250 };
2251
2252 static struct snd_kcontrol_new alc880_lg_mixer[] = {
2253 HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2254 HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT),
2255 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2256 HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
2257 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
2258 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
2259 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
2260 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
2261 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2262 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2263 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
2264 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
2265 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
2266 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
2267 {
2268 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2269 .name = "Channel Mode",
2270 .info = alc_ch_mode_info,
2271 .get = alc_ch_mode_get,
2272 .put = alc_ch_mode_put,
2273 },
2274 { } /* end */
2275 };
2276
2277 static struct hda_verb alc880_lg_init_verbs[] = {
2278 /* set capture source to mic-in */
2279 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2280 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2281 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2282 /* mute all amp mixer inputs */
2283 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
2284 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2285 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2286 /* line-in to input */
2287 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2288 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2289 /* built-in mic */
2290 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2291 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2292 /* speaker-out */
2293 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2294 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2295 /* mic-in to input */
2296 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
2297 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2298 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2299 /* HP-out */
2300 {0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
2301 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2302 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2303 /* jack sense */
2304 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
2305 { }
2306 };
2307
2308 /* toggle speaker-output according to the hp-jack state */
2309 static void alc880_lg_automute(struct hda_codec *codec)
2310 {
2311 unsigned int present;
2312 unsigned char bits;
2313
2314 present = snd_hda_codec_read(codec, 0x1b, 0,
2315 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2316 bits = present ? HDA_AMP_MUTE : 0;
2317 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
2318 HDA_AMP_MUTE, bits);
2319 }
2320
2321 static void alc880_lg_unsol_event(struct hda_codec *codec, unsigned int res)
2322 {
2323 /* Looks like the unsol event is incompatible with the standard
2324 * definition. 4bit tag is placed at 28 bit!
2325 */
2326 if ((res >> 28) == 0x01)
2327 alc880_lg_automute(codec);
2328 }
2329
2330 /*
2331 * LG LW20
2332 *
2333 * Pin assignment:
2334 * Speaker-out: 0x14
2335 * Mic-In: 0x18
2336 * Built-in Mic-In: 0x19
2337 * Line-In: 0x1b
2338 * HP-Out: 0x1a
2339 * SPDIF-Out: 0x1e
2340 */
2341
2342 static struct hda_input_mux alc880_lg_lw_capture_source = {
2343 .num_items = 3,
2344 .items = {
2345 { "Mic", 0x0 },
2346 { "Internal Mic", 0x1 },
2347 { "Line In", 0x2 },
2348 },
2349 };
2350
2351 #define alc880_lg_lw_modes alc880_threestack_modes
2352
2353 static struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
2354 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2355 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2356 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2357 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
2358 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2359 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2360 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2361 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2362 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2363 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2364 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2365 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2366 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
2367 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
2368 {
2369 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2370 .name = "Channel Mode",
2371 .info = alc_ch_mode_info,
2372 .get = alc_ch_mode_get,
2373 .put = alc_ch_mode_put,
2374 },
2375 { } /* end */
2376 };
2377
2378 static struct hda_verb alc880_lg_lw_init_verbs[] = {
2379 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2380 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
2381 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
2382
2383 /* set capture source to mic-in */
2384 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2385 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2386 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2387 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2388 /* speaker-out */
2389 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2390 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2391 /* HP-out */
2392 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2393 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2394 /* mic-in to input */
2395 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2396 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2397 /* built-in mic */
2398 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2399 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2400 /* jack sense */
2401 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
2402 { }
2403 };
2404
2405 /* toggle speaker-output according to the hp-jack state */
2406 static void alc880_lg_lw_automute(struct hda_codec *codec)
2407 {
2408 unsigned int present;
2409 unsigned char bits;
2410
2411 present = snd_hda_codec_read(codec, 0x1b, 0,
2412 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2413 bits = present ? HDA_AMP_MUTE : 0;
2414 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
2415 HDA_AMP_MUTE, bits);
2416 }
2417
2418 static void alc880_lg_lw_unsol_event(struct hda_codec *codec, unsigned int res)
2419 {
2420 /* Looks like the unsol event is incompatible with the standard
2421 * definition. 4bit tag is placed at 28 bit!
2422 */
2423 if ((res >> 28) == 0x01)
2424 alc880_lg_lw_automute(codec);
2425 }
2426
2427 static struct snd_kcontrol_new alc880_medion_rim_mixer[] = {
2428 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2429 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
2430 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2431 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2432 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2433 HDA_CODEC_MUTE("Internal Playback Switch", 0x0b, 0x1, HDA_INPUT),
2434 { } /* end */
2435 };
2436
2437 static struct hda_input_mux alc880_medion_rim_capture_source = {
2438 .num_items = 2,
2439 .items = {
2440 { "Mic", 0x0 },
2441 { "Internal Mic", 0x1 },
2442 },
2443 };
2444
2445 static struct hda_verb alc880_medion_rim_init_verbs[] = {
2446 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2447
2448 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2449 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2450
2451 /* Mic1 (rear panel) pin widget for input and vref at 80% */
2452 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2453 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2454 /* Mic2 (as headphone out) for HP output */
2455 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2456 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2457 /* Internal Speaker */
2458 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2459 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2460
2461 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2462 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
2463
2464 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
2465 { }
2466 };
2467
2468 /* toggle speaker-output according to the hp-jack state */
2469 static void alc880_medion_rim_automute(struct hda_codec *codec)
2470 {
2471 unsigned int present;
2472 unsigned char bits;
2473
2474 present = snd_hda_codec_read(codec, 0x14, 0,
2475 AC_VERB_GET_PIN_SENSE, 0)
2476 & AC_PINSENSE_PRESENCE;
2477 bits = present ? HDA_AMP_MUTE : 0;
2478 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
2479 HDA_AMP_MUTE, bits);
2480 if (present)
2481 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0);
2482 else
2483 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2);
2484 }
2485
2486 static void alc880_medion_rim_unsol_event(struct hda_codec *codec,
2487 unsigned int res)
2488 {
2489 /* Looks like the unsol event is incompatible with the standard
2490 * definition. 4bit tag is placed at 28 bit!
2491 */
2492 if ((res >> 28) == ALC880_HP_EVENT)
2493 alc880_medion_rim_automute(codec);
2494 }
2495
2496 #ifdef CONFIG_SND_HDA_POWER_SAVE
2497 static struct hda_amp_list alc880_loopbacks[] = {
2498 { 0x0b, HDA_INPUT, 0 },
2499 { 0x0b, HDA_INPUT, 1 },
2500 { 0x0b, HDA_INPUT, 2 },
2501 { 0x0b, HDA_INPUT, 3 },
2502 { 0x0b, HDA_INPUT, 4 },
2503 { } /* end */
2504 };
2505
2506 static struct hda_amp_list alc880_lg_loopbacks[] = {
2507 { 0x0b, HDA_INPUT, 1 },
2508 { 0x0b, HDA_INPUT, 6 },
2509 { 0x0b, HDA_INPUT, 7 },
2510 { } /* end */
2511 };
2512 #endif
2513
2514 /*
2515 * Common callbacks
2516 */
2517
2518 static int alc_init(struct hda_codec *codec)
2519 {
2520 struct alc_spec *spec = codec->spec;
2521 unsigned int i;
2522
2523 alc_fix_pll(codec);
2524 if (codec->vendor_id == 0x10ec0888)
2525 alc888_coef_init(codec);
2526
2527 for (i = 0; i < spec->num_init_verbs; i++)
2528 snd_hda_sequence_write(codec, spec->init_verbs[i]);
2529
2530 if (spec->init_hook)
2531 spec->init_hook(codec);
2532
2533 return 0;
2534 }
2535
2536 static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
2537 {
2538 struct alc_spec *spec = codec->spec;
2539
2540 if (spec->unsol_event)
2541 spec->unsol_event(codec, res);
2542 }
2543
2544 #ifdef CONFIG_SND_HDA_POWER_SAVE
2545 static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
2546 {
2547 struct alc_spec *spec = codec->spec;
2548 return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
2549 }
2550 #endif
2551
2552 /*
2553 * Analog playback callbacks
2554 */
2555 static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
2556 struct hda_codec *codec,
2557 struct snd_pcm_substream *substream)
2558 {
2559 struct alc_spec *spec = codec->spec;
2560 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
2561 hinfo);
2562 }
2563
2564 static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
2565 struct hda_codec *codec,
2566 unsigned int stream_tag,
2567 unsigned int format,
2568 struct snd_pcm_substream *substream)
2569 {
2570 struct alc_spec *spec = codec->spec;
2571 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
2572 stream_tag, format, substream);
2573 }
2574
2575 static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
2576 struct hda_codec *codec,
2577 struct snd_pcm_substream *substream)
2578 {
2579 struct alc_spec *spec = codec->spec;
2580 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
2581 }
2582
2583 /*
2584 * Digital out
2585 */
2586 static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
2587 struct hda_codec *codec,
2588 struct snd_pcm_substream *substream)
2589 {
2590 struct alc_spec *spec = codec->spec;
2591 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
2592 }
2593
2594 static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
2595 struct hda_codec *codec,
2596 unsigned int stream_tag,
2597 unsigned int format,
2598 struct snd_pcm_substream *substream)
2599 {
2600 struct alc_spec *spec = codec->spec;
2601 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
2602 stream_tag, format, substream);
2603 }
2604
2605 static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
2606 struct hda_codec *codec,
2607 struct snd_pcm_substream *substream)
2608 {
2609 struct alc_spec *spec = codec->spec;
2610 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
2611 }
2612
2613 /*
2614 * Analog capture
2615 */
2616 static int alc880_alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
2617 struct hda_codec *codec,
2618 unsigned int stream_tag,
2619 unsigned int format,
2620 struct snd_pcm_substream *substream)
2621 {
2622 struct alc_spec *spec = codec->spec;
2623
2624 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1],
2625 stream_tag, 0, format);
2626 return 0;
2627 }
2628
2629 static int alc880_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
2630 struct hda_codec *codec,
2631 struct snd_pcm_substream *substream)
2632 {
2633 struct alc_spec *spec = codec->spec;
2634
2635 snd_hda_codec_cleanup_stream(codec,
2636 spec->adc_nids[substream->number + 1]);
2637 return 0;
2638 }
2639
2640
2641 /*
2642 */
2643 static struct hda_pcm_stream alc880_pcm_analog_playback = {
2644 .substreams = 1,
2645 .channels_min = 2,
2646 .channels_max = 8,
2647 /* NID is set in alc_build_pcms */
2648 .ops = {
2649 .open = alc880_playback_pcm_open,
2650 .prepare = alc880_playback_pcm_prepare,
2651 .cleanup = alc880_playback_pcm_cleanup
2652 },
2653 };
2654
2655 static struct hda_pcm_stream alc880_pcm_analog_capture = {
2656 .substreams = 1,
2657 .channels_min = 2,
2658 .channels_max = 2,
2659 /* NID is set in alc_build_pcms */
2660 };
2661
2662 static struct hda_pcm_stream alc880_pcm_analog_alt_playback = {
2663 .substreams = 1,
2664 .channels_min = 2,
2665 .channels_max = 2,
2666 /* NID is set in alc_build_pcms */
2667 };
2668
2669 static struct hda_pcm_stream alc880_pcm_analog_alt_capture = {
2670 .substreams = 2, /* can be overridden */
2671 .channels_min = 2,
2672 .channels_max = 2,
2673 /* NID is set in alc_build_pcms */
2674 .ops = {
2675 .prepare = alc880_alt_capture_pcm_prepare,
2676 .cleanup = alc880_alt_capture_pcm_cleanup
2677 },
2678 };
2679
2680 static struct hda_pcm_stream alc880_pcm_digital_playback = {
2681 .substreams = 1,
2682 .channels_min = 2,
2683 .channels_max = 2,
2684 /* NID is set in alc_build_pcms */
2685 .ops = {
2686 .open = alc880_dig_playback_pcm_open,
2687 .close = alc880_dig_playback_pcm_close,
2688 .prepare = alc880_dig_playback_pcm_prepare
2689 },
2690 };
2691
2692 static struct hda_pcm_stream alc880_pcm_digital_capture = {
2693 .substreams = 1,
2694 .channels_min = 2,
2695 .channels_max = 2,
2696 /* NID is set in alc_build_pcms */
2697 };
2698
2699 /* Used by alc_build_pcms to flag that a PCM has no playback stream */
2700 static struct hda_pcm_stream alc_pcm_null_stream = {
2701 .substreams = 0,
2702 .channels_min = 0,
2703 .channels_max = 0,
2704 };
2705
2706 static int alc_build_pcms(struct hda_codec *codec)
2707 {
2708 struct alc_spec *spec = codec->spec;
2709 struct hda_pcm *info = spec->pcm_rec;
2710 int i;
2711
2712 codec->num_pcms = 1;
2713 codec->pcm_info = info;
2714
2715 info->name = spec->stream_name_analog;
2716 if (spec->stream_analog_playback) {
2717 if (snd_BUG_ON(!spec->multiout.dac_nids))
2718 return -EINVAL;
2719 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
2720 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
2721 }
2722 if (spec->stream_analog_capture) {
2723 if (snd_BUG_ON(!spec->adc_nids))
2724 return -EINVAL;
2725 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
2726 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
2727 }
2728
2729 if (spec->channel_mode) {
2730 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
2731 for (i = 0; i < spec->num_channel_mode; i++) {
2732 if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
2733 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
2734 }
2735 }
2736 }
2737
2738 /* SPDIF for stream index #1 */
2739 if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
2740 codec->num_pcms = 2;
2741 info = spec->pcm_rec + 1;
2742 info->name = spec->stream_name_digital;
2743 info->pcm_type = HDA_PCM_TYPE_SPDIF;
2744 if (spec->multiout.dig_out_nid &&
2745 spec->stream_digital_playback) {
2746 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
2747 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
2748 }
2749 if (spec->dig_in_nid &&
2750 spec->stream_digital_capture) {
2751 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
2752 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
2753 }
2754 /* FIXME: do we need this for all Realtek codec models? */
2755 codec->spdif_status_reset = 1;
2756 }
2757
2758 /* If the use of more than one ADC is requested for the current
2759 * model, configure a second analog capture-only PCM.
2760 */
2761 /* Additional Analaog capture for index #2 */
2762 if ((spec->alt_dac_nid && spec->stream_analog_alt_playback) ||
2763 (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture)) {
2764 codec->num_pcms = 3;
2765 info = spec->pcm_rec + 2;
2766 info->name = spec->stream_name_analog;
2767 if (spec->alt_dac_nid) {
2768 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
2769 *spec->stream_analog_alt_playback;
2770 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
2771 spec->alt_dac_nid;
2772 } else {
2773 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
2774 alc_pcm_null_stream;
2775 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
2776 }
2777 if (spec->num_adc_nids > 1) {
2778 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
2779 *spec->stream_analog_alt_capture;
2780 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
2781 spec->adc_nids[1];
2782 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
2783 spec->num_adc_nids - 1;
2784 } else {
2785 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
2786 alc_pcm_null_stream;
2787 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 0;
2788 }
2789 }
2790
2791 return 0;
2792 }
2793
2794 static void alc_free_kctls(struct hda_codec *codec)
2795 {
2796 struct alc_spec *spec = codec->spec;
2797
2798 if (spec->kctls.list) {
2799 struct snd_kcontrol_new *kctl = spec->kctls.list;
2800 int i;
2801 for (i = 0; i < spec->kctls.used; i++)
2802 kfree(kctl[i].name);
2803 }
2804 snd_array_free(&spec->kctls);
2805 }
2806
2807 static void alc_free(struct hda_codec *codec)
2808 {
2809 struct alc_spec *spec = codec->spec;
2810
2811 if (!spec)
2812 return;
2813
2814 alc_free_kctls(codec);
2815 kfree(spec);
2816 codec->spec = NULL; /* to be sure */
2817 }
2818
2819 #ifdef SND_HDA_NEEDS_RESUME
2820 static void store_pin_configs(struct hda_codec *codec)
2821 {
2822 struct alc_spec *spec = codec->spec;
2823 hda_nid_t nid, end_nid;
2824
2825 end_nid = codec->start_nid + codec->num_nodes;
2826 for (nid = codec->start_nid; nid < end_nid; nid++) {
2827 unsigned int wid_caps = get_wcaps(codec, nid);
2828 unsigned int wid_type =
2829 (wid_caps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
2830 if (wid_type != AC_WID_PIN)
2831 continue;
2832 if (spec->num_pins >= ARRAY_SIZE(spec->pin_nids))
2833 break;
2834 spec->pin_nids[spec->num_pins] = nid;
2835 spec->pin_cfgs[spec->num_pins] =
2836 snd_hda_codec_read(codec, nid, 0,
2837 AC_VERB_GET_CONFIG_DEFAULT, 0);
2838 spec->num_pins++;
2839 }
2840 }
2841
2842 static void resume_pin_configs(struct hda_codec *codec)
2843 {
2844 struct alc_spec *spec = codec->spec;
2845 int i;
2846
2847 for (i = 0; i < spec->num_pins; i++) {
2848 hda_nid_t pin_nid = spec->pin_nids[i];
2849 unsigned int pin_config = spec->pin_cfgs[i];
2850 snd_hda_codec_write(codec, pin_nid, 0,
2851 AC_VERB_SET_CONFIG_DEFAULT_BYTES_0,
2852 pin_config & 0x000000ff);
2853 snd_hda_codec_write(codec, pin_nid, 0,
2854 AC_VERB_SET_CONFIG_DEFAULT_BYTES_1,
2855 (pin_config & 0x0000ff00) >> 8);
2856 snd_hda_codec_write(codec, pin_nid, 0,
2857 AC_VERB_SET_CONFIG_DEFAULT_BYTES_2,
2858 (pin_config & 0x00ff0000) >> 16);
2859 snd_hda_codec_write(codec, pin_nid, 0,
2860 AC_VERB_SET_CONFIG_DEFAULT_BYTES_3,
2861 pin_config >> 24);
2862 }
2863 }
2864
2865 static int alc_resume(struct hda_codec *codec)
2866 {
2867 resume_pin_configs(codec);
2868 codec->patch_ops.init(codec);
2869 snd_hda_codec_resume_amp(codec);
2870 snd_hda_codec_resume_cache(codec);
2871 return 0;
2872 }
2873 #else
2874 #define store_pin_configs(codec)
2875 #endif
2876
2877 /*
2878 */
2879 static struct hda_codec_ops alc_patch_ops = {
2880 .build_controls = alc_build_controls,
2881 .build_pcms = alc_build_pcms,
2882 .init = alc_init,
2883 .free = alc_free,
2884 .unsol_event = alc_unsol_event,
2885 #ifdef SND_HDA_NEEDS_RESUME
2886 .resume = alc_resume,
2887 #endif
2888 #ifdef CONFIG_SND_HDA_POWER_SAVE
2889 .check_power_status = alc_check_power_status,
2890 #endif
2891 };
2892
2893
2894 /*
2895 * Test configuration for debugging
2896 *
2897 * Almost all inputs/outputs are enabled. I/O pins can be configured via
2898 * enum controls.
2899 */
2900 #ifdef CONFIG_SND_DEBUG
2901 static hda_nid_t alc880_test_dac_nids[4] = {
2902 0x02, 0x03, 0x04, 0x05
2903 };
2904
2905 static struct hda_input_mux alc880_test_capture_source = {
2906 .num_items = 7,
2907 .items = {
2908 { "In-1", 0x0 },
2909 { "In-2", 0x1 },
2910 { "In-3", 0x2 },
2911 { "In-4", 0x3 },
2912 { "CD", 0x4 },
2913 { "Front", 0x5 },
2914 { "Surround", 0x6 },
2915 },
2916 };
2917
2918 static struct hda_channel_mode alc880_test_modes[4] = {
2919 { 2, NULL },
2920 { 4, NULL },
2921 { 6, NULL },
2922 { 8, NULL },
2923 };
2924
2925 static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
2926 struct snd_ctl_elem_info *uinfo)
2927 {
2928 static char *texts[] = {
2929 "N/A", "Line Out", "HP Out",
2930 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
2931 };
2932 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2933 uinfo->count = 1;
2934 uinfo->value.enumerated.items = 8;
2935 if (uinfo->value.enumerated.item >= 8)
2936 uinfo->value.enumerated.item = 7;
2937 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2938 return 0;
2939 }
2940
2941 static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
2942 struct snd_ctl_elem_value *ucontrol)
2943 {
2944 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2945 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2946 unsigned int pin_ctl, item = 0;
2947
2948 pin_ctl = snd_hda_codec_read(codec, nid, 0,
2949 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
2950 if (pin_ctl & AC_PINCTL_OUT_EN) {
2951 if (pin_ctl & AC_PINCTL_HP_EN)
2952 item = 2;
2953 else
2954 item = 1;
2955 } else if (pin_ctl & AC_PINCTL_IN_EN) {
2956 switch (pin_ctl & AC_PINCTL_VREFEN) {
2957 case AC_PINCTL_VREF_HIZ: item = 3; break;
2958 case AC_PINCTL_VREF_50: item = 4; break;
2959 case AC_PINCTL_VREF_GRD: item = 5; break;
2960 case AC_PINCTL_VREF_80: item = 6; break;
2961 case AC_PINCTL_VREF_100: item = 7; break;
2962 }
2963 }
2964 ucontrol->value.enumerated.item[0] = item;
2965 return 0;
2966 }
2967
2968 static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
2969 struct snd_ctl_elem_value *ucontrol)
2970 {
2971 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2972 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2973 static unsigned int ctls[] = {
2974 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
2975 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
2976 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
2977 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
2978 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
2979 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
2980 };
2981 unsigned int old_ctl, new_ctl;
2982
2983 old_ctl = snd_hda_codec_read(codec, nid, 0,
2984 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
2985 new_ctl = ctls[ucontrol->value.enumerated.item[0]];
2986 if (old_ctl != new_ctl) {
2987 int val;
2988 snd_hda_codec_write_cache(codec, nid, 0,
2989 AC_VERB_SET_PIN_WIDGET_CONTROL,
2990 new_ctl);
2991 val = ucontrol->value.enumerated.item[0] >= 3 ?
2992 HDA_AMP_MUTE : 0;
2993 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
2994 HDA_AMP_MUTE, val);
2995 return 1;
2996 }
2997 return 0;
2998 }
2999
3000 static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
3001 struct snd_ctl_elem_info *uinfo)
3002 {
3003 static char *texts[] = {
3004 "Front", "Surround", "CLFE", "Side"
3005 };
3006 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
3007 uinfo->count = 1;
3008 uinfo->value.enumerated.items = 4;
3009 if (uinfo->value.enumerated.item >= 4)
3010 uinfo->value.enumerated.item = 3;
3011 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
3012 return 0;
3013 }
3014
3015 static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
3016 struct snd_ctl_elem_value *ucontrol)
3017 {
3018 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3019 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3020 unsigned int sel;
3021
3022 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
3023 ucontrol->value.enumerated.item[0] = sel & 3;
3024 return 0;
3025 }
3026
3027 static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
3028 struct snd_ctl_elem_value *ucontrol)
3029 {
3030 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3031 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
3032 unsigned int sel;
3033
3034 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
3035 if (ucontrol->value.enumerated.item[0] != sel) {
3036 sel = ucontrol->value.enumerated.item[0] & 3;
3037 snd_hda_codec_write_cache(codec, nid, 0,
3038 AC_VERB_SET_CONNECT_SEL, sel);
3039 return 1;
3040 }
3041 return 0;
3042 }
3043
3044 #define PIN_CTL_TEST(xname,nid) { \
3045 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
3046 .name = xname, \
3047 .info = alc_test_pin_ctl_info, \
3048 .get = alc_test_pin_ctl_get, \
3049 .put = alc_test_pin_ctl_put, \
3050 .private_value = nid \
3051 }
3052
3053 #define PIN_SRC_TEST(xname,nid) { \
3054 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
3055 .name = xname, \
3056 .info = alc_test_pin_src_info, \
3057 .get = alc_test_pin_src_get, \
3058 .put = alc_test_pin_src_put, \
3059 .private_value = nid \
3060 }
3061
3062 static struct snd_kcontrol_new alc880_test_mixer[] = {
3063 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3064 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3065 HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
3066 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3067 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
3068 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
3069 HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
3070 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
3071 PIN_CTL_TEST("Front Pin Mode", 0x14),
3072 PIN_CTL_TEST("Surround Pin Mode", 0x15),
3073 PIN_CTL_TEST("CLFE Pin Mode", 0x16),
3074 PIN_CTL_TEST("Side Pin Mode", 0x17),
3075 PIN_CTL_TEST("In-1 Pin Mode", 0x18),
3076 PIN_CTL_TEST("In-2 Pin Mode", 0x19),
3077 PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
3078 PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
3079 PIN_SRC_TEST("In-1 Pin Source", 0x18),
3080 PIN_SRC_TEST("In-2 Pin Source", 0x19),
3081 PIN_SRC_TEST("In-3 Pin Source", 0x1a),
3082 PIN_SRC_TEST("In-4 Pin Source", 0x1b),
3083 HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
3084 HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
3085 HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
3086 HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
3087 HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
3088 HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
3089 HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
3090 HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
3091 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
3092 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
3093 {
3094 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3095 .name = "Channel Mode",
3096 .info = alc_ch_mode_info,
3097 .get = alc_ch_mode_get,
3098 .put = alc_ch_mode_put,
3099 },
3100 { } /* end */
3101 };
3102
3103 static struct hda_verb alc880_test_init_verbs[] = {
3104 /* Unmute inputs of 0x0c - 0x0f */
3105 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3106 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3107 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3108 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3109 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3110 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3111 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3112 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3113 /* Vol output for 0x0c-0x0f */
3114 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3115 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3116 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3117 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3118 /* Set output pins 0x14-0x17 */
3119 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3120 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3121 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3122 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3123 /* Unmute output pins 0x14-0x17 */
3124 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3125 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3126 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3127 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3128 /* Set input pins 0x18-0x1c */
3129 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3130 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3131 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3132 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3133 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3134 /* Mute input pins 0x18-0x1b */
3135 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3136 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3137 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3138 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3139 /* ADC set up */
3140 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3141 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
3142 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3143 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
3144 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3145 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
3146 /* Analog input/passthru */
3147 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3148 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3149 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3150 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3151 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3152 { }
3153 };
3154 #endif
3155
3156 /*
3157 */
3158
3159 static const char *alc880_models[ALC880_MODEL_LAST] = {
3160 [ALC880_3ST] = "3stack",
3161 [ALC880_TCL_S700] = "tcl",
3162 [ALC880_3ST_DIG] = "3stack-digout",
3163 [ALC880_CLEVO] = "clevo",
3164 [ALC880_5ST] = "5stack",
3165 [ALC880_5ST_DIG] = "5stack-digout",
3166 [ALC880_W810] = "w810",
3167 [ALC880_Z71V] = "z71v",
3168 [ALC880_6ST] = "6stack",
3169 [ALC880_6ST_DIG] = "6stack-digout",
3170 [ALC880_ASUS] = "asus",
3171 [ALC880_ASUS_W1V] = "asus-w1v",
3172 [ALC880_ASUS_DIG] = "asus-dig",
3173 [ALC880_ASUS_DIG2] = "asus-dig2",
3174 [ALC880_UNIWILL_DIG] = "uniwill",
3175 [ALC880_UNIWILL_P53] = "uniwill-p53",
3176 [ALC880_FUJITSU] = "fujitsu",
3177 [ALC880_F1734] = "F1734",
3178 [ALC880_LG] = "lg",
3179 [ALC880_LG_LW] = "lg-lw",
3180 [ALC880_MEDION_RIM] = "medion",
3181 #ifdef CONFIG_SND_DEBUG
3182 [ALC880_TEST] = "test",
3183 #endif
3184 [ALC880_AUTO] = "auto",
3185 };
3186
3187 static struct snd_pci_quirk alc880_cfg_tbl[] = {
3188 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
3189 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
3190 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
3191 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
3192 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
3193 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
3194 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
3195 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
3196 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
3197 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
3198 SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST),
3199 SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
3200 SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
3201 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
3202 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
3203 SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
3204 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
3205 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
3206 /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
3207 SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
3208 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
3209 SND_PCI_QUIRK(0x1043, 0x814e, "ASUS P5GD1 w/SPDIF", ALC880_6ST_DIG),
3210 SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
3211 SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
3212 SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
3213 SND_PCI_QUIRK(0x1043, 0, "ASUS", ALC880_ASUS), /* default ASUS */
3214 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
3215 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
3216 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
3217 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
3218 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
3219 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
3220 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
3221 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
3222 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
3223 SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
3224 SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
3225 SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
3226 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
3227 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
3228 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwlll", ALC880_F1734),
3229 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
3230 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
3231 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
3232 SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_MEDION_RIM),
3233 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
3234 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
3235 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
3236 SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU),
3237 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC", ALC880_UNIWILL),
3238 SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
3239 SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
3240 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
3241 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
3242 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
3243 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
3244 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */
3245 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
3246 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
3247 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
3248 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
3249 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
3250 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
3251 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
3252 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
3253 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
3254 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
3255 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
3256 SND_PCI_QUIRK(0x8086, 0, "Intel mobo", ALC880_3ST), /* default Intel */
3257 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
3258 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
3259 {}
3260 };
3261
3262 /*
3263 * ALC880 codec presets
3264 */
3265 static struct alc_config_preset alc880_presets[] = {
3266 [ALC880_3ST] = {
3267 .mixers = { alc880_three_stack_mixer },
3268 .init_verbs = { alc880_volume_init_verbs,
3269 alc880_pin_3stack_init_verbs },
3270 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3271 .dac_nids = alc880_dac_nids,
3272 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3273 .channel_mode = alc880_threestack_modes,
3274 .need_dac_fix = 1,
3275 .input_mux = &alc880_capture_source,
3276 },
3277 [ALC880_3ST_DIG] = {
3278 .mixers = { alc880_three_stack_mixer },
3279 .init_verbs = { alc880_volume_init_verbs,
3280 alc880_pin_3stack_init_verbs },
3281 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3282 .dac_nids = alc880_dac_nids,
3283 .dig_out_nid = ALC880_DIGOUT_NID,
3284 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3285 .channel_mode = alc880_threestack_modes,
3286 .need_dac_fix = 1,
3287 .input_mux = &alc880_capture_source,
3288 },
3289 [ALC880_TCL_S700] = {
3290 .mixers = { alc880_tcl_s700_mixer },
3291 .init_verbs = { alc880_volume_init_verbs,
3292 alc880_pin_tcl_S700_init_verbs,
3293 alc880_gpio2_init_verbs },
3294 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3295 .dac_nids = alc880_dac_nids,
3296 .hp_nid = 0x03,
3297 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3298 .channel_mode = alc880_2_jack_modes,
3299 .input_mux = &alc880_capture_source,
3300 },
3301 [ALC880_5ST] = {
3302 .mixers = { alc880_three_stack_mixer,
3303 alc880_five_stack_mixer},
3304 .init_verbs = { alc880_volume_init_verbs,
3305 alc880_pin_5stack_init_verbs },
3306 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3307 .dac_nids = alc880_dac_nids,
3308 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
3309 .channel_mode = alc880_fivestack_modes,
3310 .input_mux = &alc880_capture_source,
3311 },
3312 [ALC880_5ST_DIG] = {
3313 .mixers = { alc880_three_stack_mixer,
3314 alc880_five_stack_mixer },
3315 .init_verbs = { alc880_volume_init_verbs,
3316 alc880_pin_5stack_init_verbs },
3317 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3318 .dac_nids = alc880_dac_nids,
3319 .dig_out_nid = ALC880_DIGOUT_NID,
3320 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
3321 .channel_mode = alc880_fivestack_modes,
3322 .input_mux = &alc880_capture_source,
3323 },
3324 [ALC880_6ST] = {
3325 .mixers = { alc880_six_stack_mixer },
3326 .init_verbs = { alc880_volume_init_verbs,
3327 alc880_pin_6stack_init_verbs },
3328 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
3329 .dac_nids = alc880_6st_dac_nids,
3330 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
3331 .channel_mode = alc880_sixstack_modes,
3332 .input_mux = &alc880_6stack_capture_source,
3333 },
3334 [ALC880_6ST_DIG] = {
3335 .mixers = { alc880_six_stack_mixer },
3336 .init_verbs = { alc880_volume_init_verbs,
3337 alc880_pin_6stack_init_verbs },
3338 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
3339 .dac_nids = alc880_6st_dac_nids,
3340 .dig_out_nid = ALC880_DIGOUT_NID,
3341 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
3342 .channel_mode = alc880_sixstack_modes,
3343 .input_mux = &alc880_6stack_capture_source,
3344 },
3345 [ALC880_W810] = {
3346 .mixers = { alc880_w810_base_mixer },
3347 .init_verbs = { alc880_volume_init_verbs,
3348 alc880_pin_w810_init_verbs,
3349 alc880_gpio2_init_verbs },
3350 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
3351 .dac_nids = alc880_w810_dac_nids,
3352 .dig_out_nid = ALC880_DIGOUT_NID,
3353 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
3354 .channel_mode = alc880_w810_modes,
3355 .input_mux = &alc880_capture_source,
3356 },
3357 [ALC880_Z71V] = {
3358 .mixers = { alc880_z71v_mixer },
3359 .init_verbs = { alc880_volume_init_verbs,
3360 alc880_pin_z71v_init_verbs },
3361 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
3362 .dac_nids = alc880_z71v_dac_nids,
3363 .dig_out_nid = ALC880_DIGOUT_NID,
3364 .hp_nid = 0x03,
3365 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3366 .channel_mode = alc880_2_jack_modes,
3367 .input_mux = &alc880_capture_source,
3368 },
3369 [ALC880_F1734] = {
3370 .mixers = { alc880_f1734_mixer },
3371 .init_verbs = { alc880_volume_init_verbs,
3372 alc880_pin_f1734_init_verbs },
3373 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
3374 .dac_nids = alc880_f1734_dac_nids,
3375 .hp_nid = 0x02,
3376 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3377 .channel_mode = alc880_2_jack_modes,
3378 .input_mux = &alc880_f1734_capture_source,
3379 .unsol_event = alc880_uniwill_p53_unsol_event,
3380 .init_hook = alc880_uniwill_p53_hp_automute,
3381 },
3382 [ALC880_ASUS] = {
3383 .mixers = { alc880_asus_mixer },
3384 .init_verbs = { alc880_volume_init_verbs,
3385 alc880_pin_asus_init_verbs,
3386 alc880_gpio1_init_verbs },
3387 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3388 .dac_nids = alc880_asus_dac_nids,
3389 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3390 .channel_mode = alc880_asus_modes,
3391 .need_dac_fix = 1,
3392 .input_mux = &alc880_capture_source,
3393 },
3394 [ALC880_ASUS_DIG] = {
3395 .mixers = { alc880_asus_mixer },
3396 .init_verbs = { alc880_volume_init_verbs,
3397 alc880_pin_asus_init_verbs,
3398 alc880_gpio1_init_verbs },
3399 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3400 .dac_nids = alc880_asus_dac_nids,
3401 .dig_out_nid = ALC880_DIGOUT_NID,
3402 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3403 .channel_mode = alc880_asus_modes,
3404 .need_dac_fix = 1,
3405 .input_mux = &alc880_capture_source,
3406 },
3407 [ALC880_ASUS_DIG2] = {
3408 .mixers = { alc880_asus_mixer },
3409 .init_verbs = { alc880_volume_init_verbs,
3410 alc880_pin_asus_init_verbs,
3411 alc880_gpio2_init_verbs }, /* use GPIO2 */
3412 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3413 .dac_nids = alc880_asus_dac_nids,
3414 .dig_out_nid = ALC880_DIGOUT_NID,
3415 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3416 .channel_mode = alc880_asus_modes,
3417 .need_dac_fix = 1,
3418 .input_mux = &alc880_capture_source,
3419 },
3420 [ALC880_ASUS_W1V] = {
3421 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
3422 .init_verbs = { alc880_volume_init_verbs,
3423 alc880_pin_asus_init_verbs,
3424 alc880_gpio1_init_verbs },
3425 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3426 .dac_nids = alc880_asus_dac_nids,
3427 .dig_out_nid = ALC880_DIGOUT_NID,
3428 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3429 .channel_mode = alc880_asus_modes,
3430 .need_dac_fix = 1,
3431 .input_mux = &alc880_capture_source,
3432 },
3433 [ALC880_UNIWILL_DIG] = {
3434 .mixers = { alc880_asus_mixer, alc880_pcbeep_mixer },
3435 .init_verbs = { alc880_volume_init_verbs,
3436 alc880_pin_asus_init_verbs },
3437 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3438 .dac_nids = alc880_asus_dac_nids,
3439 .dig_out_nid = ALC880_DIGOUT_NID,
3440 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
3441 .channel_mode = alc880_asus_modes,
3442 .need_dac_fix = 1,
3443 .input_mux = &alc880_capture_source,
3444 },
3445 [ALC880_UNIWILL] = {
3446 .mixers = { alc880_uniwill_mixer },
3447 .init_verbs = { alc880_volume_init_verbs,
3448 alc880_uniwill_init_verbs },
3449 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3450 .dac_nids = alc880_asus_dac_nids,
3451 .dig_out_nid = ALC880_DIGOUT_NID,
3452 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3453 .channel_mode = alc880_threestack_modes,
3454 .need_dac_fix = 1,
3455 .input_mux = &alc880_capture_source,
3456 .unsol_event = alc880_uniwill_unsol_event,
3457 .init_hook = alc880_uniwill_automute,
3458 },
3459 [ALC880_UNIWILL_P53] = {
3460 .mixers = { alc880_uniwill_p53_mixer },
3461 .init_verbs = { alc880_volume_init_verbs,
3462 alc880_uniwill_p53_init_verbs },
3463 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3464 .dac_nids = alc880_asus_dac_nids,
3465 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
3466 .channel_mode = alc880_threestack_modes,
3467 .input_mux = &alc880_capture_source,
3468 .unsol_event = alc880_uniwill_p53_unsol_event,
3469 .init_hook = alc880_uniwill_p53_hp_automute,
3470 },
3471 [ALC880_FUJITSU] = {
3472 .mixers = { alc880_fujitsu_mixer,
3473 alc880_pcbeep_mixer, },
3474 .init_verbs = { alc880_volume_init_verbs,
3475 alc880_uniwill_p53_init_verbs,
3476 alc880_beep_init_verbs },
3477 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3478 .dac_nids = alc880_dac_nids,
3479 .dig_out_nid = ALC880_DIGOUT_NID,
3480 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3481 .channel_mode = alc880_2_jack_modes,
3482 .input_mux = &alc880_capture_source,
3483 .unsol_event = alc880_uniwill_p53_unsol_event,
3484 .init_hook = alc880_uniwill_p53_hp_automute,
3485 },
3486 [ALC880_CLEVO] = {
3487 .mixers = { alc880_three_stack_mixer },
3488 .init_verbs = { alc880_volume_init_verbs,
3489 alc880_pin_clevo_init_verbs },
3490 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3491 .dac_nids = alc880_dac_nids,
3492 .hp_nid = 0x03,
3493 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3494 .channel_mode = alc880_threestack_modes,
3495 .need_dac_fix = 1,
3496 .input_mux = &alc880_capture_source,
3497 },
3498 [ALC880_LG] = {
3499 .mixers = { alc880_lg_mixer },
3500 .init_verbs = { alc880_volume_init_verbs,
3501 alc880_lg_init_verbs },
3502 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
3503 .dac_nids = alc880_lg_dac_nids,
3504 .dig_out_nid = ALC880_DIGOUT_NID,
3505 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
3506 .channel_mode = alc880_lg_ch_modes,
3507 .need_dac_fix = 1,
3508 .input_mux = &alc880_lg_capture_source,
3509 .unsol_event = alc880_lg_unsol_event,
3510 .init_hook = alc880_lg_automute,
3511 #ifdef CONFIG_SND_HDA_POWER_SAVE
3512 .loopbacks = alc880_lg_loopbacks,
3513 #endif
3514 },
3515 [ALC880_LG_LW] = {
3516 .mixers = { alc880_lg_lw_mixer },
3517 .init_verbs = { alc880_volume_init_verbs,
3518 alc880_lg_lw_init_verbs },
3519 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3520 .dac_nids = alc880_dac_nids,
3521 .dig_out_nid = ALC880_DIGOUT_NID,
3522 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
3523 .channel_mode = alc880_lg_lw_modes,
3524 .input_mux = &alc880_lg_lw_capture_source,
3525 .unsol_event = alc880_lg_lw_unsol_event,
3526 .init_hook = alc880_lg_lw_automute,
3527 },
3528 [ALC880_MEDION_RIM] = {
3529 .mixers = { alc880_medion_rim_mixer },
3530 .init_verbs = { alc880_volume_init_verbs,
3531 alc880_medion_rim_init_verbs,
3532 alc_gpio2_init_verbs },
3533 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3534 .dac_nids = alc880_dac_nids,
3535 .dig_out_nid = ALC880_DIGOUT_NID,
3536 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3537 .channel_mode = alc880_2_jack_modes,
3538 .input_mux = &alc880_medion_rim_capture_source,
3539 .unsol_event = alc880_medion_rim_unsol_event,
3540 .init_hook = alc880_medion_rim_automute,
3541 },
3542 #ifdef CONFIG_SND_DEBUG
3543 [ALC880_TEST] = {
3544 .mixers = { alc880_test_mixer },
3545 .init_verbs = { alc880_test_init_verbs },
3546 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
3547 .dac_nids = alc880_test_dac_nids,
3548 .dig_out_nid = ALC880_DIGOUT_NID,
3549 .num_channel_mode = ARRAY_SIZE(alc880_test_modes),
3550 .channel_mode = alc880_test_modes,
3551 .input_mux = &alc880_test_capture_source,
3552 },
3553 #endif
3554 };
3555
3556 /*
3557 * Automatic parse of I/O pins from the BIOS configuration
3558 */
3559
3560 enum {
3561 ALC_CTL_WIDGET_VOL,
3562 ALC_CTL_WIDGET_MUTE,
3563 ALC_CTL_BIND_MUTE,
3564 };
3565 static struct snd_kcontrol_new alc880_control_templates[] = {
3566 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
3567 HDA_CODEC_MUTE(NULL, 0, 0, 0),
3568 HDA_BIND_MUTE(NULL, 0, 0, 0),
3569 };
3570
3571 /* add dynamic controls */
3572 static int add_control(struct alc_spec *spec, int type, const char *name,
3573 unsigned long val)
3574 {
3575 struct snd_kcontrol_new *knew;
3576
3577 snd_array_init(&spec->kctls, sizeof(*knew), 32);
3578 knew = snd_array_new(&spec->kctls);
3579 if (!knew)
3580 return -ENOMEM;
3581 *knew = alc880_control_templates[type];
3582 knew->name = kstrdup(name, GFP_KERNEL);
3583 if (!knew->name)
3584 return -ENOMEM;
3585 knew->private_value = val;
3586 return 0;
3587 }
3588
3589 #define alc880_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17)
3590 #define alc880_fixed_pin_idx(nid) ((nid) - 0x14)
3591 #define alc880_is_multi_pin(nid) ((nid) >= 0x18)
3592 #define alc880_multi_pin_idx(nid) ((nid) - 0x18)
3593 #define alc880_is_input_pin(nid) ((nid) >= 0x18)
3594 #define alc880_input_pin_idx(nid) ((nid) - 0x18)
3595 #define alc880_idx_to_dac(nid) ((nid) + 0x02)
3596 #define alc880_dac_to_idx(nid) ((nid) - 0x02)
3597 #define alc880_idx_to_mixer(nid) ((nid) + 0x0c)
3598 #define alc880_idx_to_selector(nid) ((nid) + 0x10)
3599 #define ALC880_PIN_CD_NID 0x1c
3600
3601 /* fill in the dac_nids table from the parsed pin configuration */
3602 static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
3603 const struct auto_pin_cfg *cfg)
3604 {
3605 hda_nid_t nid;
3606 int assigned[4];
3607 int i, j;
3608
3609 memset(assigned, 0, sizeof(assigned));
3610 spec->multiout.dac_nids = spec->private_dac_nids;
3611
3612 /* check the pins hardwired to audio widget */
3613 for (i = 0; i < cfg->line_outs; i++) {
3614 nid = cfg->line_out_pins[i];
3615 if (alc880_is_fixed_pin(nid)) {
3616 int idx = alc880_fixed_pin_idx(nid);
3617 spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx);
3618 assigned[idx] = 1;
3619 }
3620 }
3621 /* left pins can be connect to any audio widget */
3622 for (i = 0; i < cfg->line_outs; i++) {
3623 nid = cfg->line_out_pins[i];
3624 if (alc880_is_fixed_pin(nid))
3625 continue;
3626 /* search for an empty channel */
3627 for (j = 0; j < cfg->line_outs; j++) {
3628 if (!assigned[j]) {
3629 spec->multiout.dac_nids[i] =
3630 alc880_idx_to_dac(j);
3631 assigned[j] = 1;
3632 break;
3633 }
3634 }
3635 }
3636 spec->multiout.num_dacs = cfg->line_outs;
3637 return 0;
3638 }
3639
3640 /* add playback controls from the parsed DAC table */
3641 static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
3642 const struct auto_pin_cfg *cfg)
3643 {
3644 char name[32];
3645 static const char *chname[4] = {
3646 "Front", "Surround", NULL /*CLFE*/, "Side"
3647 };
3648 hda_nid_t nid;
3649 int i, err;
3650
3651 for (i = 0; i < cfg->line_outs; i++) {
3652 if (!spec->multiout.dac_nids[i])
3653 continue;
3654 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
3655 if (i == 2) {
3656 /* Center/LFE */
3657 err = add_control(spec, ALC_CTL_WIDGET_VOL,
3658 "Center Playback Volume",
3659 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
3660 HDA_OUTPUT));
3661 if (err < 0)
3662 return err;
3663 err = add_control(spec, ALC_CTL_WIDGET_VOL,
3664 "LFE Playback Volume",
3665 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
3666 HDA_OUTPUT));
3667 if (err < 0)
3668 return err;
3669 err = add_control(spec, ALC_CTL_BIND_MUTE,
3670 "Center Playback Switch",
3671 HDA_COMPOSE_AMP_VAL(nid, 1, 2,
3672 HDA_INPUT));
3673 if (err < 0)
3674 return err;
3675 err = add_control(spec, ALC_CTL_BIND_MUTE,
3676 "LFE Playback Switch",
3677 HDA_COMPOSE_AMP_VAL(nid, 2, 2,
3678 HDA_INPUT));
3679 if (err < 0)
3680 return err;
3681 } else {
3682 sprintf(name, "%s Playback Volume", chname[i]);
3683 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3684 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
3685 HDA_OUTPUT));
3686 if (err < 0)
3687 return err;
3688 sprintf(name, "%s Playback Switch", chname[i]);
3689 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
3690 HDA_COMPOSE_AMP_VAL(nid, 3, 2,
3691 HDA_INPUT));
3692 if (err < 0)
3693 return err;
3694 }
3695 }
3696 return 0;
3697 }
3698
3699 /* add playback controls for speaker and HP outputs */
3700 static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
3701 const char *pfx)
3702 {
3703 hda_nid_t nid;
3704 int err;
3705 char name[32];
3706
3707 if (!pin)
3708 return 0;
3709
3710 if (alc880_is_fixed_pin(pin)) {
3711 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
3712 /* specify the DAC as the extra output */
3713 if (!spec->multiout.hp_nid)
3714 spec->multiout.hp_nid = nid;
3715 else
3716 spec->multiout.extra_out_nid[0] = nid;
3717 /* control HP volume/switch on the output mixer amp */
3718 nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
3719 sprintf(name, "%s Playback Volume", pfx);
3720 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3721 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
3722 if (err < 0)
3723 return err;
3724 sprintf(name, "%s Playback Switch", pfx);
3725 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
3726 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
3727 if (err < 0)
3728 return err;
3729 } else if (alc880_is_multi_pin(pin)) {
3730 /* set manual connection */
3731 /* we have only a switch on HP-out PIN */
3732 sprintf(name, "%s Playback Switch", pfx);
3733 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
3734 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
3735 if (err < 0)
3736 return err;
3737 }
3738 return 0;
3739 }
3740
3741 /* create input playback/capture controls for the given pin */
3742 static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
3743 const char *ctlname,
3744 int idx, hda_nid_t mix_nid)
3745 {
3746 char name[32];
3747 int err;
3748
3749 sprintf(name, "%s Playback Volume", ctlname);
3750 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3751 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
3752 if (err < 0)
3753 return err;
3754 sprintf(name, "%s Playback Switch", ctlname);
3755 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
3756 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
3757 if (err < 0)
3758 return err;
3759 return 0;
3760 }
3761
3762 /* create playback/capture controls for input pins */
3763 static int alc880_auto_create_analog_input_ctls(struct alc_spec *spec,
3764 const struct auto_pin_cfg *cfg)
3765 {
3766 struct hda_input_mux *imux = &spec->private_imux;
3767 int i, err, idx;
3768
3769 for (i = 0; i < AUTO_PIN_LAST; i++) {
3770 if (alc880_is_input_pin(cfg->input_pins[i])) {
3771 idx = alc880_input_pin_idx(cfg->input_pins[i]);
3772 err = new_analog_input(spec, cfg->input_pins[i],
3773 auto_pin_cfg_labels[i],
3774 idx, 0x0b);
3775 if (err < 0)
3776 return err;
3777 imux->items[imux->num_items].label =
3778 auto_pin_cfg_labels[i];
3779 imux->items[imux->num_items].index =
3780 alc880_input_pin_idx(cfg->input_pins[i]);
3781 imux->num_items++;
3782 }
3783 }
3784 return 0;
3785 }
3786
3787 static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid,
3788 unsigned int pin_type)
3789 {
3790 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3791 pin_type);
3792 /* unmute pin */
3793 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
3794 AMP_OUT_UNMUTE);
3795 }
3796
3797 static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
3798 hda_nid_t nid, int pin_type,
3799 int dac_idx)
3800 {
3801 alc_set_pin_output(codec, nid, pin_type);
3802 /* need the manual connection? */
3803 if (alc880_is_multi_pin(nid)) {
3804 struct alc_spec *spec = codec->spec;
3805 int idx = alc880_multi_pin_idx(nid);
3806 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
3807 AC_VERB_SET_CONNECT_SEL,
3808 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
3809 }
3810 }
3811
3812 static int get_pin_type(int line_out_type)
3813 {
3814 if (line_out_type == AUTO_PIN_HP_OUT)
3815 return PIN_HP;
3816 else
3817 return PIN_OUT;
3818 }
3819
3820 static void alc880_auto_init_multi_out(struct hda_codec *codec)
3821 {
3822 struct alc_spec *spec = codec->spec;
3823 int i;
3824
3825 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
3826 for (i = 0; i < spec->autocfg.line_outs; i++) {
3827 hda_nid_t nid = spec->autocfg.line_out_pins[i];
3828 int pin_type = get_pin_type(spec->autocfg.line_out_type);
3829 alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
3830 }
3831 }
3832
3833 static void alc880_auto_init_extra_out(struct hda_codec *codec)
3834 {
3835 struct alc_spec *spec = codec->spec;
3836 hda_nid_t pin;
3837
3838 pin = spec->autocfg.speaker_pins[0];
3839 if (pin) /* connect to front */
3840 alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
3841 pin = spec->autocfg.hp_pins[0];
3842 if (pin) /* connect to front */
3843 alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
3844 }
3845
3846 static void alc880_auto_init_analog_input(struct hda_codec *codec)
3847 {
3848 struct alc_spec *spec = codec->spec;
3849 int i;
3850
3851 for (i = 0; i < AUTO_PIN_LAST; i++) {
3852 hda_nid_t nid = spec->autocfg.input_pins[i];
3853 if (alc880_is_input_pin(nid)) {
3854 snd_hda_codec_write(codec, nid, 0,
3855 AC_VERB_SET_PIN_WIDGET_CONTROL,
3856 i <= AUTO_PIN_FRONT_MIC ?
3857 PIN_VREF80 : PIN_IN);
3858 if (nid != ALC880_PIN_CD_NID)
3859 snd_hda_codec_write(codec, nid, 0,
3860 AC_VERB_SET_AMP_GAIN_MUTE,
3861 AMP_OUT_MUTE);
3862 }
3863 }
3864 }
3865
3866 /* parse the BIOS configuration and set up the alc_spec */
3867 /* return 1 if successful, 0 if the proper config is not found,
3868 * or a negative error code
3869 */
3870 static int alc880_parse_auto_config(struct hda_codec *codec)
3871 {
3872 struct alc_spec *spec = codec->spec;
3873 int err;
3874 static hda_nid_t alc880_ignore[] = { 0x1d, 0 };
3875
3876 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
3877 alc880_ignore);
3878 if (err < 0)
3879 return err;
3880 if (!spec->autocfg.line_outs)
3881 return 0; /* can't find valid BIOS pin config */
3882
3883 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
3884 if (err < 0)
3885 return err;
3886 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
3887 if (err < 0)
3888 return err;
3889 err = alc880_auto_create_extra_out(spec,
3890 spec->autocfg.speaker_pins[0],
3891 "Speaker");
3892 if (err < 0)
3893 return err;
3894 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
3895 "Headphone");
3896 if (err < 0)
3897 return err;
3898 err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
3899 if (err < 0)
3900 return err;
3901
3902 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
3903
3904 if (spec->autocfg.dig_out_pin)
3905 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
3906 if (spec->autocfg.dig_in_pin)
3907 spec->dig_in_nid = ALC880_DIGIN_NID;
3908
3909 if (spec->kctls.list)
3910 add_mixer(spec, spec->kctls.list);
3911
3912 add_verb(spec, alc880_volume_init_verbs);
3913
3914 spec->num_mux_defs = 1;
3915 spec->input_mux = &spec->private_imux;
3916
3917 store_pin_configs(codec);
3918 return 1;
3919 }
3920
3921 /* additional initialization for auto-configuration model */
3922 static void alc880_auto_init(struct hda_codec *codec)
3923 {
3924 struct alc_spec *spec = codec->spec;
3925 alc880_auto_init_multi_out(codec);
3926 alc880_auto_init_extra_out(codec);
3927 alc880_auto_init_analog_input(codec);
3928 if (spec->unsol_event)
3929 alc_inithook(codec);
3930 }
3931
3932 /*
3933 * OK, here we have finally the patch for ALC880
3934 */
3935
3936 static int patch_alc880(struct hda_codec *codec)
3937 {
3938 struct alc_spec *spec;
3939 int board_config;
3940 int err;
3941
3942 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
3943 if (spec == NULL)
3944 return -ENOMEM;
3945
3946 codec->spec = spec;
3947
3948 board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
3949 alc880_models,
3950 alc880_cfg_tbl);
3951 if (board_config < 0) {
3952 printk(KERN_INFO "hda_codec: Unknown model for ALC880, "
3953 "trying auto-probe from BIOS...\n");
3954 board_config = ALC880_AUTO;
3955 }
3956
3957 if (board_config == ALC880_AUTO) {
3958 /* automatic parse from the BIOS config */
3959 err = alc880_parse_auto_config(codec);
3960 if (err < 0) {
3961 alc_free(codec);
3962 return err;
3963 } else if (!err) {
3964 printk(KERN_INFO
3965 "hda_codec: Cannot set up configuration "
3966 "from BIOS. Using 3-stack mode...\n");
3967 board_config = ALC880_3ST;
3968 }
3969 }
3970
3971 if (board_config != ALC880_AUTO)
3972 setup_preset(spec, &alc880_presets[board_config]);
3973
3974 spec->stream_name_analog = "ALC880 Analog";
3975 spec->stream_analog_playback = &alc880_pcm_analog_playback;
3976 spec->stream_analog_capture = &alc880_pcm_analog_capture;
3977 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
3978
3979 spec->stream_name_digital = "ALC880 Digital";
3980 spec->stream_digital_playback = &alc880_pcm_digital_playback;
3981 spec->stream_digital_capture = &alc880_pcm_digital_capture;
3982
3983 if (!spec->adc_nids && spec->input_mux) {
3984 /* check whether NID 0x07 is valid */
3985 unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
3986 /* get type */
3987 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
3988 if (wcap != AC_WID_AUD_IN) {
3989 spec->adc_nids = alc880_adc_nids_alt;
3990 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
3991 add_mixer(spec, alc880_capture_alt_mixer);
3992 } else {
3993 spec->adc_nids = alc880_adc_nids;
3994 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
3995 add_mixer(spec, alc880_capture_mixer);
3996 }
3997 }
3998
3999 spec->vmaster_nid = 0x0c;
4000
4001 codec->patch_ops = alc_patch_ops;
4002 if (board_config == ALC880_AUTO)
4003 spec->init_hook = alc880_auto_init;
4004 #ifdef CONFIG_SND_HDA_POWER_SAVE
4005 if (!spec->loopback.amplist)
4006 spec->loopback.amplist = alc880_loopbacks;
4007 #endif
4008
4009 return 0;
4010 }
4011
4012
4013 /*
4014 * ALC260 support
4015 */
4016
4017 static hda_nid_t alc260_dac_nids[1] = {
4018 /* front */
4019 0x02,
4020 };
4021
4022 static hda_nid_t alc260_adc_nids[1] = {
4023 /* ADC0 */
4024 0x04,
4025 };
4026
4027 static hda_nid_t alc260_adc_nids_alt[1] = {
4028 /* ADC1 */
4029 0x05,
4030 };
4031
4032 static hda_nid_t alc260_hp_adc_nids[2] = {
4033 /* ADC1, 0 */
4034 0x05, 0x04
4035 };
4036
4037 /* NIDs used when simultaneous access to both ADCs makes sense. Note that
4038 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
4039 */
4040 static hda_nid_t alc260_dual_adc_nids[2] = {
4041 /* ADC0, ADC1 */
4042 0x04, 0x05
4043 };
4044
4045 #define ALC260_DIGOUT_NID 0x03
4046 #define ALC260_DIGIN_NID 0x06
4047
4048 static struct hda_input_mux alc260_capture_source = {
4049 .num_items = 4,
4050 .items = {
4051 { "Mic", 0x0 },
4052 { "Front Mic", 0x1 },
4053 { "Line", 0x2 },
4054 { "CD", 0x4 },
4055 },
4056 };
4057
4058 /* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
4059 * headphone jack and the internal CD lines since these are the only pins at
4060 * which audio can appear. For flexibility, also allow the option of
4061 * recording the mixer output on the second ADC (ADC0 doesn't have a
4062 * connection to the mixer output).
4063 */
4064 static struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
4065 {
4066 .num_items = 3,
4067 .items = {
4068 { "Mic/Line", 0x0 },
4069 { "CD", 0x4 },
4070 { "Headphone", 0x2 },
4071 },
4072 },
4073 {
4074 .num_items = 4,
4075 .items = {
4076 { "Mic/Line", 0x0 },
4077 { "CD", 0x4 },
4078 { "Headphone", 0x2 },
4079 { "Mixer", 0x5 },
4080 },
4081 },
4082
4083 };
4084
4085 /* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
4086 * the Fujitsu S702x, but jacks are marked differently.
4087 */
4088 static struct hda_input_mux alc260_acer_capture_sources[2] = {
4089 {
4090 .num_items = 4,
4091 .items = {
4092 { "Mic", 0x0 },
4093 { "Line", 0x2 },
4094 { "CD", 0x4 },
4095 { "Headphone", 0x5 },
4096 },
4097 },
4098 {
4099 .num_items = 5,
4100 .items = {
4101 { "Mic", 0x0 },
4102 { "Line", 0x2 },
4103 { "CD", 0x4 },
4104 { "Headphone", 0x6 },
4105 { "Mixer", 0x5 },
4106 },
4107 },
4108 };
4109 /*
4110 * This is just place-holder, so there's something for alc_build_pcms to look
4111 * at when it calculates the maximum number of channels. ALC260 has no mixer
4112 * element which allows changing the channel mode, so the verb list is
4113 * never used.
4114 */
4115 static struct hda_channel_mode alc260_modes[1] = {
4116 { 2, NULL },
4117 };
4118
4119
4120 /* Mixer combinations
4121 *
4122 * basic: base_output + input + pc_beep + capture
4123 * HP: base_output + input + capture_alt
4124 * HP_3013: hp_3013 + input + capture
4125 * fujitsu: fujitsu + capture
4126 * acer: acer + capture
4127 */
4128
4129 static struct snd_kcontrol_new alc260_base_output_mixer[] = {
4130 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4131 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
4132 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4133 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
4134 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
4135 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
4136 { } /* end */
4137 };
4138
4139 static struct snd_kcontrol_new alc260_input_mixer[] = {
4140 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4141 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4142 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4143 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4144 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4145 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4146 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
4147 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
4148 { } /* end */
4149 };
4150
4151 static struct snd_kcontrol_new alc260_pc_beep_mixer[] = {
4152 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x07, 0x05, HDA_INPUT),
4153 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x07, 0x05, HDA_INPUT),
4154 { } /* end */
4155 };
4156
4157 /* update HP, line and mono out pins according to the master switch */
4158 static void alc260_hp_master_update(struct hda_codec *codec,
4159 hda_nid_t hp, hda_nid_t line,
4160 hda_nid_t mono)
4161 {
4162 struct alc_spec *spec = codec->spec;
4163 unsigned int val = spec->master_sw ? PIN_HP : 0;
4164 /* change HP and line-out pins */
4165 snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4166 val);
4167 snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4168 val);
4169 /* mono (speaker) depending on the HP jack sense */
4170 val = (val && !spec->jack_present) ? PIN_OUT : 0;
4171 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4172 val);
4173 }
4174
4175 static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol,
4176 struct snd_ctl_elem_value *ucontrol)
4177 {
4178 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4179 struct alc_spec *spec = codec->spec;
4180 *ucontrol->value.integer.value = spec->master_sw;
4181 return 0;
4182 }
4183
4184 static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol,
4185 struct snd_ctl_elem_value *ucontrol)
4186 {
4187 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4188 struct alc_spec *spec = codec->spec;
4189 int val = !!*ucontrol->value.integer.value;
4190 hda_nid_t hp, line, mono;
4191
4192 if (val == spec->master_sw)
4193 return 0;
4194 spec->master_sw = val;
4195 hp = (kcontrol->private_value >> 16) & 0xff;
4196 line = (kcontrol->private_value >> 8) & 0xff;
4197 mono = kcontrol->private_value & 0xff;
4198 alc260_hp_master_update(codec, hp, line, mono);
4199 return 1;
4200 }
4201
4202 static struct snd_kcontrol_new alc260_hp_output_mixer[] = {
4203 {
4204 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4205 .name = "Master Playback Switch",
4206 .info = snd_ctl_boolean_mono_info,
4207 .get = alc260_hp_master_sw_get,
4208 .put = alc260_hp_master_sw_put,
4209 .private_value = (0x0f << 16) | (0x10 << 8) | 0x11
4210 },
4211 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4212 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
4213 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4214 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
4215 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
4216 HDA_OUTPUT),
4217 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT),
4218 { } /* end */
4219 };
4220
4221 static struct hda_verb alc260_hp_unsol_verbs[] = {
4222 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4223 {},
4224 };
4225
4226 static void alc260_hp_automute(struct hda_codec *codec)
4227 {
4228 struct alc_spec *spec = codec->spec;
4229 unsigned int present;
4230
4231 present = snd_hda_codec_read(codec, 0x10, 0,
4232 AC_VERB_GET_PIN_SENSE, 0);
4233 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
4234 alc260_hp_master_update(codec, 0x0f, 0x10, 0x11);
4235 }
4236
4237 static void alc260_hp_unsol_event(struct hda_codec *codec, unsigned int res)
4238 {
4239 if ((res >> 26) == ALC880_HP_EVENT)
4240 alc260_hp_automute(codec);
4241 }
4242
4243 static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
4244 {
4245 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4246 .name = "Master Playback Switch",
4247 .info = snd_ctl_boolean_mono_info,
4248 .get = alc260_hp_master_sw_get,
4249 .put = alc260_hp_master_sw_put,
4250 .private_value = (0x10 << 16) | (0x15 << 8) | 0x11
4251 },
4252 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4253 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
4254 HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
4255 HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
4256 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4257 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
4258 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
4259 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
4260 { } /* end */
4261 };
4262
4263 static struct hda_bind_ctls alc260_dc7600_bind_master_vol = {
4264 .ops = &snd_hda_bind_vol,
4265 .values = {
4266 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_OUTPUT),
4267 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT),
4268 HDA_COMPOSE_AMP_VAL(0x0a, 3, 0, HDA_OUTPUT),
4269 0
4270 },
4271 };
4272
4273 static struct hda_bind_ctls alc260_dc7600_bind_switch = {
4274 .ops = &snd_hda_bind_sw,
4275 .values = {
4276 HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT),
4277 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
4278 0
4279 },
4280 };
4281
4282 static struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = {
4283 HDA_BIND_VOL("Master Playback Volume", &alc260_dc7600_bind_master_vol),
4284 HDA_BIND_SW("LineOut Playback Switch", &alc260_dc7600_bind_switch),
4285 HDA_CODEC_MUTE("Speaker Playback Switch", 0x0f, 0x0, HDA_OUTPUT),
4286 HDA_CODEC_MUTE("Headphone Playback Switch", 0x10, 0x0, HDA_OUTPUT),
4287 { } /* end */
4288 };
4289
4290 static struct hda_verb alc260_hp_3013_unsol_verbs[] = {
4291 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4292 {},
4293 };
4294
4295 static void alc260_hp_3013_automute(struct hda_codec *codec)
4296 {
4297 struct alc_spec *spec = codec->spec;
4298 unsigned int present;
4299
4300 present = snd_hda_codec_read(codec, 0x15, 0,
4301 AC_VERB_GET_PIN_SENSE, 0);
4302 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
4303 alc260_hp_master_update(codec, 0x10, 0x15, 0x11);
4304 }
4305
4306 static void alc260_hp_3013_unsol_event(struct hda_codec *codec,
4307 unsigned int res)
4308 {
4309 if ((res >> 26) == ALC880_HP_EVENT)
4310 alc260_hp_3013_automute(codec);
4311 }
4312
4313 static void alc260_hp_3012_automute(struct hda_codec *codec)
4314 {
4315 unsigned int present, bits;
4316
4317 present = snd_hda_codec_read(codec, 0x10, 0,
4318 AC_VERB_GET_PIN_SENSE, 0) & AC_PINSENSE_PRESENCE;
4319
4320 bits = present ? 0 : PIN_OUT;
4321 snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4322 bits);
4323 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4324 bits);
4325 snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4326 bits);
4327 }
4328
4329 static void alc260_hp_3012_unsol_event(struct hda_codec *codec,
4330 unsigned int res)
4331 {
4332 if ((res >> 26) == ALC880_HP_EVENT)
4333 alc260_hp_3012_automute(codec);
4334 }
4335
4336 /* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12,
4337 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10.
4338 */
4339 static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
4340 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4341 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
4342 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4343 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4344 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4345 HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
4346 HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
4347 ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
4348 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4349 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
4350 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4351 HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT),
4352 { } /* end */
4353 };
4354
4355 /* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks. Note that current
4356 * versions of the ALC260 don't act on requests to enable mic bias from NID
4357 * 0x0f (used to drive the headphone jack in these laptops). The ALC260
4358 * datasheet doesn't mention this restriction. At this stage it's not clear
4359 * whether this behaviour is intentional or is a hardware bug in chip
4360 * revisions available in early 2006. Therefore for now allow the
4361 * "Headphone Jack Mode" control to span all choices, but if it turns out
4362 * that the lack of mic bias for this NID is intentional we could change the
4363 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
4364 *
4365 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
4366 * don't appear to make the mic bias available from the "line" jack, even
4367 * though the NID used for this jack (0x14) can supply it. The theory is
4368 * that perhaps Acer have included blocking capacitors between the ALC260
4369 * and the output jack. If this turns out to be the case for all such
4370 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
4371 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
4372 *
4373 * The C20x Tablet series have a mono internal speaker which is controlled
4374 * via the chip's Mono sum widget and pin complex, so include the necessary
4375 * controls for such models. On models without a "mono speaker" the control
4376 * won't do anything.
4377 */
4378 static struct snd_kcontrol_new alc260_acer_mixer[] = {
4379 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4380 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
4381 ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
4382 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
4383 HDA_OUTPUT),
4384 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2,
4385 HDA_INPUT),
4386 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4387 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4388 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4389 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4390 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4391 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4392 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4393 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4394 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4395 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
4396 { } /* end */
4397 };
4398
4399 /* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
4400 * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17.
4401 */
4402 static struct snd_kcontrol_new alc260_will_mixer[] = {
4403 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4404 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
4405 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4406 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4407 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4408 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4409 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4410 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4411 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4412 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4413 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4414 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
4415 { } /* end */
4416 };
4417
4418 /* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
4419 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
4420 */
4421 static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
4422 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4423 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
4424 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
4425 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
4426 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
4427 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
4428 HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
4429 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
4430 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
4431 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
4432 { } /* end */
4433 };
4434
4435 /* capture mixer elements */
4436 static struct snd_kcontrol_new alc260_capture_mixer[] = {
4437 HDA_CODEC_VOLUME("Capture Volume", 0x04, 0x0, HDA_INPUT),
4438 HDA_CODEC_MUTE("Capture Switch", 0x04, 0x0, HDA_INPUT),
4439 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x05, 0x0, HDA_INPUT),
4440 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x05, 0x0, HDA_INPUT),
4441 {
4442 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4443 /* The multiple "Capture Source" controls confuse alsamixer
4444 * So call somewhat different..
4445 */
4446 /* .name = "Capture Source", */
4447 .name = "Input Source",
4448 .count = 2,
4449 .info = alc_mux_enum_info,
4450 .get = alc_mux_enum_get,
4451 .put = alc_mux_enum_put,
4452 },
4453 { } /* end */
4454 };
4455
4456 static struct snd_kcontrol_new alc260_capture_alt_mixer[] = {
4457 HDA_CODEC_VOLUME("Capture Volume", 0x05, 0x0, HDA_INPUT),
4458 HDA_CODEC_MUTE("Capture Switch", 0x05, 0x0, HDA_INPUT),
4459 {
4460 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4461 /* The multiple "Capture Source" controls confuse alsamixer
4462 * So call somewhat different..
4463 */
4464 /* .name = "Capture Source", */
4465 .name = "Input Source",
4466 .count = 1,
4467 .info = alc_mux_enum_info,
4468 .get = alc_mux_enum_get,
4469 .put = alc_mux_enum_put,
4470 },
4471 { } /* end */
4472 };
4473
4474 /*
4475 * initialization verbs
4476 */
4477 static struct hda_verb alc260_init_verbs[] = {
4478 /* Line In pin widget for input */
4479 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4480 /* CD pin widget for input */
4481 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4482 /* Mic1 (rear panel) pin widget for input and vref at 80% */
4483 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4484 /* Mic2 (front panel) pin widget for input and vref at 80% */
4485 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4486 /* LINE-2 is used for line-out in rear */
4487 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4488 /* select line-out */
4489 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
4490 /* LINE-OUT pin */
4491 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4492 /* enable HP */
4493 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4494 /* enable Mono */
4495 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4496 /* mute capture amp left and right */
4497 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4498 /* set connection select to line in (default select for this ADC) */
4499 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
4500 /* mute capture amp left and right */
4501 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4502 /* set connection select to line in (default select for this ADC) */
4503 {0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
4504 /* set vol=0 Line-Out mixer amp left and right */
4505 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4506 /* unmute pin widget amp left and right (no gain on this amp) */
4507 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4508 /* set vol=0 HP mixer amp left and right */
4509 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4510 /* unmute pin widget amp left and right (no gain on this amp) */
4511 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4512 /* set vol=0 Mono mixer amp left and right */
4513 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4514 /* unmute pin widget amp left and right (no gain on this amp) */
4515 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4516 /* unmute LINE-2 out pin */
4517 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4518 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
4519 * Line In 2 = 0x03
4520 */
4521 /* mute analog inputs */
4522 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4523 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4524 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4525 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4526 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4527 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
4528 /* mute Front out path */
4529 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4530 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4531 /* mute Headphone out path */
4532 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4533 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4534 /* mute Mono out path */
4535 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4536 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4537 { }
4538 };
4539
4540 #if 0 /* should be identical with alc260_init_verbs? */
4541 static struct hda_verb alc260_hp_init_verbs[] = {
4542 /* Headphone and output */
4543 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
4544 /* mono output */
4545 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4546 /* Mic1 (rear panel) pin widget for input and vref at 80% */
4547 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4548 /* Mic2 (front panel) pin widget for input and vref at 80% */
4549 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4550 /* Line In pin widget for input */
4551 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4552 /* Line-2 pin widget for output */
4553 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4554 /* CD pin widget for input */
4555 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4556 /* unmute amp left and right */
4557 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
4558 /* set connection select to line in (default select for this ADC) */
4559 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
4560 /* unmute Line-Out mixer amp left and right (volume = 0) */
4561 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4562 /* mute pin widget amp left and right (no gain on this amp) */
4563 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4564 /* unmute HP mixer amp left and right (volume = 0) */
4565 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4566 /* mute pin widget amp left and right (no gain on this amp) */
4567 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4568 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
4569 * Line In 2 = 0x03
4570 */
4571 /* mute analog inputs */
4572 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4573 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4574 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4575 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4576 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4577 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
4578 /* Unmute Front out path */
4579 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4580 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4581 /* Unmute Headphone out path */
4582 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4583 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4584 /* Unmute Mono out path */
4585 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4586 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4587 { }
4588 };
4589 #endif
4590
4591 static struct hda_verb alc260_hp_3013_init_verbs[] = {
4592 /* Line out and output */
4593 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4594 /* mono output */
4595 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4596 /* Mic1 (rear panel) pin widget for input and vref at 80% */
4597 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4598 /* Mic2 (front panel) pin widget for input and vref at 80% */
4599 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
4600 /* Line In pin widget for input */
4601 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4602 /* Headphone pin widget for output */
4603 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
4604 /* CD pin widget for input */
4605 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
4606 /* unmute amp left and right */
4607 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
4608 /* set connection select to line in (default select for this ADC) */
4609 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
4610 /* unmute Line-Out mixer amp left and right (volume = 0) */
4611 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4612 /* mute pin widget amp left and right (no gain on this amp) */
4613 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4614 /* unmute HP mixer amp left and right (volume = 0) */
4615 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
4616 /* mute pin widget amp left and right (no gain on this amp) */
4617 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
4618 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
4619 * Line In 2 = 0x03
4620 */
4621 /* mute analog inputs */
4622 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4623 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4624 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4625 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4626 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4627 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
4628 /* Unmute Front out path */
4629 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4630 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4631 /* Unmute Headphone out path */
4632 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4633 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4634 /* Unmute Mono out path */
4635 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4636 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4637 { }
4638 };
4639
4640 /* Initialisation sequence for ALC260 as configured in Fujitsu S702x
4641 * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
4642 * audio = 0x16, internal speaker = 0x10.
4643 */
4644 static struct hda_verb alc260_fujitsu_init_verbs[] = {
4645 /* Disable all GPIOs */
4646 {0x01, AC_VERB_SET_GPIO_MASK, 0},
4647 /* Internal speaker is connected to headphone pin */
4648 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4649 /* Headphone/Line-out jack connects to Line1 pin; make it an output */
4650 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4651 /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
4652 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4653 /* Ensure all other unused pins are disabled and muted. */
4654 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4655 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4656 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4657 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4658 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4659 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4660 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4661 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4662
4663 /* Disable digital (SPDIF) pins */
4664 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
4665 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
4666
4667 /* Ensure Line1 pin widget takes its input from the OUT1 sum bus
4668 * when acting as an output.
4669 */
4670 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4671
4672 /* Start with output sum widgets muted and their output gains at min */
4673 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4674 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4675 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4676 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4677 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4678 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4679 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4680 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4681 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4682
4683 /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
4684 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4685 /* Unmute Line1 pin widget output buffer since it starts as an output.
4686 * If the pin mode is changed by the user the pin mode control will
4687 * take care of enabling the pin's input/output buffers as needed.
4688 * Therefore there's no need to enable the input buffer at this
4689 * stage.
4690 */
4691 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4692 /* Unmute input buffer of pin widget used for Line-in (no equiv
4693 * mixer ctrl)
4694 */
4695 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4696
4697 /* Mute capture amp left and right */
4698 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4699 /* Set ADC connection select to match default mixer setting - line
4700 * in (on mic1 pin)
4701 */
4702 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4703
4704 /* Do the same for the second ADC: mute capture input amp and
4705 * set ADC connection to line in (on mic1 pin)
4706 */
4707 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4708 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4709
4710 /* Mute all inputs to mixer widget (even unconnected ones) */
4711 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
4712 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
4713 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
4714 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
4715 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
4716 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4717 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4718 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4719
4720 { }
4721 };
4722
4723 /* Initialisation sequence for ALC260 as configured in Acer TravelMate and
4724 * similar laptops (adapted from Fujitsu init verbs).
4725 */
4726 static struct hda_verb alc260_acer_init_verbs[] = {
4727 /* On TravelMate laptops, GPIO 0 enables the internal speaker and
4728 * the headphone jack. Turn this on and rely on the standard mute
4729 * methods whenever the user wants to turn these outputs off.
4730 */
4731 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
4732 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
4733 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
4734 /* Internal speaker/Headphone jack is connected to Line-out pin */
4735 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4736 /* Internal microphone/Mic jack is connected to Mic1 pin */
4737 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
4738 /* Line In jack is connected to Line1 pin */
4739 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4740 /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
4741 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4742 /* Ensure all other unused pins are disabled and muted. */
4743 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4744 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4745 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4746 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4747 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4748 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4749 /* Disable digital (SPDIF) pins */
4750 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
4751 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
4752
4753 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
4754 * bus when acting as outputs.
4755 */
4756 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
4757 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4758
4759 /* Start with output sum widgets muted and their output gains at min */
4760 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4761 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4762 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4763 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4764 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4765 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4766 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4767 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4768 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4769
4770 /* Unmute Line-out pin widget amp left and right
4771 * (no equiv mixer ctrl)
4772 */
4773 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4774 /* Unmute mono pin widget amp output (no equiv mixer ctrl) */
4775 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4776 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
4777 * inputs. If the pin mode is changed by the user the pin mode control
4778 * will take care of enabling the pin's input/output buffers as needed.
4779 * Therefore there's no need to enable the input buffer at this
4780 * stage.
4781 */
4782 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4783 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4784
4785 /* Mute capture amp left and right */
4786 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4787 /* Set ADC connection select to match default mixer setting - mic
4788 * (on mic1 pin)
4789 */
4790 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4791
4792 /* Do similar with the second ADC: mute capture input amp and
4793 * set ADC connection to mic to match ALSA's default state.
4794 */
4795 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4796 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4797
4798 /* Mute all inputs to mixer widget (even unconnected ones) */
4799 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
4800 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
4801 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
4802 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
4803 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
4804 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4805 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4806 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4807
4808 { }
4809 };
4810
4811 static struct hda_verb alc260_will_verbs[] = {
4812 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4813 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
4814 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
4815 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
4816 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
4817 {0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
4818 {}
4819 };
4820
4821 static struct hda_verb alc260_replacer_672v_verbs[] = {
4822 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
4823 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
4824 {0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
4825
4826 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
4827 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
4828 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
4829
4830 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4831 {}
4832 };
4833
4834 /* toggle speaker-output according to the hp-jack state */
4835 static void alc260_replacer_672v_automute(struct hda_codec *codec)
4836 {
4837 unsigned int present;
4838
4839 /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
4840 present = snd_hda_codec_read(codec, 0x0f, 0,
4841 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
4842 if (present) {
4843 snd_hda_codec_write_cache(codec, 0x01, 0,
4844 AC_VERB_SET_GPIO_DATA, 1);
4845 snd_hda_codec_write_cache(codec, 0x0f, 0,
4846 AC_VERB_SET_PIN_WIDGET_CONTROL,
4847 PIN_HP);
4848 } else {
4849 snd_hda_codec_write_cache(codec, 0x01, 0,
4850 AC_VERB_SET_GPIO_DATA, 0);
4851 snd_hda_codec_write_cache(codec, 0x0f, 0,
4852 AC_VERB_SET_PIN_WIDGET_CONTROL,
4853 PIN_OUT);
4854 }
4855 }
4856
4857 static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
4858 unsigned int res)
4859 {
4860 if ((res >> 26) == ALC880_HP_EVENT)
4861 alc260_replacer_672v_automute(codec);
4862 }
4863
4864 static struct hda_verb alc260_hp_dc7600_verbs[] = {
4865 {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
4866 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
4867 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4868 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4869 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4870 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4871 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4872 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4873 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4874 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4875 {}
4876 };
4877
4878 /* Test configuration for debugging, modelled after the ALC880 test
4879 * configuration.
4880 */
4881 #ifdef CONFIG_SND_DEBUG
4882 static hda_nid_t alc260_test_dac_nids[1] = {
4883 0x02,
4884 };
4885 static hda_nid_t alc260_test_adc_nids[2] = {
4886 0x04, 0x05,
4887 };
4888 /* For testing the ALC260, each input MUX needs its own definition since
4889 * the signal assignments are different. This assumes that the first ADC
4890 * is NID 0x04.
4891 */
4892 static struct hda_input_mux alc260_test_capture_sources[2] = {
4893 {
4894 .num_items = 7,
4895 .items = {
4896 { "MIC1 pin", 0x0 },
4897 { "MIC2 pin", 0x1 },
4898 { "LINE1 pin", 0x2 },
4899 { "LINE2 pin", 0x3 },
4900 { "CD pin", 0x4 },
4901 { "LINE-OUT pin", 0x5 },
4902 { "HP-OUT pin", 0x6 },
4903 },
4904 },
4905 {
4906 .num_items = 8,
4907 .items = {
4908 { "MIC1 pin", 0x0 },
4909 { "MIC2 pin", 0x1 },
4910 { "LINE1 pin", 0x2 },
4911 { "LINE2 pin", 0x3 },
4912 { "CD pin", 0x4 },
4913 { "Mixer", 0x5 },
4914 { "LINE-OUT pin", 0x6 },
4915 { "HP-OUT pin", 0x7 },
4916 },
4917 },
4918 };
4919 static struct snd_kcontrol_new alc260_test_mixer[] = {
4920 /* Output driver widgets */
4921 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
4922 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
4923 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4924 HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
4925 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4926 HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
4927
4928 /* Modes for retasking pin widgets
4929 * Note: the ALC260 doesn't seem to act on requests to enable mic
4930 * bias from NIDs 0x0f and 0x10. The ALC260 datasheet doesn't
4931 * mention this restriction. At this stage it's not clear whether
4932 * this behaviour is intentional or is a hardware bug in chip
4933 * revisions available at least up until early 2006. Therefore for
4934 * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
4935 * choices, but if it turns out that the lack of mic bias for these
4936 * NIDs is intentional we could change their modes from
4937 * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
4938 */
4939 ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
4940 ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
4941 ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
4942 ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
4943 ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
4944 ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
4945
4946 /* Loopback mixer controls */
4947 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
4948 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
4949 HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
4950 HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
4951 HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
4952 HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
4953 HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
4954 HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
4955 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4956 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4957 HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4958 HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
4959 HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
4960 HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
4961 HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
4962 HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
4963
4964 /* Controls for GPIO pins, assuming they are configured as outputs */
4965 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
4966 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
4967 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
4968 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
4969
4970 /* Switches to allow the digital IO pins to be enabled. The datasheet
4971 * is ambigious as to which NID is which; testing on laptops which
4972 * make this output available should provide clarification.
4973 */
4974 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
4975 ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
4976
4977 /* A switch allowing EAPD to be enabled. Some laptops seem to use
4978 * this output to turn on an external amplifier.
4979 */
4980 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
4981 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
4982
4983 { } /* end */
4984 };
4985 static struct hda_verb alc260_test_init_verbs[] = {
4986 /* Enable all GPIOs as outputs with an initial value of 0 */
4987 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
4988 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
4989 {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
4990
4991 /* Enable retasking pins as output, initially without power amp */
4992 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4993 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4994 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4995 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4996 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4997 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4998
4999 /* Disable digital (SPDIF) pins initially, but users can enable
5000 * them via a mixer switch. In the case of SPDIF-out, this initverb
5001 * payload also sets the generation to 0, output to be in "consumer"
5002 * PCM format, copyright asserted, no pre-emphasis and no validity
5003 * control.
5004 */
5005 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
5006 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
5007
5008 /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
5009 * OUT1 sum bus when acting as an output.
5010 */
5011 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
5012 {0x0c, AC_VERB_SET_CONNECT_SEL, 0},
5013 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
5014 {0x0e, AC_VERB_SET_CONNECT_SEL, 0},
5015
5016 /* Start with output sum widgets muted and their output gains at min */
5017 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5018 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5019 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5020 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5021 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5022 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5023 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5024 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5025 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5026
5027 /* Unmute retasking pin widget output buffers since the default
5028 * state appears to be output. As the pin mode is changed by the
5029 * user the pin mode control will take care of enabling the pin's
5030 * input/output buffers as needed.
5031 */
5032 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5033 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5034 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5035 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5036 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5037 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5038 /* Also unmute the mono-out pin widget */
5039 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5040
5041 /* Mute capture amp left and right */
5042 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5043 /* Set ADC connection select to match default mixer setting (mic1
5044 * pin)
5045 */
5046 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5047
5048 /* Do the same for the second ADC: mute capture input amp and
5049 * set ADC connection to mic1 pin
5050 */
5051 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5052 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5053
5054 /* Mute all inputs to mixer widget (even unconnected ones) */
5055 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
5056 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
5057 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
5058 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
5059 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
5060 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
5061 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
5062 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
5063
5064 { }
5065 };
5066 #endif
5067
5068 #define alc260_pcm_analog_playback alc880_pcm_analog_alt_playback
5069 #define alc260_pcm_analog_capture alc880_pcm_analog_capture
5070
5071 #define alc260_pcm_digital_playback alc880_pcm_digital_playback
5072 #define alc260_pcm_digital_capture alc880_pcm_digital_capture
5073
5074 /*
5075 * for BIOS auto-configuration
5076 */
5077
5078 static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
5079 const char *pfx, int *vol_bits)
5080 {
5081 hda_nid_t nid_vol;
5082 unsigned long vol_val, sw_val;
5083 char name[32];
5084 int err;
5085
5086 if (nid >= 0x0f && nid < 0x11) {
5087 nid_vol = nid - 0x7;
5088 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
5089 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
5090 } else if (nid == 0x11) {
5091 nid_vol = nid - 0x7;
5092 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
5093 sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
5094 } else if (nid >= 0x12 && nid <= 0x15) {
5095 nid_vol = 0x08;
5096 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
5097 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
5098 } else
5099 return 0; /* N/A */
5100
5101 if (!(*vol_bits & (1 << nid_vol))) {
5102 /* first control for the volume widget */
5103 snprintf(name, sizeof(name), "%s Playback Volume", pfx);
5104 err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val);
5105 if (err < 0)
5106 return err;
5107 *vol_bits |= (1 << nid_vol);
5108 }
5109 snprintf(name, sizeof(name), "%s Playback Switch", pfx);
5110 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, sw_val);
5111 if (err < 0)
5112 return err;
5113 return 1;
5114 }
5115
5116 /* add playback controls from the parsed DAC table */
5117 static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
5118 const struct auto_pin_cfg *cfg)
5119 {
5120 hda_nid_t nid;
5121 int err;
5122 int vols = 0;
5123
5124 spec->multiout.num_dacs = 1;
5125 spec->multiout.dac_nids = spec->private_dac_nids;
5126 spec->multiout.dac_nids[0] = 0x02;
5127
5128 nid = cfg->line_out_pins[0];
5129 if (nid) {
5130 err = alc260_add_playback_controls(spec, nid, "Front", &vols);
5131 if (err < 0)
5132 return err;
5133 }
5134
5135 nid = cfg->speaker_pins[0];
5136 if (nid) {
5137 err = alc260_add_playback_controls(spec, nid, "Speaker", &vols);
5138 if (err < 0)
5139 return err;
5140 }
5141
5142 nid = cfg->hp_pins[0];
5143 if (nid) {
5144 err = alc260_add_playback_controls(spec, nid, "Headphone",
5145 &vols);
5146 if (err < 0)
5147 return err;
5148 }
5149 return 0;
5150 }
5151
5152 /* create playback/capture controls for input pins */
5153 static int alc260_auto_create_analog_input_ctls(struct alc_spec *spec,
5154 const struct auto_pin_cfg *cfg)
5155 {
5156 struct hda_input_mux *imux = &spec->private_imux;
5157 int i, err, idx;
5158
5159 for (i = 0; i < AUTO_PIN_LAST; i++) {
5160 if (cfg->input_pins[i] >= 0x12) {
5161 idx = cfg->input_pins[i] - 0x12;
5162 err = new_analog_input(spec, cfg->input_pins[i],
5163 auto_pin_cfg_labels[i], idx,
5164 0x07);
5165 if (err < 0)
5166 return err;
5167 imux->items[imux->num_items].label =
5168 auto_pin_cfg_labels[i];
5169 imux->items[imux->num_items].index = idx;
5170 imux->num_items++;
5171 }
5172 if (cfg->input_pins[i] >= 0x0f && cfg->input_pins[i] <= 0x10){
5173 idx = cfg->input_pins[i] - 0x09;
5174 err = new_analog_input(spec, cfg->input_pins[i],
5175 auto_pin_cfg_labels[i], idx,
5176 0x07);
5177 if (err < 0)
5178 return err;
5179 imux->items[imux->num_items].label =
5180 auto_pin_cfg_labels[i];
5181 imux->items[imux->num_items].index = idx;
5182 imux->num_items++;
5183 }
5184 }
5185 return 0;
5186 }
5187
5188 static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
5189 hda_nid_t nid, int pin_type,
5190 int sel_idx)
5191 {
5192 alc_set_pin_output(codec, nid, pin_type);
5193 /* need the manual connection? */
5194 if (nid >= 0x12) {
5195 int idx = nid - 0x12;
5196 snd_hda_codec_write(codec, idx + 0x0b, 0,
5197 AC_VERB_SET_CONNECT_SEL, sel_idx);
5198 }
5199 }
5200
5201 static void alc260_auto_init_multi_out(struct hda_codec *codec)
5202 {
5203 struct alc_spec *spec = codec->spec;
5204 hda_nid_t nid;
5205
5206 alc_subsystem_id(codec, 0x10, 0x15, 0x0f);
5207 nid = spec->autocfg.line_out_pins[0];
5208 if (nid) {
5209 int pin_type = get_pin_type(spec->autocfg.line_out_type);
5210 alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
5211 }
5212
5213 nid = spec->autocfg.speaker_pins[0];
5214 if (nid)
5215 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
5216
5217 nid = spec->autocfg.hp_pins[0];
5218 if (nid)
5219 alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
5220 }
5221
5222 #define ALC260_PIN_CD_NID 0x16
5223 static void alc260_auto_init_analog_input(struct hda_codec *codec)
5224 {
5225 struct alc_spec *spec = codec->spec;
5226 int i;
5227
5228 for (i = 0; i < AUTO_PIN_LAST; i++) {
5229 hda_nid_t nid = spec->autocfg.input_pins[i];
5230 if (nid >= 0x12) {
5231 snd_hda_codec_write(codec, nid, 0,
5232 AC_VERB_SET_PIN_WIDGET_CONTROL,
5233 i <= AUTO_PIN_FRONT_MIC ?
5234 PIN_VREF80 : PIN_IN);
5235 if (nid != ALC260_PIN_CD_NID)
5236 snd_hda_codec_write(codec, nid, 0,
5237 AC_VERB_SET_AMP_GAIN_MUTE,
5238 AMP_OUT_MUTE);
5239 }
5240 }
5241 }
5242
5243 /*
5244 * generic initialization of ADC, input mixers and output mixers
5245 */
5246 static struct hda_verb alc260_volume_init_verbs[] = {
5247 /*
5248 * Unmute ADC0-1 and set the default input to mic-in
5249 */
5250 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
5251 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5252 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
5253 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5254
5255 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
5256 * mixer widget
5257 * Note: PASD motherboards uses the Line In 2 as the input for
5258 * front panel mic (mic 2)
5259 */
5260 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
5261 /* mute analog inputs */
5262 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5263 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5264 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5265 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5266 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5267
5268 /*
5269 * Set up output mixers (0x08 - 0x0a)
5270 */
5271 /* set vol=0 to output mixers */
5272 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5273 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5274 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5275 /* set up input amps for analog loopback */
5276 /* Amp Indices: DAC = 0, mixer = 1 */
5277 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5278 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5279 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5280 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5281 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5282 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5283
5284 { }
5285 };
5286
5287 static int alc260_parse_auto_config(struct hda_codec *codec)
5288 {
5289 struct alc_spec *spec = codec->spec;
5290 unsigned int wcap;
5291 int err;
5292 static hda_nid_t alc260_ignore[] = { 0x17, 0 };
5293
5294 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
5295 alc260_ignore);
5296 if (err < 0)
5297 return err;
5298 err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
5299 if (err < 0)
5300 return err;
5301 if (!spec->kctls.list)
5302 return 0; /* can't find valid BIOS pin config */
5303 err = alc260_auto_create_analog_input_ctls(spec, &spec->autocfg);
5304 if (err < 0)
5305 return err;
5306
5307 spec->multiout.max_channels = 2;
5308
5309 if (spec->autocfg.dig_out_pin)
5310 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
5311 if (spec->kctls.list)
5312 add_mixer(spec, spec->kctls.list);
5313
5314 add_verb(spec, alc260_volume_init_verbs);
5315
5316 spec->num_mux_defs = 1;
5317 spec->input_mux = &spec->private_imux;
5318
5319 /* check whether NID 0x04 is valid */
5320 wcap = get_wcaps(codec, 0x04);
5321 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; /* get type */
5322 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
5323 spec->adc_nids = alc260_adc_nids_alt;
5324 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
5325 add_mixer(spec, alc260_capture_alt_mixer);
5326 } else {
5327 spec->adc_nids = alc260_adc_nids;
5328 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
5329 add_mixer(spec, alc260_capture_mixer);
5330 }
5331
5332 store_pin_configs(codec);
5333 return 1;
5334 }
5335
5336 /* additional initialization for auto-configuration model */
5337 static void alc260_auto_init(struct hda_codec *codec)
5338 {
5339 struct alc_spec *spec = codec->spec;
5340 alc260_auto_init_multi_out(codec);
5341 alc260_auto_init_analog_input(codec);
5342 if (spec->unsol_event)
5343 alc_inithook(codec);
5344 }
5345
5346 #ifdef CONFIG_SND_HDA_POWER_SAVE
5347 static struct hda_amp_list alc260_loopbacks[] = {
5348 { 0x07, HDA_INPUT, 0 },
5349 { 0x07, HDA_INPUT, 1 },
5350 { 0x07, HDA_INPUT, 2 },
5351 { 0x07, HDA_INPUT, 3 },
5352 { 0x07, HDA_INPUT, 4 },
5353 { } /* end */
5354 };
5355 #endif
5356
5357 /*
5358 * ALC260 configurations
5359 */
5360 static const char *alc260_models[ALC260_MODEL_LAST] = {
5361 [ALC260_BASIC] = "basic",
5362 [ALC260_HP] = "hp",
5363 [ALC260_HP_3013] = "hp-3013",
5364 [ALC260_HP_DC7600] = "hp-dc7600",
5365 [ALC260_FUJITSU_S702X] = "fujitsu",
5366 [ALC260_ACER] = "acer",
5367 [ALC260_WILL] = "will",
5368 [ALC260_REPLACER_672V] = "replacer",
5369 #ifdef CONFIG_SND_DEBUG
5370 [ALC260_TEST] = "test",
5371 #endif
5372 [ALC260_AUTO] = "auto",
5373 };
5374
5375 static struct snd_pci_quirk alc260_cfg_tbl[] = {
5376 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
5377 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
5378 SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
5379 SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_HP_3013),
5380 SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
5381 SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013),
5382 SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_DC7600),
5383 SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
5384 SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
5385 SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
5386 SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
5387 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
5388 SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
5389 SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
5390 SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
5391 SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
5392 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
5393 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
5394 {}
5395 };
5396
5397 static struct alc_config_preset alc260_presets[] = {
5398 [ALC260_BASIC] = {
5399 .mixers = { alc260_base_output_mixer,
5400 alc260_input_mixer,
5401 alc260_pc_beep_mixer,
5402 alc260_capture_mixer },
5403 .init_verbs = { alc260_init_verbs },
5404 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5405 .dac_nids = alc260_dac_nids,
5406 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
5407 .adc_nids = alc260_adc_nids,
5408 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5409 .channel_mode = alc260_modes,
5410 .input_mux = &alc260_capture_source,
5411 },
5412 [ALC260_HP] = {
5413 .mixers = { alc260_hp_output_mixer,
5414 alc260_input_mixer,
5415 alc260_capture_alt_mixer },
5416 .init_verbs = { alc260_init_verbs,
5417 alc260_hp_unsol_verbs },
5418 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5419 .dac_nids = alc260_dac_nids,
5420 .num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
5421 .adc_nids = alc260_hp_adc_nids,
5422 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5423 .channel_mode = alc260_modes,
5424 .input_mux = &alc260_capture_source,
5425 .unsol_event = alc260_hp_unsol_event,
5426 .init_hook = alc260_hp_automute,
5427 },
5428 [ALC260_HP_DC7600] = {
5429 .mixers = { alc260_hp_dc7600_mixer,
5430 alc260_input_mixer,
5431 alc260_capture_alt_mixer },
5432 .init_verbs = { alc260_init_verbs,
5433 alc260_hp_dc7600_verbs },
5434 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5435 .dac_nids = alc260_dac_nids,
5436 .num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
5437 .adc_nids = alc260_hp_adc_nids,
5438 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5439 .channel_mode = alc260_modes,
5440 .input_mux = &alc260_capture_source,
5441 .unsol_event = alc260_hp_3012_unsol_event,
5442 .init_hook = alc260_hp_3012_automute,
5443 },
5444 [ALC260_HP_3013] = {
5445 .mixers = { alc260_hp_3013_mixer,
5446 alc260_input_mixer,
5447 alc260_capture_alt_mixer },
5448 .init_verbs = { alc260_hp_3013_init_verbs,
5449 alc260_hp_3013_unsol_verbs },
5450 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5451 .dac_nids = alc260_dac_nids,
5452 .num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
5453 .adc_nids = alc260_hp_adc_nids,
5454 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5455 .channel_mode = alc260_modes,
5456 .input_mux = &alc260_capture_source,
5457 .unsol_event = alc260_hp_3013_unsol_event,
5458 .init_hook = alc260_hp_3013_automute,
5459 },
5460 [ALC260_FUJITSU_S702X] = {
5461 .mixers = { alc260_fujitsu_mixer,
5462 alc260_capture_mixer },
5463 .init_verbs = { alc260_fujitsu_init_verbs },
5464 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5465 .dac_nids = alc260_dac_nids,
5466 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
5467 .adc_nids = alc260_dual_adc_nids,
5468 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5469 .channel_mode = alc260_modes,
5470 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
5471 .input_mux = alc260_fujitsu_capture_sources,
5472 },
5473 [ALC260_ACER] = {
5474 .mixers = { alc260_acer_mixer,
5475 alc260_capture_mixer },
5476 .init_verbs = { alc260_acer_init_verbs },
5477 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5478 .dac_nids = alc260_dac_nids,
5479 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
5480 .adc_nids = alc260_dual_adc_nids,
5481 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5482 .channel_mode = alc260_modes,
5483 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
5484 .input_mux = alc260_acer_capture_sources,
5485 },
5486 [ALC260_WILL] = {
5487 .mixers = { alc260_will_mixer,
5488 alc260_capture_mixer },
5489 .init_verbs = { alc260_init_verbs, alc260_will_verbs },
5490 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5491 .dac_nids = alc260_dac_nids,
5492 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
5493 .adc_nids = alc260_adc_nids,
5494 .dig_out_nid = ALC260_DIGOUT_NID,
5495 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5496 .channel_mode = alc260_modes,
5497 .input_mux = &alc260_capture_source,
5498 },
5499 [ALC260_REPLACER_672V] = {
5500 .mixers = { alc260_replacer_672v_mixer,
5501 alc260_capture_mixer },
5502 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
5503 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5504 .dac_nids = alc260_dac_nids,
5505 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
5506 .adc_nids = alc260_adc_nids,
5507 .dig_out_nid = ALC260_DIGOUT_NID,
5508 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5509 .channel_mode = alc260_modes,
5510 .input_mux = &alc260_capture_source,
5511 .unsol_event = alc260_replacer_672v_unsol_event,
5512 .init_hook = alc260_replacer_672v_automute,
5513 },
5514 #ifdef CONFIG_SND_DEBUG
5515 [ALC260_TEST] = {
5516 .mixers = { alc260_test_mixer,
5517 alc260_capture_mixer },
5518 .init_verbs = { alc260_test_init_verbs },
5519 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
5520 .dac_nids = alc260_test_dac_nids,
5521 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
5522 .adc_nids = alc260_test_adc_nids,
5523 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5524 .channel_mode = alc260_modes,
5525 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
5526 .input_mux = alc260_test_capture_sources,
5527 },
5528 #endif
5529 };
5530
5531 static int patch_alc260(struct hda_codec *codec)
5532 {
5533 struct alc_spec *spec;
5534 int err, board_config;
5535
5536 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
5537 if (spec == NULL)
5538 return -ENOMEM;
5539
5540 codec->spec = spec;
5541
5542 board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
5543 alc260_models,
5544 alc260_cfg_tbl);
5545 if (board_config < 0) {
5546 snd_printd(KERN_INFO "hda_codec: Unknown model for ALC260, "
5547 "trying auto-probe from BIOS...\n");
5548 board_config = ALC260_AUTO;
5549 }
5550
5551 if (board_config == ALC260_AUTO) {
5552 /* automatic parse from the BIOS config */
5553 err = alc260_parse_auto_config(codec);
5554 if (err < 0) {
5555 alc_free(codec);
5556 return err;
5557 } else if (!err) {
5558 printk(KERN_INFO
5559 "hda_codec: Cannot set up configuration "
5560 "from BIOS. Using base mode...\n");
5561 board_config = ALC260_BASIC;
5562 }
5563 }
5564
5565 if (board_config != ALC260_AUTO)
5566 setup_preset(spec, &alc260_presets[board_config]);
5567
5568 spec->stream_name_analog = "ALC260 Analog";
5569 spec->stream_analog_playback = &alc260_pcm_analog_playback;
5570 spec->stream_analog_capture = &alc260_pcm_analog_capture;
5571
5572 spec->stream_name_digital = "ALC260 Digital";
5573 spec->stream_digital_playback = &alc260_pcm_digital_playback;
5574 spec->stream_digital_capture = &alc260_pcm_digital_capture;
5575
5576 spec->vmaster_nid = 0x08;
5577
5578 codec->patch_ops = alc_patch_ops;
5579 if (board_config == ALC260_AUTO)
5580 spec->init_hook = alc260_auto_init;
5581 #ifdef CONFIG_SND_HDA_POWER_SAVE
5582 if (!spec->loopback.amplist)
5583 spec->loopback.amplist = alc260_loopbacks;
5584 #endif
5585
5586 return 0;
5587 }
5588
5589
5590 /*
5591 * ALC882 support
5592 *
5593 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
5594 * configuration. Each pin widget can choose any input DACs and a mixer.
5595 * Each ADC is connected from a mixer of all inputs. This makes possible
5596 * 6-channel independent captures.
5597 *
5598 * In addition, an independent DAC for the multi-playback (not used in this
5599 * driver yet).
5600 */
5601 #define ALC882_DIGOUT_NID 0x06
5602 #define ALC882_DIGIN_NID 0x0a
5603
5604 static struct hda_channel_mode alc882_ch_modes[1] = {
5605 { 8, NULL }
5606 };
5607
5608 static hda_nid_t alc882_dac_nids[4] = {
5609 /* front, rear, clfe, rear_surr */
5610 0x02, 0x03, 0x04, 0x05
5611 };
5612
5613 /* identical with ALC880 */
5614 #define alc882_adc_nids alc880_adc_nids
5615 #define alc882_adc_nids_alt alc880_adc_nids_alt
5616
5617 static hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 };
5618 static hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 };
5619
5620 /* input MUX */
5621 /* FIXME: should be a matrix-type input source selection */
5622
5623 static struct hda_input_mux alc882_capture_source = {
5624 .num_items = 4,
5625 .items = {
5626 { "Mic", 0x0 },
5627 { "Front Mic", 0x1 },
5628 { "Line", 0x2 },
5629 { "CD", 0x4 },
5630 },
5631 };
5632 #define alc882_mux_enum_info alc_mux_enum_info
5633 #define alc882_mux_enum_get alc_mux_enum_get
5634
5635 static int alc882_mux_enum_put(struct snd_kcontrol *kcontrol,
5636 struct snd_ctl_elem_value *ucontrol)
5637 {
5638 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5639 struct alc_spec *spec = codec->spec;
5640 const struct hda_input_mux *imux = spec->input_mux;
5641 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
5642 hda_nid_t nid = spec->capsrc_nids ?
5643 spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx];
5644 unsigned int *cur_val = &spec->cur_mux[adc_idx];
5645 unsigned int i, idx;
5646
5647 idx = ucontrol->value.enumerated.item[0];
5648 if (idx >= imux->num_items)
5649 idx = imux->num_items - 1;
5650 if (*cur_val == idx)
5651 return 0;
5652 for (i = 0; i < imux->num_items; i++) {
5653 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
5654 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
5655 imux->items[i].index,
5656 HDA_AMP_MUTE, v);
5657 }
5658 *cur_val = idx;
5659 return 1;
5660 }
5661
5662 /*
5663 * 2ch mode
5664 */
5665 static struct hda_verb alc882_3ST_ch2_init[] = {
5666 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
5667 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
5668 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
5669 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
5670 { } /* end */
5671 };
5672
5673 /*
5674 * 6ch mode
5675 */
5676 static struct hda_verb alc882_3ST_ch6_init[] = {
5677 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5678 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
5679 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
5680 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5681 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
5682 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
5683 { } /* end */
5684 };
5685
5686 static struct hda_channel_mode alc882_3ST_6ch_modes[2] = {
5687 { 2, alc882_3ST_ch2_init },
5688 { 6, alc882_3ST_ch6_init },
5689 };
5690
5691 /*
5692 * 6ch mode
5693 */
5694 static struct hda_verb alc882_sixstack_ch6_init[] = {
5695 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
5696 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5697 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5698 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5699 { } /* end */
5700 };
5701
5702 /*
5703 * 8ch mode
5704 */
5705 static struct hda_verb alc882_sixstack_ch8_init[] = {
5706 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5707 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5708 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5709 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5710 { } /* end */
5711 };
5712
5713 static struct hda_channel_mode alc882_sixstack_modes[2] = {
5714 { 6, alc882_sixstack_ch6_init },
5715 { 8, alc882_sixstack_ch8_init },
5716 };
5717
5718 /*
5719 * macbook pro ALC885 can switch LineIn to LineOut without loosing Mic
5720 */
5721
5722 /*
5723 * 2ch mode
5724 */
5725 static struct hda_verb alc885_mbp_ch2_init[] = {
5726 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
5727 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5728 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5729 { } /* end */
5730 };
5731
5732 /*
5733 * 6ch mode
5734 */
5735 static struct hda_verb alc885_mbp_ch6_init[] = {
5736 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5737 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5738 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
5739 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5740 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5741 { } /* end */
5742 };
5743
5744 static struct hda_channel_mode alc885_mbp_6ch_modes[2] = {
5745 { 2, alc885_mbp_ch2_init },
5746 { 6, alc885_mbp_ch6_init },
5747 };
5748
5749
5750 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
5751 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
5752 */
5753 static struct snd_kcontrol_new alc882_base_mixer[] = {
5754 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5755 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5756 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
5757 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
5758 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
5759 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
5760 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
5761 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
5762 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
5763 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
5764 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5765 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5766 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5767 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5768 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5769 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5770 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5771 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5772 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5773 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
5774 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5775 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5776 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5777 { } /* end */
5778 };
5779
5780 static struct snd_kcontrol_new alc885_mbp3_mixer[] = {
5781 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
5782 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
5783 HDA_CODEC_MUTE ("Speaker Playback Switch", 0x14, 0x00, HDA_OUTPUT),
5784 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
5785 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5786 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5787 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
5788 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
5789 HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT),
5790 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
5791 { } /* end */
5792 };
5793 static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
5794 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5795 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5796 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5797 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5798 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5799 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5800 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5801 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5802 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5803 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5804 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5805 { } /* end */
5806 };
5807
5808 static struct snd_kcontrol_new alc882_targa_mixer[] = {
5809 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5810 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5811 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5812 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5813 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5814 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5815 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5816 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5817 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5818 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5819 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5820 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5821 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
5822 { } /* end */
5823 };
5824
5825 /* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
5826 * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
5827 */
5828 static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
5829 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5830 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
5831 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5832 HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
5833 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5834 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5835 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5836 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5837 HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
5838 HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
5839 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5840 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5841 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5842 { } /* end */
5843 };
5844
5845 static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
5846 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5847 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5848 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5849 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5850 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5851 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5852 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5853 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5854 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5855 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5856 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5857 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5858 { } /* end */
5859 };
5860
5861 static struct snd_kcontrol_new alc882_chmode_mixer[] = {
5862 {
5863 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5864 .name = "Channel Mode",
5865 .info = alc_ch_mode_info,
5866 .get = alc_ch_mode_get,
5867 .put = alc_ch_mode_put,
5868 },
5869 { } /* end */
5870 };
5871
5872 static struct hda_verb alc882_init_verbs[] = {
5873 /* Front mixer: unmute input/output amp left and right (volume = 0) */
5874 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5875 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5876 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5877 /* Rear mixer */
5878 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5879 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5880 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5881 /* CLFE mixer */
5882 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5883 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5884 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5885 /* Side mixer */
5886 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5887 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5888 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5889
5890 /* Front Pin: output 0 (0x0c) */
5891 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5892 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5893 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
5894 /* Rear Pin: output 1 (0x0d) */
5895 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5896 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5897 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
5898 /* CLFE Pin: output 2 (0x0e) */
5899 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5900 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5901 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
5902 /* Side Pin: output 3 (0x0f) */
5903 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5904 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5905 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
5906 /* Mic (rear) pin: input vref at 80% */
5907 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5908 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5909 /* Front Mic pin: input vref at 80% */
5910 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5911 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5912 /* Line In pin: input */
5913 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5914 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5915 /* Line-2 In: Headphone output (output 0 - 0x0c) */
5916 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5917 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5918 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
5919 /* CD pin widget for input */
5920 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5921
5922 /* FIXME: use matrix-type input source selection */
5923 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5924 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5925 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5926 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5927 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5928 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5929 /* Input mixer2 */
5930 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5931 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5932 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5933 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5934 /* Input mixer3 */
5935 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5936 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5937 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5938 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5939 /* ADC1: mute amp left and right */
5940 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5941 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5942 /* ADC2: mute amp left and right */
5943 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5944 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5945 /* ADC3: mute amp left and right */
5946 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5947 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5948
5949 { }
5950 };
5951
5952 static struct hda_verb alc882_eapd_verbs[] = {
5953 /* change to EAPD mode */
5954 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
5955 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
5956 { }
5957 };
5958
5959 /* Mac Pro test */
5960 static struct snd_kcontrol_new alc882_macpro_mixer[] = {
5961 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5962 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5963 HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
5964 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
5965 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
5966 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x02, HDA_INPUT),
5967 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x02, HDA_INPUT),
5968 { } /* end */
5969 };
5970
5971 static struct hda_verb alc882_macpro_init_verbs[] = {
5972 /* Front mixer: unmute input/output amp left and right (volume = 0) */
5973 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5974 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5975 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5976 /* Front Pin: output 0 (0x0c) */
5977 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5978 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5979 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
5980 /* Front Mic pin: input vref at 80% */
5981 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5982 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5983 /* Speaker: output */
5984 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5985 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5986 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
5987 /* Headphone output (output 0 - 0x0c) */
5988 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5989 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5990 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
5991
5992 /* FIXME: use matrix-type input source selection */
5993 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5994 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5995 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5996 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5997 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5998 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5999 /* Input mixer2 */
6000 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6001 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6002 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6003 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6004 /* Input mixer3 */
6005 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6006 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6007 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6008 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6009 /* ADC1: mute amp left and right */
6010 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6011 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
6012 /* ADC2: mute amp left and right */
6013 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6014 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6015 /* ADC3: mute amp left and right */
6016 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6017 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6018
6019 { }
6020 };
6021
6022 /* Macbook Pro rev3 */
6023 static struct hda_verb alc885_mbp3_init_verbs[] = {
6024 /* Front mixer: unmute input/output amp left and right (volume = 0) */
6025 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6026 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6027 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6028 /* Rear mixer */
6029 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6030 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6031 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6032 /* Front Pin: output 0 (0x0c) */
6033 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6034 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6035 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
6036 /* HP Pin: output 0 (0x0d) */
6037 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
6038 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6039 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6040 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6041 /* Mic (rear) pin: input vref at 80% */
6042 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6043 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6044 /* Front Mic pin: input vref at 80% */
6045 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6046 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6047 /* Line In pin: use output 1 when in LineOut mode */
6048 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6049 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6050 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
6051
6052 /* FIXME: use matrix-type input source selection */
6053 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6054 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
6055 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6056 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6057 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6058 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6059 /* Input mixer2 */
6060 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6061 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6062 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6063 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6064 /* Input mixer3 */
6065 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6066 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6067 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6068 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6069 /* ADC1: mute amp left and right */
6070 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6071 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
6072 /* ADC2: mute amp left and right */
6073 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6074 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6075 /* ADC3: mute amp left and right */
6076 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6077 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6078
6079 { }
6080 };
6081
6082 /* iMac 24 mixer. */
6083 static struct snd_kcontrol_new alc885_imac24_mixer[] = {
6084 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
6085 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
6086 { } /* end */
6087 };
6088
6089 /* iMac 24 init verbs. */
6090 static struct hda_verb alc885_imac24_init_verbs[] = {
6091 /* Internal speakers: output 0 (0x0c) */
6092 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6093 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6094 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
6095 /* Internal speakers: output 0 (0x0c) */
6096 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6097 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6098 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
6099 /* Headphone: output 0 (0x0c) */
6100 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6101 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6102 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
6103 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6104 /* Front Mic: input vref at 80% */
6105 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6106 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6107 { }
6108 };
6109
6110 /* Toggle speaker-output according to the hp-jack state */
6111 static void alc885_imac24_automute(struct hda_codec *codec)
6112 {
6113 unsigned int present;
6114
6115 present = snd_hda_codec_read(codec, 0x14, 0,
6116 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6117 snd_hda_codec_amp_stereo(codec, 0x18, HDA_OUTPUT, 0,
6118 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6119 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
6120 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6121 }
6122
6123 /* Processes unsolicited events. */
6124 static void alc885_imac24_unsol_event(struct hda_codec *codec,
6125 unsigned int res)
6126 {
6127 /* Headphone insertion or removal. */
6128 if ((res >> 26) == ALC880_HP_EVENT)
6129 alc885_imac24_automute(codec);
6130 }
6131
6132 static void alc885_mbp3_automute(struct hda_codec *codec)
6133 {
6134 unsigned int present;
6135
6136 present = snd_hda_codec_read(codec, 0x15, 0,
6137 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6138 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
6139 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6140 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
6141 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
6142
6143 }
6144 static void alc885_mbp3_unsol_event(struct hda_codec *codec,
6145 unsigned int res)
6146 {
6147 /* Headphone insertion or removal. */
6148 if ((res >> 26) == ALC880_HP_EVENT)
6149 alc885_mbp3_automute(codec);
6150 }
6151
6152
6153 static struct hda_verb alc882_targa_verbs[] = {
6154 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6155 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6156
6157 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6158 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6159
6160 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6161 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6162 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6163
6164 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6165 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
6166 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
6167 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
6168 { } /* end */
6169 };
6170
6171 /* toggle speaker-output according to the hp-jack state */
6172 static void alc882_targa_automute(struct hda_codec *codec)
6173 {
6174 unsigned int present;
6175
6176 present = snd_hda_codec_read(codec, 0x14, 0,
6177 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6178 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
6179 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6180 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
6181 present ? 1 : 3);
6182 }
6183
6184 static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
6185 {
6186 /* Looks like the unsol event is incompatible with the standard
6187 * definition. 4bit tag is placed at 26 bit!
6188 */
6189 if (((res >> 26) == ALC880_HP_EVENT)) {
6190 alc882_targa_automute(codec);
6191 }
6192 }
6193
6194 static struct hda_verb alc882_asus_a7j_verbs[] = {
6195 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6196 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6197
6198 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6199 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6200 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6201
6202 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6203 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6204 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6205
6206 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6207 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6208 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6209 { } /* end */
6210 };
6211
6212 static struct hda_verb alc882_asus_a7m_verbs[] = {
6213 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6214 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6215
6216 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6217 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6218 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6219
6220 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6221 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6222 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
6223
6224 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6225 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6226 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6227 { } /* end */
6228 };
6229
6230 static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
6231 {
6232 unsigned int gpiostate, gpiomask, gpiodir;
6233
6234 gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
6235 AC_VERB_GET_GPIO_DATA, 0);
6236
6237 if (!muted)
6238 gpiostate |= (1 << pin);
6239 else
6240 gpiostate &= ~(1 << pin);
6241
6242 gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
6243 AC_VERB_GET_GPIO_MASK, 0);
6244 gpiomask |= (1 << pin);
6245
6246 gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
6247 AC_VERB_GET_GPIO_DIRECTION, 0);
6248 gpiodir |= (1 << pin);
6249
6250
6251 snd_hda_codec_write(codec, codec->afg, 0,
6252 AC_VERB_SET_GPIO_MASK, gpiomask);
6253 snd_hda_codec_write(codec, codec->afg, 0,
6254 AC_VERB_SET_GPIO_DIRECTION, gpiodir);
6255
6256 msleep(1);
6257
6258 snd_hda_codec_write(codec, codec->afg, 0,
6259 AC_VERB_SET_GPIO_DATA, gpiostate);
6260 }
6261
6262 /* set up GPIO at initialization */
6263 static void alc885_macpro_init_hook(struct hda_codec *codec)
6264 {
6265 alc882_gpio_mute(codec, 0, 0);
6266 alc882_gpio_mute(codec, 1, 0);
6267 }
6268
6269 /* set up GPIO and update auto-muting at initialization */
6270 static void alc885_imac24_init_hook(struct hda_codec *codec)
6271 {
6272 alc885_macpro_init_hook(codec);
6273 alc885_imac24_automute(codec);
6274 }
6275
6276 /*
6277 * generic initialization of ADC, input mixers and output mixers
6278 */
6279 static struct hda_verb alc882_auto_init_verbs[] = {
6280 /*
6281 * Unmute ADC0-2 and set the default input to mic-in
6282 */
6283 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
6284 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6285 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6286 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6287 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6288 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6289
6290 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
6291 * mixer widget
6292 * Note: PASD motherboards uses the Line In 2 as the input for
6293 * front panel mic (mic 2)
6294 */
6295 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
6296 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6297 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6298 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6299 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6300 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6301
6302 /*
6303 * Set up output mixers (0x0c - 0x0f)
6304 */
6305 /* set vol=0 to output mixers */
6306 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6307 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6308 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6309 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6310 /* set up input amps for analog loopback */
6311 /* Amp Indices: DAC = 0, mixer = 1 */
6312 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6313 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6314 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6315 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6316 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6317 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6318 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6319 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6320 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6321 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6322
6323 /* FIXME: use matrix-type input source selection */
6324 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6325 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
6326 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6327 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6328 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6329 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
6330 /* Input mixer2 */
6331 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6332 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6333 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6334 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
6335 /* Input mixer3 */
6336 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6337 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
6338 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
6339 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
6340
6341 { }
6342 };
6343
6344 /* capture mixer elements */
6345 static struct snd_kcontrol_new alc882_capture_alt_mixer[] = {
6346 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6347 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6348 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6349 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6350 {
6351 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6352 /* The multiple "Capture Source" controls confuse alsamixer
6353 * So call somewhat different..
6354 */
6355 /* .name = "Capture Source", */
6356 .name = "Input Source",
6357 .count = 2,
6358 .info = alc882_mux_enum_info,
6359 .get = alc882_mux_enum_get,
6360 .put = alc882_mux_enum_put,
6361 },
6362 { } /* end */
6363 };
6364
6365 static struct snd_kcontrol_new alc882_capture_mixer[] = {
6366 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
6367 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
6368 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
6369 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
6370 HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
6371 HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
6372 {
6373 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6374 /* The multiple "Capture Source" controls confuse alsamixer
6375 * So call somewhat different..
6376 */
6377 /* .name = "Capture Source", */
6378 .name = "Input Source",
6379 .count = 3,
6380 .info = alc882_mux_enum_info,
6381 .get = alc882_mux_enum_get,
6382 .put = alc882_mux_enum_put,
6383 },
6384 { } /* end */
6385 };
6386
6387 #ifdef CONFIG_SND_HDA_POWER_SAVE
6388 #define alc882_loopbacks alc880_loopbacks
6389 #endif
6390
6391 /* pcm configuration: identiacal with ALC880 */
6392 #define alc882_pcm_analog_playback alc880_pcm_analog_playback
6393 #define alc882_pcm_analog_capture alc880_pcm_analog_capture
6394 #define alc882_pcm_digital_playback alc880_pcm_digital_playback
6395 #define alc882_pcm_digital_capture alc880_pcm_digital_capture
6396
6397 /*
6398 * configuration and preset
6399 */
6400 static const char *alc882_models[ALC882_MODEL_LAST] = {
6401 [ALC882_3ST_DIG] = "3stack-dig",
6402 [ALC882_6ST_DIG] = "6stack-dig",
6403 [ALC882_ARIMA] = "arima",
6404 [ALC882_W2JC] = "w2jc",
6405 [ALC882_TARGA] = "targa",
6406 [ALC882_ASUS_A7J] = "asus-a7j",
6407 [ALC882_ASUS_A7M] = "asus-a7m",
6408 [ALC885_MACPRO] = "macpro",
6409 [ALC885_MBP3] = "mbp3",
6410 [ALC885_IMAC24] = "imac24",
6411 [ALC882_AUTO] = "auto",
6412 };
6413
6414 static struct snd_pci_quirk alc882_cfg_tbl[] = {
6415 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
6416 SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
6417 SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
6418 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
6419 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
6420 SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
6421 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
6422 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
6423 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG),
6424 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */
6425 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
6426 SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA),
6427 {}
6428 };
6429
6430 static struct alc_config_preset alc882_presets[] = {
6431 [ALC882_3ST_DIG] = {
6432 .mixers = { alc882_base_mixer },
6433 .init_verbs = { alc882_init_verbs },
6434 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6435 .dac_nids = alc882_dac_nids,
6436 .dig_out_nid = ALC882_DIGOUT_NID,
6437 .dig_in_nid = ALC882_DIGIN_NID,
6438 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
6439 .channel_mode = alc882_ch_modes,
6440 .need_dac_fix = 1,
6441 .input_mux = &alc882_capture_source,
6442 },
6443 [ALC882_6ST_DIG] = {
6444 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
6445 .init_verbs = { alc882_init_verbs },
6446 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6447 .dac_nids = alc882_dac_nids,
6448 .dig_out_nid = ALC882_DIGOUT_NID,
6449 .dig_in_nid = ALC882_DIGIN_NID,
6450 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
6451 .channel_mode = alc882_sixstack_modes,
6452 .input_mux = &alc882_capture_source,
6453 },
6454 [ALC882_ARIMA] = {
6455 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
6456 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs },
6457 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6458 .dac_nids = alc882_dac_nids,
6459 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
6460 .channel_mode = alc882_sixstack_modes,
6461 .input_mux = &alc882_capture_source,
6462 },
6463 [ALC882_W2JC] = {
6464 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
6465 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
6466 alc880_gpio1_init_verbs },
6467 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6468 .dac_nids = alc882_dac_nids,
6469 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
6470 .channel_mode = alc880_threestack_modes,
6471 .need_dac_fix = 1,
6472 .input_mux = &alc882_capture_source,
6473 .dig_out_nid = ALC882_DIGOUT_NID,
6474 },
6475 [ALC885_MBP3] = {
6476 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
6477 .init_verbs = { alc885_mbp3_init_verbs,
6478 alc880_gpio1_init_verbs },
6479 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6480 .dac_nids = alc882_dac_nids,
6481 .channel_mode = alc885_mbp_6ch_modes,
6482 .num_channel_mode = ARRAY_SIZE(alc885_mbp_6ch_modes),
6483 .input_mux = &alc882_capture_source,
6484 .dig_out_nid = ALC882_DIGOUT_NID,
6485 .dig_in_nid = ALC882_DIGIN_NID,
6486 .unsol_event = alc885_mbp3_unsol_event,
6487 .init_hook = alc885_mbp3_automute,
6488 },
6489 [ALC885_MACPRO] = {
6490 .mixers = { alc882_macpro_mixer },
6491 .init_verbs = { alc882_macpro_init_verbs },
6492 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6493 .dac_nids = alc882_dac_nids,
6494 .dig_out_nid = ALC882_DIGOUT_NID,
6495 .dig_in_nid = ALC882_DIGIN_NID,
6496 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
6497 .channel_mode = alc882_ch_modes,
6498 .input_mux = &alc882_capture_source,
6499 .init_hook = alc885_macpro_init_hook,
6500 },
6501 [ALC885_IMAC24] = {
6502 .mixers = { alc885_imac24_mixer },
6503 .init_verbs = { alc885_imac24_init_verbs },
6504 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6505 .dac_nids = alc882_dac_nids,
6506 .dig_out_nid = ALC882_DIGOUT_NID,
6507 .dig_in_nid = ALC882_DIGIN_NID,
6508 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
6509 .channel_mode = alc882_ch_modes,
6510 .input_mux = &alc882_capture_source,
6511 .unsol_event = alc885_imac24_unsol_event,
6512 .init_hook = alc885_imac24_init_hook,
6513 },
6514 [ALC882_TARGA] = {
6515 .mixers = { alc882_targa_mixer, alc882_chmode_mixer,
6516 alc882_capture_mixer },
6517 .init_verbs = { alc882_init_verbs, alc882_targa_verbs},
6518 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6519 .dac_nids = alc882_dac_nids,
6520 .dig_out_nid = ALC882_DIGOUT_NID,
6521 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
6522 .adc_nids = alc882_adc_nids,
6523 .capsrc_nids = alc882_capsrc_nids,
6524 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
6525 .channel_mode = alc882_3ST_6ch_modes,
6526 .need_dac_fix = 1,
6527 .input_mux = &alc882_capture_source,
6528 .unsol_event = alc882_targa_unsol_event,
6529 .init_hook = alc882_targa_automute,
6530 },
6531 [ALC882_ASUS_A7J] = {
6532 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer,
6533 alc882_capture_mixer },
6534 .init_verbs = { alc882_init_verbs, alc882_asus_a7j_verbs},
6535 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6536 .dac_nids = alc882_dac_nids,
6537 .dig_out_nid = ALC882_DIGOUT_NID,
6538 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
6539 .adc_nids = alc882_adc_nids,
6540 .capsrc_nids = alc882_capsrc_nids,
6541 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
6542 .channel_mode = alc882_3ST_6ch_modes,
6543 .need_dac_fix = 1,
6544 .input_mux = &alc882_capture_source,
6545 },
6546 [ALC882_ASUS_A7M] = {
6547 .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
6548 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
6549 alc880_gpio1_init_verbs,
6550 alc882_asus_a7m_verbs },
6551 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6552 .dac_nids = alc882_dac_nids,
6553 .dig_out_nid = ALC882_DIGOUT_NID,
6554 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
6555 .channel_mode = alc880_threestack_modes,
6556 .need_dac_fix = 1,
6557 .input_mux = &alc882_capture_source,
6558 },
6559 };
6560
6561
6562 /*
6563 * Pin config fixes
6564 */
6565 enum {
6566 PINFIX_ABIT_AW9D_MAX
6567 };
6568
6569 static struct alc_pincfg alc882_abit_aw9d_pinfix[] = {
6570 { 0x15, 0x01080104 }, /* side */
6571 { 0x16, 0x01011012 }, /* rear */
6572 { 0x17, 0x01016011 }, /* clfe */
6573 { }
6574 };
6575
6576 static const struct alc_pincfg *alc882_pin_fixes[] = {
6577 [PINFIX_ABIT_AW9D_MAX] = alc882_abit_aw9d_pinfix,
6578 };
6579
6580 static struct snd_pci_quirk alc882_pinfix_tbl[] = {
6581 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
6582 {}
6583 };
6584
6585 /*
6586 * BIOS auto configuration
6587 */
6588 static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
6589 hda_nid_t nid, int pin_type,
6590 int dac_idx)
6591 {
6592 /* set as output */
6593 struct alc_spec *spec = codec->spec;
6594 int idx;
6595
6596 alc_set_pin_output(codec, nid, pin_type);
6597 if (spec->multiout.dac_nids[dac_idx] == 0x25)
6598 idx = 4;
6599 else
6600 idx = spec->multiout.dac_nids[dac_idx] - 2;
6601 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
6602
6603 }
6604
6605 static void alc882_auto_init_multi_out(struct hda_codec *codec)
6606 {
6607 struct alc_spec *spec = codec->spec;
6608 int i;
6609
6610 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
6611 for (i = 0; i <= HDA_SIDE; i++) {
6612 hda_nid_t nid = spec->autocfg.line_out_pins[i];
6613 int pin_type = get_pin_type(spec->autocfg.line_out_type);
6614 if (nid)
6615 alc882_auto_set_output_and_unmute(codec, nid, pin_type,
6616 i);
6617 }
6618 }
6619
6620 static void alc882_auto_init_hp_out(struct hda_codec *codec)
6621 {
6622 struct alc_spec *spec = codec->spec;
6623 hda_nid_t pin;
6624
6625 pin = spec->autocfg.hp_pins[0];
6626 if (pin) /* connect to front */
6627 /* use dac 0 */
6628 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
6629 pin = spec->autocfg.speaker_pins[0];
6630 if (pin)
6631 alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
6632 }
6633
6634 #define alc882_is_input_pin(nid) alc880_is_input_pin(nid)
6635 #define ALC882_PIN_CD_NID ALC880_PIN_CD_NID
6636
6637 static void alc882_auto_init_analog_input(struct hda_codec *codec)
6638 {
6639 struct alc_spec *spec = codec->spec;
6640 int i;
6641
6642 for (i = 0; i < AUTO_PIN_LAST; i++) {
6643 hda_nid_t nid = spec->autocfg.input_pins[i];
6644 unsigned int vref;
6645 if (!nid)
6646 continue;
6647 vref = PIN_IN;
6648 if (1 /*i <= AUTO_PIN_FRONT_MIC*/) {
6649 unsigned int pincap;
6650 pincap = snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP);
6651 if ((pincap >> AC_PINCAP_VREF_SHIFT) &
6652 AC_PINCAP_VREF_80)
6653 vref = PIN_VREF80;
6654 }
6655 snd_hda_codec_write(codec, nid, 0,
6656 AC_VERB_SET_PIN_WIDGET_CONTROL, vref);
6657 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
6658 snd_hda_codec_write(codec, nid, 0,
6659 AC_VERB_SET_AMP_GAIN_MUTE,
6660 AMP_OUT_MUTE);
6661 }
6662 }
6663
6664 static void alc882_auto_init_input_src(struct hda_codec *codec)
6665 {
6666 struct alc_spec *spec = codec->spec;
6667 const struct hda_input_mux *imux = spec->input_mux;
6668 int c;
6669
6670 for (c = 0; c < spec->num_adc_nids; c++) {
6671 hda_nid_t conn_list[HDA_MAX_NUM_INPUTS];
6672 hda_nid_t nid = spec->capsrc_nids[c];
6673 int conns, mute, idx, item;
6674
6675 conns = snd_hda_get_connections(codec, nid, conn_list,
6676 ARRAY_SIZE(conn_list));
6677 if (conns < 0)
6678 continue;
6679 for (idx = 0; idx < conns; idx++) {
6680 /* if the current connection is the selected one,
6681 * unmute it as default - otherwise mute it
6682 */
6683 mute = AMP_IN_MUTE(idx);
6684 for (item = 0; item < imux->num_items; item++) {
6685 if (imux->items[item].index == idx) {
6686 if (spec->cur_mux[c] == item)
6687 mute = AMP_IN_UNMUTE(idx);
6688 break;
6689 }
6690 }
6691 snd_hda_codec_write(codec, nid, 0,
6692 AC_VERB_SET_AMP_GAIN_MUTE, mute);
6693 }
6694 }
6695 }
6696
6697 /* add mic boosts if needed */
6698 static int alc_auto_add_mic_boost(struct hda_codec *codec)
6699 {
6700 struct alc_spec *spec = codec->spec;
6701 int err;
6702 hda_nid_t nid;
6703
6704 nid = spec->autocfg.input_pins[AUTO_PIN_MIC];
6705 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
6706 err = add_control(spec, ALC_CTL_WIDGET_VOL,
6707 "Mic Boost",
6708 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
6709 if (err < 0)
6710 return err;
6711 }
6712 nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC];
6713 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
6714 err = add_control(spec, ALC_CTL_WIDGET_VOL,
6715 "Front Mic Boost",
6716 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
6717 if (err < 0)
6718 return err;
6719 }
6720 return 0;
6721 }
6722
6723 /* almost identical with ALC880 parser... */
6724 static int alc882_parse_auto_config(struct hda_codec *codec)
6725 {
6726 struct alc_spec *spec = codec->spec;
6727 int err = alc880_parse_auto_config(codec);
6728
6729 if (err < 0)
6730 return err;
6731 else if (!err)
6732 return 0; /* no config found */
6733
6734 err = alc_auto_add_mic_boost(codec);
6735 if (err < 0)
6736 return err;
6737
6738 /* hack - override the init verbs */
6739 spec->init_verbs[0] = alc882_auto_init_verbs;
6740
6741 return 1; /* config found */
6742 }
6743
6744 /* additional initialization for auto-configuration model */
6745 static void alc882_auto_init(struct hda_codec *codec)
6746 {
6747 struct alc_spec *spec = codec->spec;
6748 alc882_auto_init_multi_out(codec);
6749 alc882_auto_init_hp_out(codec);
6750 alc882_auto_init_analog_input(codec);
6751 alc882_auto_init_input_src(codec);
6752 if (spec->unsol_event)
6753 alc_inithook(codec);
6754 }
6755
6756 static int patch_alc883(struct hda_codec *codec); /* called in patch_alc882() */
6757
6758 static int patch_alc882(struct hda_codec *codec)
6759 {
6760 struct alc_spec *spec;
6761 int err, board_config;
6762
6763 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
6764 if (spec == NULL)
6765 return -ENOMEM;
6766
6767 codec->spec = spec;
6768
6769 board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
6770 alc882_models,
6771 alc882_cfg_tbl);
6772
6773 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
6774 /* Pick up systems that don't supply PCI SSID */
6775 switch (codec->subsystem_id) {
6776 case 0x106b0c00: /* Mac Pro */
6777 board_config = ALC885_MACPRO;
6778 break;
6779 case 0x106b1000: /* iMac 24 */
6780 case 0x106b2800: /* AppleTV */
6781 board_config = ALC885_IMAC24;
6782 break;
6783 case 0x106b00a1: /* Macbook (might be wrong - PCI SSID?) */
6784 case 0x106b00a4: /* MacbookPro4,1 */
6785 case 0x106b2c00: /* Macbook Pro rev3 */
6786 case 0x106b3600: /* Macbook 3.1 */
6787 board_config = ALC885_MBP3;
6788 break;
6789 default:
6790 /* ALC889A is handled better as ALC888-compatible */
6791 if (codec->revision_id == 0x100101 ||
6792 codec->revision_id == 0x100103) {
6793 alc_free(codec);
6794 return patch_alc883(codec);
6795 }
6796 printk(KERN_INFO "hda_codec: Unknown model for ALC882, "
6797 "trying auto-probe from BIOS...\n");
6798 board_config = ALC882_AUTO;
6799 }
6800 }
6801
6802 alc_fix_pincfg(codec, alc882_pinfix_tbl, alc882_pin_fixes);
6803
6804 if (board_config == ALC882_AUTO) {
6805 /* automatic parse from the BIOS config */
6806 err = alc882_parse_auto_config(codec);
6807 if (err < 0) {
6808 alc_free(codec);
6809 return err;
6810 } else if (!err) {
6811 printk(KERN_INFO
6812 "hda_codec: Cannot set up configuration "
6813 "from BIOS. Using base mode...\n");
6814 board_config = ALC882_3ST_DIG;
6815 }
6816 }
6817
6818 if (board_config != ALC882_AUTO)
6819 setup_preset(spec, &alc882_presets[board_config]);
6820
6821 if (codec->vendor_id == 0x10ec0885) {
6822 spec->stream_name_analog = "ALC885 Analog";
6823 spec->stream_name_digital = "ALC885 Digital";
6824 } else {
6825 spec->stream_name_analog = "ALC882 Analog";
6826 spec->stream_name_digital = "ALC882 Digital";
6827 }
6828
6829 spec->stream_analog_playback = &alc882_pcm_analog_playback;
6830 spec->stream_analog_capture = &alc882_pcm_analog_capture;
6831 /* FIXME: setup DAC5 */
6832 /*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/
6833 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
6834
6835 spec->stream_digital_playback = &alc882_pcm_digital_playback;
6836 spec->stream_digital_capture = &alc882_pcm_digital_capture;
6837
6838 if (!spec->adc_nids && spec->input_mux) {
6839 /* check whether NID 0x07 is valid */
6840 unsigned int wcap = get_wcaps(codec, 0x07);
6841 /* get type */
6842 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
6843 if (wcap != AC_WID_AUD_IN) {
6844 spec->adc_nids = alc882_adc_nids_alt;
6845 spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids_alt);
6846 spec->capsrc_nids = alc882_capsrc_nids_alt;
6847 add_mixer(spec, alc882_capture_alt_mixer);
6848 } else {
6849 spec->adc_nids = alc882_adc_nids;
6850 spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids);
6851 spec->capsrc_nids = alc882_capsrc_nids;
6852 add_mixer(spec, alc882_capture_mixer);
6853 }
6854 }
6855
6856 spec->vmaster_nid = 0x0c;
6857
6858 codec->patch_ops = alc_patch_ops;
6859 if (board_config == ALC882_AUTO)
6860 spec->init_hook = alc882_auto_init;
6861 #ifdef CONFIG_SND_HDA_POWER_SAVE
6862 if (!spec->loopback.amplist)
6863 spec->loopback.amplist = alc882_loopbacks;
6864 #endif
6865
6866 return 0;
6867 }
6868
6869 /*
6870 * ALC883 support
6871 *
6872 * ALC883 is almost identical with ALC880 but has cleaner and more flexible
6873 * configuration. Each pin widget can choose any input DACs and a mixer.
6874 * Each ADC is connected from a mixer of all inputs. This makes possible
6875 * 6-channel independent captures.
6876 *
6877 * In addition, an independent DAC for the multi-playback (not used in this
6878 * driver yet).
6879 */
6880 #define ALC883_DIGOUT_NID 0x06
6881 #define ALC883_DIGIN_NID 0x0a
6882
6883 static hda_nid_t alc883_dac_nids[4] = {
6884 /* front, rear, clfe, rear_surr */
6885 0x02, 0x03, 0x04, 0x05
6886 };
6887
6888 static hda_nid_t alc883_adc_nids[2] = {
6889 /* ADC1-2 */
6890 0x08, 0x09,
6891 };
6892
6893 static hda_nid_t alc883_capsrc_nids[2] = { 0x23, 0x22 };
6894
6895 /* input MUX */
6896 /* FIXME: should be a matrix-type input source selection */
6897
6898 static struct hda_input_mux alc883_capture_source = {
6899 .num_items = 4,
6900 .items = {
6901 { "Mic", 0x0 },
6902 { "Front Mic", 0x1 },
6903 { "Line", 0x2 },
6904 { "CD", 0x4 },
6905 },
6906 };
6907
6908 static struct hda_input_mux alc883_3stack_6ch_intel = {
6909 .num_items = 4,
6910 .items = {
6911 { "Mic", 0x1 },
6912 { "Front Mic", 0x0 },
6913 { "Line", 0x2 },
6914 { "CD", 0x4 },
6915 },
6916 };
6917
6918 static struct hda_input_mux alc883_lenovo_101e_capture_source = {
6919 .num_items = 2,
6920 .items = {
6921 { "Mic", 0x1 },
6922 { "Line", 0x2 },
6923 },
6924 };
6925
6926 static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
6927 .num_items = 4,
6928 .items = {
6929 { "Mic", 0x0 },
6930 { "iMic", 0x1 },
6931 { "Line", 0x2 },
6932 { "CD", 0x4 },
6933 },
6934 };
6935
6936 static struct hda_input_mux alc883_fujitsu_pi2515_capture_source = {
6937 .num_items = 2,
6938 .items = {
6939 { "Mic", 0x0 },
6940 { "Int Mic", 0x1 },
6941 },
6942 };
6943
6944 static struct hda_input_mux alc883_lenovo_sky_capture_source = {
6945 .num_items = 3,
6946 .items = {
6947 { "Mic", 0x0 },
6948 { "Front Mic", 0x1 },
6949 { "Line", 0x4 },
6950 },
6951 };
6952
6953 static struct hda_input_mux alc883_asus_eee1601_capture_source = {
6954 .num_items = 2,
6955 .items = {
6956 { "Mic", 0x0 },
6957 { "Line", 0x2 },
6958 },
6959 };
6960
6961 #define alc883_mux_enum_info alc_mux_enum_info
6962 #define alc883_mux_enum_get alc_mux_enum_get
6963 /* ALC883 has the ALC882-type input selection */
6964 #define alc883_mux_enum_put alc882_mux_enum_put
6965
6966 /*
6967 * 2ch mode
6968 */
6969 static struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
6970 { 2, NULL }
6971 };
6972
6973 /*
6974 * 2ch mode
6975 */
6976 static struct hda_verb alc883_3ST_ch2_init[] = {
6977 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6978 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6979 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6980 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6981 { } /* end */
6982 };
6983
6984 /*
6985 * 4ch mode
6986 */
6987 static struct hda_verb alc883_3ST_ch4_init[] = {
6988 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6989 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6990 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6991 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6992 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6993 { } /* end */
6994 };
6995
6996 /*
6997 * 6ch mode
6998 */
6999 static struct hda_verb alc883_3ST_ch6_init[] = {
7000 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7001 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7002 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7003 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7004 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7005 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7006 { } /* end */
7007 };
7008
7009 static struct hda_channel_mode alc883_3ST_6ch_modes[3] = {
7010 { 2, alc883_3ST_ch2_init },
7011 { 4, alc883_3ST_ch4_init },
7012 { 6, alc883_3ST_ch6_init },
7013 };
7014
7015 /*
7016 * 2ch mode
7017 */
7018 static struct hda_verb alc883_3ST_ch2_intel_init[] = {
7019 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7020 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7021 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7022 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7023 { } /* end */
7024 };
7025
7026 /*
7027 * 4ch mode
7028 */
7029 static struct hda_verb alc883_3ST_ch4_intel_init[] = {
7030 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7031 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
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 /*
7039 * 6ch mode
7040 */
7041 static struct hda_verb alc883_3ST_ch6_intel_init[] = {
7042 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7043 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7044 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 },
7045 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7046 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7047 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7048 { } /* end */
7049 };
7050
7051 static struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = {
7052 { 2, alc883_3ST_ch2_intel_init },
7053 { 4, alc883_3ST_ch4_intel_init },
7054 { 6, alc883_3ST_ch6_intel_init },
7055 };
7056
7057 /*
7058 * 6ch mode
7059 */
7060 static struct hda_verb alc883_sixstack_ch6_init[] = {
7061 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7062 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7063 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7064 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7065 { } /* end */
7066 };
7067
7068 /*
7069 * 8ch mode
7070 */
7071 static struct hda_verb alc883_sixstack_ch8_init[] = {
7072 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7073 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7074 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7075 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7076 { } /* end */
7077 };
7078
7079 static struct hda_channel_mode alc883_sixstack_modes[2] = {
7080 { 6, alc883_sixstack_ch6_init },
7081 { 8, alc883_sixstack_ch8_init },
7082 };
7083
7084 static struct hda_verb alc883_medion_eapd_verbs[] = {
7085 /* eanable EAPD on medion laptop */
7086 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
7087 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
7088 { }
7089 };
7090
7091 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
7092 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
7093 */
7094
7095 static struct snd_kcontrol_new alc883_base_mixer[] = {
7096 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7097 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7098 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7099 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7100 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7101 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7102 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7103 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7104 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
7105 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
7106 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7107 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7108 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7109 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7110 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7111 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7112 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7113 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7114 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7115 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7116 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7117 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
7118 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
7119 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7120 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7121 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7122 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7123 {
7124 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7125 /* .name = "Capture Source", */
7126 .name = "Input Source",
7127 .count = 2,
7128 .info = alc883_mux_enum_info,
7129 .get = alc883_mux_enum_get,
7130 .put = alc883_mux_enum_put,
7131 },
7132 { } /* end */
7133 };
7134
7135 static struct snd_kcontrol_new alc883_mitac_mixer[] = {
7136 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7137 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7138 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7139 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7140 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7141 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7142 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7143 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7144 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7145 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7146 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7147 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7148 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7149 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7150 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7151 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7152 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7153 {
7154 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7155 /* .name = "Capture Source", */
7156 .name = "Input Source",
7157 .count = 2,
7158 .info = alc883_mux_enum_info,
7159 .get = alc883_mux_enum_get,
7160 .put = alc883_mux_enum_put,
7161 },
7162 { } /* end */
7163 };
7164
7165 static struct snd_kcontrol_new alc883_clevo_m720_mixer[] = {
7166 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7167 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
7168 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7169 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
7170 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7171 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7172 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7173 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7174 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7175 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7176 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7177 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7178 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7179 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7180 {
7181 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7182 /* .name = "Capture Source", */
7183 .name = "Input Source",
7184 .count = 2,
7185 .info = alc883_mux_enum_info,
7186 .get = alc883_mux_enum_get,
7187 .put = alc883_mux_enum_put,
7188 },
7189 { } /* end */
7190 };
7191
7192 static struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = {
7193 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7194 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
7195 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7196 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
7197 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7198 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7199 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7200 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7201 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7202 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7203 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7204 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7205 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7206 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7207 {
7208 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7209 /* .name = "Capture Source", */
7210 .name = "Input Source",
7211 .count = 2,
7212 .info = alc883_mux_enum_info,
7213 .get = alc883_mux_enum_get,
7214 .put = alc883_mux_enum_put,
7215 },
7216 { } /* end */
7217 };
7218
7219 static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
7220 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7221 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7222 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7223 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7224 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7225 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7226 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7227 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7228 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7229 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7230 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7231 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7232 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7233 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
7234 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
7235 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7236 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7237 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7238 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7239 {
7240 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7241 /* .name = "Capture Source", */
7242 .name = "Input Source",
7243 .count = 2,
7244 .info = alc883_mux_enum_info,
7245 .get = alc883_mux_enum_get,
7246 .put = alc883_mux_enum_put,
7247 },
7248 { } /* end */
7249 };
7250
7251 static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
7252 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7253 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7254 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7255 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7256 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7257 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7258 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7259 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7260 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7261 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7262 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7263 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7264 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7265 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7266 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7267 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7268 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7269 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7270 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7271 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
7272 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
7273 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7274 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7275 {
7276 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7277 /* .name = "Capture Source", */
7278 .name = "Input Source",
7279 .count = 1,
7280 .info = alc883_mux_enum_info,
7281 .get = alc883_mux_enum_get,
7282 .put = alc883_mux_enum_put,
7283 },
7284 { } /* end */
7285 };
7286
7287 static struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = {
7288 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7289 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7290 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7291 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7292 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
7293 HDA_OUTPUT),
7294 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7295 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7296 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7297 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7298 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7299 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7300 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7301 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7302 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7303 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
7304 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7305 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7306 HDA_CODEC_VOLUME("Front Mic Boost", 0x18, 0, HDA_INPUT),
7307 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7308 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
7309 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
7310 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7311 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7312 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7313 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7314 {
7315 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7316 /* .name = "Capture Source", */
7317 .name = "Input Source",
7318 .count = 2,
7319 .info = alc883_mux_enum_info,
7320 .get = alc883_mux_enum_get,
7321 .put = alc883_mux_enum_put,
7322 },
7323 { } /* end */
7324 };
7325
7326 static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
7327 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7328 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7329 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7330 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7331 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7332 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7333 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7334 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7335 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7336 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7337 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7338 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7339 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7340 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7341 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7342 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7343 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7344 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7345 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7346 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
7347 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
7348 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7349 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7350
7351 {
7352 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7353 /* .name = "Capture Source", */
7354 .name = "Input Source",
7355 .count = 1,
7356 .info = alc883_mux_enum_info,
7357 .get = alc883_mux_enum_get,
7358 .put = alc883_mux_enum_put,
7359 },
7360 { } /* end */
7361 };
7362
7363 static struct snd_kcontrol_new alc883_tagra_mixer[] = {
7364 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7365 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7366 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7367 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7368 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7369 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7370 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7371 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7372 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7373 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7374 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7375 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7376 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7377 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7378 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7379 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7380 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7381 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7382 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7383 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7384 {
7385 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7386 /* .name = "Capture Source", */
7387 .name = "Input Source",
7388 .count = 2,
7389 .info = alc883_mux_enum_info,
7390 .get = alc883_mux_enum_get,
7391 .put = alc883_mux_enum_put,
7392 },
7393 { } /* end */
7394 };
7395
7396 static struct snd_kcontrol_new alc883_tagra_2ch_mixer[] = {
7397 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7398 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7399 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7400 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7401 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7402 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7403 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7404 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7405 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7406 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7407 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7408 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7409 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7410 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7411 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7412 {
7413 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7414 /* .name = "Capture Source", */
7415 .name = "Input Source",
7416 .count = 2,
7417 .info = alc883_mux_enum_info,
7418 .get = alc883_mux_enum_get,
7419 .put = alc883_mux_enum_put,
7420 },
7421 { } /* end */
7422 };
7423
7424 static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
7425 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7426 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7427 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7428 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
7429 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7430 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7431 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7432 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7433 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7434 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7435 {
7436 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7437 /* .name = "Capture Source", */
7438 .name = "Input Source",
7439 .count = 1,
7440 .info = alc883_mux_enum_info,
7441 .get = alc883_mux_enum_get,
7442 .put = alc883_mux_enum_put,
7443 },
7444 { } /* end */
7445 };
7446
7447 static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
7448 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7449 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
7450 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7451 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7452 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7453 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7454 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7455 HDA_CODEC_VOLUME("iMic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7456 HDA_CODEC_MUTE("iMic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7457 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7458 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7459 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7460 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7461 {
7462 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7463 /* .name = "Capture Source", */
7464 .name = "Input Source",
7465 .count = 2,
7466 .info = alc883_mux_enum_info,
7467 .get = alc883_mux_enum_get,
7468 .put = alc883_mux_enum_put,
7469 },
7470 { } /* end */
7471 };
7472
7473 static struct snd_kcontrol_new alc883_medion_md2_mixer[] = {
7474 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7475 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7476 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7477 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7478 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7479 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7480 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7481 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7482 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7483 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7484 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7485 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7486 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7487 {
7488 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7489 /* .name = "Capture Source", */
7490 .name = "Input Source",
7491 .count = 2,
7492 .info = alc883_mux_enum_info,
7493 .get = alc883_mux_enum_get,
7494 .put = alc883_mux_enum_put,
7495 },
7496 { } /* end */
7497 };
7498
7499 static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
7500 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7501 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7502 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7503 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7504 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7505 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7506 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7507 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7508 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7509 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7510 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7511 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7512 {
7513 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7514 /* .name = "Capture Source", */
7515 .name = "Input Source",
7516 .count = 2,
7517 .info = alc883_mux_enum_info,
7518 .get = alc883_mux_enum_get,
7519 .put = alc883_mux_enum_put,
7520 },
7521 { } /* end */
7522 };
7523
7524 static struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = {
7525 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7526 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7527 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
7528 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
7529 HDA_CODEC_VOLUME_MONO("Center Playback Volume",
7530 0x0d, 1, 0x0, HDA_OUTPUT),
7531 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
7532 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
7533 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
7534 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
7535 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
7536 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7537 HDA_CODEC_MUTE("iSpeaker Playback Switch", 0x1a, 0x0, HDA_OUTPUT),
7538 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7539 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7540 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7541 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7542 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7543 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7544 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7545 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7546 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7547 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7548 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7549 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7550 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7551 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7552 {
7553 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7554 /* .name = "Capture Source", */
7555 .name = "Input Source",
7556 .count = 2,
7557 .info = alc883_mux_enum_info,
7558 .get = alc883_mux_enum_get,
7559 .put = alc883_mux_enum_put,
7560 },
7561 { } /* end */
7562 };
7563
7564 static struct hda_bind_ctls alc883_bind_cap_vol = {
7565 .ops = &snd_hda_bind_vol,
7566 .values = {
7567 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
7568 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
7569 0
7570 },
7571 };
7572
7573 static struct hda_bind_ctls alc883_bind_cap_switch = {
7574 .ops = &snd_hda_bind_sw,
7575 .values = {
7576 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
7577 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
7578 0
7579 },
7580 };
7581
7582 static struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = {
7583 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7584 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7585 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7586 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7587 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7588 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7589 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7590 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7591 HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol),
7592 HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch),
7593 {
7594 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7595 /* .name = "Capture Source", */
7596 .name = "Input Source",
7597 .count = 1,
7598 .info = alc883_mux_enum_info,
7599 .get = alc883_mux_enum_get,
7600 .put = alc883_mux_enum_put,
7601 },
7602 { } /* end */
7603 };
7604
7605 static struct snd_kcontrol_new alc883_chmode_mixer[] = {
7606 {
7607 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7608 .name = "Channel Mode",
7609 .info = alc_ch_mode_info,
7610 .get = alc_ch_mode_get,
7611 .put = alc_ch_mode_put,
7612 },
7613 { } /* end */
7614 };
7615
7616 static struct hda_verb alc883_init_verbs[] = {
7617 /* ADC1: mute amp left and right */
7618 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7619 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7620 /* ADC2: mute amp left and right */
7621 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7622 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7623 /* Front mixer: unmute input/output amp left and right (volume = 0) */
7624 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7625 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7626 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7627 /* Rear mixer */
7628 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7629 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7630 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7631 /* CLFE mixer */
7632 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7633 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7634 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7635 /* Side mixer */
7636 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7637 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7638 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7639
7640 /* mute analog input loopbacks */
7641 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7642 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7643 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7644 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7645 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7646
7647 /* Front Pin: output 0 (0x0c) */
7648 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7649 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7650 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7651 /* Rear Pin: output 1 (0x0d) */
7652 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7653 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7654 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7655 /* CLFE Pin: output 2 (0x0e) */
7656 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7657 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7658 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
7659 /* Side Pin: output 3 (0x0f) */
7660 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7661 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7662 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
7663 /* Mic (rear) pin: input vref at 80% */
7664 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7665 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7666 /* Front Mic pin: input vref at 80% */
7667 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7668 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7669 /* Line In pin: input */
7670 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7671 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7672 /* Line-2 In: Headphone output (output 0 - 0x0c) */
7673 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7674 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7675 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
7676 /* CD pin widget for input */
7677 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7678
7679 /* FIXME: use matrix-type input source selection */
7680 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7681 /* Input mixer2 */
7682 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7683 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7684 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7685 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7686 /* Input mixer3 */
7687 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7688 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7689 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7690 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7691 { }
7692 };
7693
7694 /* toggle speaker-output according to the hp-jack state */
7695 static void alc883_mitac_hp_automute(struct hda_codec *codec)
7696 {
7697 unsigned int present;
7698
7699 present = snd_hda_codec_read(codec, 0x15, 0,
7700 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7701 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7702 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7703 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
7704 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7705 }
7706
7707 /* auto-toggle front mic */
7708 /*
7709 static void alc883_mitac_mic_automute(struct hda_codec *codec)
7710 {
7711 unsigned int present;
7712 unsigned char bits;
7713
7714 present = snd_hda_codec_read(codec, 0x18, 0,
7715 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7716 bits = present ? HDA_AMP_MUTE : 0;
7717 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
7718 }
7719 */
7720
7721 static void alc883_mitac_automute(struct hda_codec *codec)
7722 {
7723 alc883_mitac_hp_automute(codec);
7724 /* alc883_mitac_mic_automute(codec); */
7725 }
7726
7727 static void alc883_mitac_unsol_event(struct hda_codec *codec,
7728 unsigned int res)
7729 {
7730 switch (res >> 26) {
7731 case ALC880_HP_EVENT:
7732 alc883_mitac_hp_automute(codec);
7733 break;
7734 case ALC880_MIC_EVENT:
7735 /* alc883_mitac_mic_automute(codec); */
7736 break;
7737 }
7738 }
7739
7740 static struct hda_verb alc883_mitac_verbs[] = {
7741 /* HP */
7742 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7743 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7744 /* Subwoofer */
7745 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
7746 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7747
7748 /* enable unsolicited event */
7749 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7750 /* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */
7751
7752 { } /* end */
7753 };
7754
7755 static struct hda_verb alc883_clevo_m720_verbs[] = {
7756 /* HP */
7757 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7758 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7759 /* Int speaker */
7760 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
7761 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7762
7763 /* enable unsolicited event */
7764 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7765 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
7766
7767 { } /* end */
7768 };
7769
7770 static struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = {
7771 /* HP */
7772 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7773 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7774 /* Subwoofer */
7775 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7776 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7777
7778 /* enable unsolicited event */
7779 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7780
7781 { } /* end */
7782 };
7783
7784 static struct hda_verb alc883_tagra_verbs[] = {
7785 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7786 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7787
7788 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7789 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7790
7791 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
7792 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
7793 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
7794
7795 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7796 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
7797 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
7798 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
7799
7800 { } /* end */
7801 };
7802
7803 static struct hda_verb alc883_lenovo_101e_verbs[] = {
7804 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7805 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
7806 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
7807 { } /* end */
7808 };
7809
7810 static struct hda_verb alc883_lenovo_nb0763_verbs[] = {
7811 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7812 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7813 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7814 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7815 { } /* end */
7816 };
7817
7818 static struct hda_verb alc888_lenovo_ms7195_verbs[] = {
7819 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7820 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7821 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7822 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
7823 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7824 { } /* end */
7825 };
7826
7827 static struct hda_verb alc883_haier_w66_verbs[] = {
7828 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7829 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7830
7831 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7832
7833 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
7834 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7835 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7836 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7837 { } /* end */
7838 };
7839
7840 static struct hda_verb alc888_lenovo_sky_verbs[] = {
7841 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7842 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7843 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7844 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7845 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7846 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7847 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
7848 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7849 { } /* end */
7850 };
7851
7852 static struct hda_verb alc888_3st_hp_verbs[] = {
7853 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
7854 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */
7855 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */
7856 { }
7857 };
7858
7859 static struct hda_verb alc888_6st_dell_verbs[] = {
7860 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7861 { }
7862 };
7863
7864 static struct hda_verb alc888_3st_hp_2ch_init[] = {
7865 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7866 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7867 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7868 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7869 { }
7870 };
7871
7872 static struct hda_verb alc888_3st_hp_6ch_init[] = {
7873 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7874 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7875 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7876 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7877 { }
7878 };
7879
7880 static struct hda_channel_mode alc888_3st_hp_modes[2] = {
7881 { 2, alc888_3st_hp_2ch_init },
7882 { 6, alc888_3st_hp_6ch_init },
7883 };
7884
7885 /* toggle front-jack and RCA according to the hp-jack state */
7886 static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec)
7887 {
7888 unsigned int present;
7889
7890 present = snd_hda_codec_read(codec, 0x1b, 0,
7891 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7892 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7893 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7894 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7895 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7896 }
7897
7898 /* toggle RCA according to the front-jack state */
7899 static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec)
7900 {
7901 unsigned int present;
7902
7903 present = snd_hda_codec_read(codec, 0x14, 0,
7904 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7905 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7906 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7907 }
7908
7909 static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec,
7910 unsigned int res)
7911 {
7912 if ((res >> 26) == ALC880_HP_EVENT)
7913 alc888_lenovo_ms7195_front_automute(codec);
7914 if ((res >> 26) == ALC880_FRONT_EVENT)
7915 alc888_lenovo_ms7195_rca_automute(codec);
7916 }
7917
7918 static struct hda_verb alc883_medion_md2_verbs[] = {
7919 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7920 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7921
7922 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7923
7924 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7925 { } /* end */
7926 };
7927
7928 /* toggle speaker-output according to the hp-jack state */
7929 static void alc883_medion_md2_automute(struct hda_codec *codec)
7930 {
7931 unsigned int present;
7932
7933 present = snd_hda_codec_read(codec, 0x14, 0,
7934 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7935 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7936 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7937 }
7938
7939 static void alc883_medion_md2_unsol_event(struct hda_codec *codec,
7940 unsigned int res)
7941 {
7942 if ((res >> 26) == ALC880_HP_EVENT)
7943 alc883_medion_md2_automute(codec);
7944 }
7945
7946 /* toggle speaker-output according to the hp-jack state */
7947 static void alc883_tagra_automute(struct hda_codec *codec)
7948 {
7949 unsigned int present;
7950 unsigned char bits;
7951
7952 present = snd_hda_codec_read(codec, 0x14, 0,
7953 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7954 bits = present ? HDA_AMP_MUTE : 0;
7955 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
7956 HDA_AMP_MUTE, bits);
7957 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
7958 present ? 1 : 3);
7959 }
7960
7961 static void alc883_tagra_unsol_event(struct hda_codec *codec, unsigned int res)
7962 {
7963 if ((res >> 26) == ALC880_HP_EVENT)
7964 alc883_tagra_automute(codec);
7965 }
7966
7967 /* toggle speaker-output according to the hp-jack state */
7968 static void alc883_clevo_m720_hp_automute(struct hda_codec *codec)
7969 {
7970 unsigned int present;
7971 unsigned char bits;
7972
7973 present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0)
7974 & AC_PINSENSE_PRESENCE;
7975 bits = present ? HDA_AMP_MUTE : 0;
7976 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7977 HDA_AMP_MUTE, bits);
7978 }
7979
7980 static void alc883_clevo_m720_mic_automute(struct hda_codec *codec)
7981 {
7982 unsigned int present;
7983
7984 present = snd_hda_codec_read(codec, 0x18, 0,
7985 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7986 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
7987 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7988 }
7989
7990 static void alc883_clevo_m720_automute(struct hda_codec *codec)
7991 {
7992 alc883_clevo_m720_hp_automute(codec);
7993 alc883_clevo_m720_mic_automute(codec);
7994 }
7995
7996 static void alc883_clevo_m720_unsol_event(struct hda_codec *codec,
7997 unsigned int res)
7998 {
7999 switch (res >> 26) {
8000 case ALC880_HP_EVENT:
8001 alc883_clevo_m720_hp_automute(codec);
8002 break;
8003 case ALC880_MIC_EVENT:
8004 alc883_clevo_m720_mic_automute(codec);
8005 break;
8006 }
8007 }
8008
8009 /* toggle speaker-output according to the hp-jack state */
8010 static void alc883_2ch_fujitsu_pi2515_automute(struct hda_codec *codec)
8011 {
8012 unsigned int present;
8013 unsigned char bits;
8014
8015 present = snd_hda_codec_read(codec, 0x14, 0, AC_VERB_GET_PIN_SENSE, 0)
8016 & AC_PINSENSE_PRESENCE;
8017 bits = present ? HDA_AMP_MUTE : 0;
8018 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8019 HDA_AMP_MUTE, bits);
8020 }
8021
8022 static void alc883_2ch_fujitsu_pi2515_unsol_event(struct hda_codec *codec,
8023 unsigned int res)
8024 {
8025 if ((res >> 26) == ALC880_HP_EVENT)
8026 alc883_2ch_fujitsu_pi2515_automute(codec);
8027 }
8028
8029 static void alc883_haier_w66_automute(struct hda_codec *codec)
8030 {
8031 unsigned int present;
8032 unsigned char bits;
8033
8034 present = snd_hda_codec_read(codec, 0x1b, 0,
8035 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8036 bits = present ? 0x80 : 0;
8037 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8038 0x80, bits);
8039 }
8040
8041 static void alc883_haier_w66_unsol_event(struct hda_codec *codec,
8042 unsigned int res)
8043 {
8044 if ((res >> 26) == ALC880_HP_EVENT)
8045 alc883_haier_w66_automute(codec);
8046 }
8047
8048 static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
8049 {
8050 unsigned int present;
8051 unsigned char bits;
8052
8053 present = snd_hda_codec_read(codec, 0x14, 0,
8054 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8055 bits = present ? HDA_AMP_MUTE : 0;
8056 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8057 HDA_AMP_MUTE, bits);
8058 }
8059
8060 static void alc883_lenovo_101e_all_automute(struct hda_codec *codec)
8061 {
8062 unsigned int present;
8063 unsigned char bits;
8064
8065 present = snd_hda_codec_read(codec, 0x1b, 0,
8066 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8067 bits = present ? HDA_AMP_MUTE : 0;
8068 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8069 HDA_AMP_MUTE, bits);
8070 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8071 HDA_AMP_MUTE, bits);
8072 }
8073
8074 static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec,
8075 unsigned int res)
8076 {
8077 if ((res >> 26) == ALC880_HP_EVENT)
8078 alc883_lenovo_101e_all_automute(codec);
8079 if ((res >> 26) == ALC880_FRONT_EVENT)
8080 alc883_lenovo_101e_ispeaker_automute(codec);
8081 }
8082
8083 /* toggle speaker-output according to the hp-jack state */
8084 static void alc883_acer_aspire_automute(struct hda_codec *codec)
8085 {
8086 unsigned int present;
8087
8088 present = snd_hda_codec_read(codec, 0x14, 0,
8089 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8090 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8091 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8092 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
8093 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8094 }
8095
8096 static void alc883_acer_aspire_unsol_event(struct hda_codec *codec,
8097 unsigned int res)
8098 {
8099 if ((res >> 26) == ALC880_HP_EVENT)
8100 alc883_acer_aspire_automute(codec);
8101 }
8102
8103 static struct hda_verb alc883_acer_eapd_verbs[] = {
8104 /* HP Pin: output 0 (0x0c) */
8105 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8106 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8107 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8108 /* Front Pin: output 0 (0x0c) */
8109 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8110 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8111 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8112 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
8113 /* eanable EAPD on medion laptop */
8114 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8115 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
8116 /* enable unsolicited event */
8117 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8118 { }
8119 };
8120
8121 static void alc888_6st_dell_front_automute(struct hda_codec *codec)
8122 {
8123 unsigned int present;
8124
8125 present = snd_hda_codec_read(codec, 0x1b, 0,
8126 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8127 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8128 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8129 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8130 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8131 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
8132 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8133 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
8134 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8135 }
8136
8137 static void alc888_6st_dell_unsol_event(struct hda_codec *codec,
8138 unsigned int res)
8139 {
8140 switch (res >> 26) {
8141 case ALC880_HP_EVENT:
8142 printk("hp_event\n");
8143 alc888_6st_dell_front_automute(codec);
8144 break;
8145 }
8146 }
8147
8148 static void alc888_lenovo_sky_front_automute(struct hda_codec *codec)
8149 {
8150 unsigned int mute;
8151 unsigned int present;
8152
8153 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
8154 present = snd_hda_codec_read(codec, 0x1b, 0,
8155 AC_VERB_GET_PIN_SENSE, 0);
8156 present = (present & 0x80000000) != 0;
8157 if (present) {
8158 /* mute internal speaker */
8159 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8160 HDA_AMP_MUTE, HDA_AMP_MUTE);
8161 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8162 HDA_AMP_MUTE, HDA_AMP_MUTE);
8163 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
8164 HDA_AMP_MUTE, HDA_AMP_MUTE);
8165 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
8166 HDA_AMP_MUTE, HDA_AMP_MUTE);
8167 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
8168 HDA_AMP_MUTE, HDA_AMP_MUTE);
8169 } else {
8170 /* unmute internal speaker if necessary */
8171 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
8172 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
8173 HDA_AMP_MUTE, mute);
8174 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8175 HDA_AMP_MUTE, mute);
8176 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
8177 HDA_AMP_MUTE, mute);
8178 snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
8179 HDA_AMP_MUTE, mute);
8180 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
8181 HDA_AMP_MUTE, mute);
8182 }
8183 }
8184
8185 static void alc883_lenovo_sky_unsol_event(struct hda_codec *codec,
8186 unsigned int res)
8187 {
8188 if ((res >> 26) == ALC880_HP_EVENT)
8189 alc888_lenovo_sky_front_automute(codec);
8190 }
8191
8192 /*
8193 * generic initialization of ADC, input mixers and output mixers
8194 */
8195 static struct hda_verb alc883_auto_init_verbs[] = {
8196 /*
8197 * Unmute ADC0-2 and set the default input to mic-in
8198 */
8199 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8200 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8201 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8202 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8203
8204 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
8205 * mixer widget
8206 * Note: PASD motherboards uses the Line In 2 as the input for
8207 * front panel mic (mic 2)
8208 */
8209 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
8210 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8211 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8212 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8213 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8214 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8215
8216 /*
8217 * Set up output mixers (0x0c - 0x0f)
8218 */
8219 /* set vol=0 to output mixers */
8220 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8221 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8222 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8223 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8224 /* set up input amps for analog loopback */
8225 /* Amp Indices: DAC = 0, mixer = 1 */
8226 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8227 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8228 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8229 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8230 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8231 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8232 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8233 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8234 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8235 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8236
8237 /* FIXME: use matrix-type input source selection */
8238 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8239 /* Input mixer1 */
8240 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8241 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8242 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8243 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
8244 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
8245 /* Input mixer2 */
8246 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8247 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8248 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8249 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
8250 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
8251
8252 { }
8253 };
8254
8255 /* capture mixer elements */
8256 static struct snd_kcontrol_new alc883_capture_mixer[] = {
8257 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
8258 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
8259 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
8260 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
8261 {
8262 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8263 /* The multiple "Capture Source" controls confuse alsamixer
8264 * So call somewhat different..
8265 */
8266 /* .name = "Capture Source", */
8267 .name = "Input Source",
8268 .count = 2,
8269 .info = alc882_mux_enum_info,
8270 .get = alc882_mux_enum_get,
8271 .put = alc882_mux_enum_put,
8272 },
8273 { } /* end */
8274 };
8275
8276 static struct hda_verb alc888_asus_m90v_verbs[] = {
8277 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8278 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8279 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8280 /* enable unsolicited event */
8281 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8282 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
8283 { } /* end */
8284 };
8285
8286 static void alc883_nb_mic_automute(struct hda_codec *codec)
8287 {
8288 unsigned int present;
8289
8290 present = snd_hda_codec_read(codec, 0x18, 0,
8291 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8292 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
8293 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
8294 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
8295 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
8296 }
8297
8298 static void alc883_M90V_speaker_automute(struct hda_codec *codec)
8299 {
8300 unsigned int present;
8301 unsigned char bits;
8302
8303 present = snd_hda_codec_read(codec, 0x1b, 0,
8304 AC_VERB_GET_PIN_SENSE, 0)
8305 & AC_PINSENSE_PRESENCE;
8306 bits = present ? 0 : PIN_OUT;
8307 snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
8308 bits);
8309 snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
8310 bits);
8311 snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
8312 bits);
8313 }
8314
8315 static void alc883_mode2_unsol_event(struct hda_codec *codec,
8316 unsigned int res)
8317 {
8318 switch (res >> 26) {
8319 case ALC880_HP_EVENT:
8320 alc883_M90V_speaker_automute(codec);
8321 break;
8322 case ALC880_MIC_EVENT:
8323 alc883_nb_mic_automute(codec);
8324 break;
8325 }
8326 }
8327
8328 static void alc883_mode2_inithook(struct hda_codec *codec)
8329 {
8330 alc883_M90V_speaker_automute(codec);
8331 alc883_nb_mic_automute(codec);
8332 }
8333
8334 static struct hda_verb alc888_asus_eee1601_verbs[] = {
8335 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8336 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8337 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8338 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8339 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8340 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
8341 {0x20, AC_VERB_SET_PROC_COEF, 0x0838},
8342 /* enable unsolicited event */
8343 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8344 { } /* end */
8345 };
8346
8347 static void alc883_eee1601_speaker_automute(struct hda_codec *codec)
8348 {
8349 unsigned int present;
8350 unsigned char bits;
8351
8352 present = snd_hda_codec_read(codec, 0x14, 0,
8353 AC_VERB_GET_PIN_SENSE, 0)
8354 & AC_PINSENSE_PRESENCE;
8355 bits = present ? 0 : PIN_OUT;
8356 snd_hda_codec_write(codec, 0x1b, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
8357 bits);
8358 }
8359
8360 static void alc883_eee1601_unsol_event(struct hda_codec *codec,
8361 unsigned int res)
8362 {
8363 switch (res >> 26) {
8364 case ALC880_HP_EVENT:
8365 alc883_eee1601_speaker_automute(codec);
8366 break;
8367 }
8368 }
8369
8370 static void alc883_eee1601_inithook(struct hda_codec *codec)
8371 {
8372 alc883_eee1601_speaker_automute(codec);
8373 }
8374
8375 #ifdef CONFIG_SND_HDA_POWER_SAVE
8376 #define alc883_loopbacks alc880_loopbacks
8377 #endif
8378
8379 /* pcm configuration: identiacal with ALC880 */
8380 #define alc883_pcm_analog_playback alc880_pcm_analog_playback
8381 #define alc883_pcm_analog_capture alc880_pcm_analog_capture
8382 #define alc883_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
8383 #define alc883_pcm_digital_playback alc880_pcm_digital_playback
8384 #define alc883_pcm_digital_capture alc880_pcm_digital_capture
8385
8386 /*
8387 * configuration and preset
8388 */
8389 static const char *alc883_models[ALC883_MODEL_LAST] = {
8390 [ALC883_3ST_2ch_DIG] = "3stack-dig",
8391 [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig",
8392 [ALC883_3ST_6ch] = "3stack-6ch",
8393 [ALC883_6ST_DIG] = "6stack-dig",
8394 [ALC883_TARGA_DIG] = "targa-dig",
8395 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig",
8396 [ALC883_ACER] = "acer",
8397 [ALC883_ACER_ASPIRE] = "acer-aspire",
8398 [ALC883_MEDION] = "medion",
8399 [ALC883_MEDION_MD2] = "medion-md2",
8400 [ALC883_LAPTOP_EAPD] = "laptop-eapd",
8401 [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
8402 [ALC883_LENOVO_NB0763] = "lenovo-nb0763",
8403 [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
8404 [ALC888_LENOVO_SKY] = "lenovo-sky",
8405 [ALC883_HAIER_W66] = "haier-w66",
8406 [ALC888_3ST_HP] = "3stack-hp",
8407 [ALC888_6ST_DELL] = "6stack-dell",
8408 [ALC883_MITAC] = "mitac",
8409 [ALC883_CLEVO_M720] = "clevo-m720",
8410 [ALC883_FUJITSU_PI2515] = "fujitsu-pi2515",
8411 [ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel",
8412 [ALC883_AUTO] = "auto",
8413 };
8414
8415 static struct snd_pci_quirk alc883_cfg_tbl[] = {
8416 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC883_3ST_6ch_DIG),
8417 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
8418 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
8419 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
8420 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE),
8421 SND_PCI_QUIRK(0x1025, 0, "Acer laptop", ALC883_ACER), /* default Acer */
8422 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
8423 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
8424 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
8425 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
8426 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG),
8427 SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V),
8428 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
8429 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601),
8430 SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG),
8431 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC883_6ST_DIG),
8432 SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
8433 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
8434 SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL),
8435 SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
8436 SND_PCI_QUIRK(0x1458, 0xa002, "MSI", ALC883_6ST_DIG),
8437 SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
8438 SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
8439 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
8440 SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC883_TARGA_2ch_DIG),
8441 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
8442 SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG),
8443 SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
8444 SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
8445 SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
8446 SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
8447 SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
8448 SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
8449 SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
8450 SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
8451 SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
8452 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
8453 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
8454 SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
8455 SND_PCI_QUIRK(0x1462, 0x7267, "MSI", ALC883_3ST_6ch_DIG),
8456 SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
8457 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
8458 SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
8459 SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
8460 SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720),
8461 SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720),
8462 SND_PCI_QUIRK(0x1558, 0, "Clevo laptop", ALC883_LAPTOP_EAPD),
8463 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
8464 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
8465 SND_PCI_QUIRK(0x1734, 0x1108, "Fujitsu AMILO Pi2515", ALC883_FUJITSU_PI2515),
8466 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
8467 SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
8468 SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
8469 SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
8470 SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY),
8471 SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2),
8472 SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
8473 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
8474 SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL),
8475 SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL),
8476 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch),
8477 {}
8478 };
8479
8480 static struct alc_config_preset alc883_presets[] = {
8481 [ALC883_3ST_2ch_DIG] = {
8482 .mixers = { alc883_3ST_2ch_mixer },
8483 .init_verbs = { alc883_init_verbs },
8484 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8485 .dac_nids = alc883_dac_nids,
8486 .dig_out_nid = ALC883_DIGOUT_NID,
8487 .dig_in_nid = ALC883_DIGIN_NID,
8488 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8489 .channel_mode = alc883_3ST_2ch_modes,
8490 .input_mux = &alc883_capture_source,
8491 },
8492 [ALC883_3ST_6ch_DIG] = {
8493 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8494 .init_verbs = { alc883_init_verbs },
8495 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8496 .dac_nids = alc883_dac_nids,
8497 .dig_out_nid = ALC883_DIGOUT_NID,
8498 .dig_in_nid = ALC883_DIGIN_NID,
8499 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8500 .channel_mode = alc883_3ST_6ch_modes,
8501 .need_dac_fix = 1,
8502 .input_mux = &alc883_capture_source,
8503 },
8504 [ALC883_3ST_6ch] = {
8505 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8506 .init_verbs = { alc883_init_verbs },
8507 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8508 .dac_nids = alc883_dac_nids,
8509 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8510 .channel_mode = alc883_3ST_6ch_modes,
8511 .need_dac_fix = 1,
8512 .input_mux = &alc883_capture_source,
8513 },
8514 [ALC883_3ST_6ch_INTEL] = {
8515 .mixers = { alc883_3ST_6ch_intel_mixer, alc883_chmode_mixer },
8516 .init_verbs = { alc883_init_verbs },
8517 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8518 .dac_nids = alc883_dac_nids,
8519 .dig_out_nid = ALC883_DIGOUT_NID,
8520 .dig_in_nid = ALC883_DIGIN_NID,
8521 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes),
8522 .channel_mode = alc883_3ST_6ch_intel_modes,
8523 .need_dac_fix = 1,
8524 .input_mux = &alc883_3stack_6ch_intel,
8525 },
8526 [ALC883_6ST_DIG] = {
8527 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
8528 .init_verbs = { alc883_init_verbs },
8529 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8530 .dac_nids = alc883_dac_nids,
8531 .dig_out_nid = ALC883_DIGOUT_NID,
8532 .dig_in_nid = ALC883_DIGIN_NID,
8533 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8534 .channel_mode = alc883_sixstack_modes,
8535 .input_mux = &alc883_capture_source,
8536 },
8537 [ALC883_TARGA_DIG] = {
8538 .mixers = { alc883_tagra_mixer, alc883_chmode_mixer },
8539 .init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
8540 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8541 .dac_nids = alc883_dac_nids,
8542 .dig_out_nid = ALC883_DIGOUT_NID,
8543 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8544 .channel_mode = alc883_3ST_6ch_modes,
8545 .need_dac_fix = 1,
8546 .input_mux = &alc883_capture_source,
8547 .unsol_event = alc883_tagra_unsol_event,
8548 .init_hook = alc883_tagra_automute,
8549 },
8550 [ALC883_TARGA_2ch_DIG] = {
8551 .mixers = { alc883_tagra_2ch_mixer},
8552 .init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
8553 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8554 .dac_nids = alc883_dac_nids,
8555 .dig_out_nid = ALC883_DIGOUT_NID,
8556 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8557 .channel_mode = alc883_3ST_2ch_modes,
8558 .input_mux = &alc883_capture_source,
8559 .unsol_event = alc883_tagra_unsol_event,
8560 .init_hook = alc883_tagra_automute,
8561 },
8562 [ALC883_ACER] = {
8563 .mixers = { alc883_base_mixer },
8564 /* On TravelMate laptops, GPIO 0 enables the internal speaker
8565 * and the headphone jack. Turn this on and rely on the
8566 * standard mute methods whenever the user wants to turn
8567 * these outputs off.
8568 */
8569 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
8570 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8571 .dac_nids = alc883_dac_nids,
8572 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8573 .channel_mode = alc883_3ST_2ch_modes,
8574 .input_mux = &alc883_capture_source,
8575 },
8576 [ALC883_ACER_ASPIRE] = {
8577 .mixers = { alc883_acer_aspire_mixer },
8578 .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
8579 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8580 .dac_nids = alc883_dac_nids,
8581 .dig_out_nid = ALC883_DIGOUT_NID,
8582 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8583 .channel_mode = alc883_3ST_2ch_modes,
8584 .input_mux = &alc883_capture_source,
8585 .unsol_event = alc883_acer_aspire_unsol_event,
8586 .init_hook = alc883_acer_aspire_automute,
8587 },
8588 [ALC883_MEDION] = {
8589 .mixers = { alc883_fivestack_mixer,
8590 alc883_chmode_mixer },
8591 .init_verbs = { alc883_init_verbs,
8592 alc883_medion_eapd_verbs },
8593 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8594 .dac_nids = alc883_dac_nids,
8595 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8596 .channel_mode = alc883_sixstack_modes,
8597 .input_mux = &alc883_capture_source,
8598 },
8599 [ALC883_MEDION_MD2] = {
8600 .mixers = { alc883_medion_md2_mixer},
8601 .init_verbs = { alc883_init_verbs, alc883_medion_md2_verbs},
8602 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8603 .dac_nids = alc883_dac_nids,
8604 .dig_out_nid = ALC883_DIGOUT_NID,
8605 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8606 .channel_mode = alc883_3ST_2ch_modes,
8607 .input_mux = &alc883_capture_source,
8608 .unsol_event = alc883_medion_md2_unsol_event,
8609 .init_hook = alc883_medion_md2_automute,
8610 },
8611 [ALC883_LAPTOP_EAPD] = {
8612 .mixers = { alc883_base_mixer },
8613 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
8614 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8615 .dac_nids = alc883_dac_nids,
8616 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8617 .channel_mode = alc883_3ST_2ch_modes,
8618 .input_mux = &alc883_capture_source,
8619 },
8620 [ALC883_CLEVO_M720] = {
8621 .mixers = { alc883_clevo_m720_mixer },
8622 .init_verbs = { alc883_init_verbs, alc883_clevo_m720_verbs },
8623 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8624 .dac_nids = alc883_dac_nids,
8625 .dig_out_nid = ALC883_DIGOUT_NID,
8626 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8627 .channel_mode = alc883_3ST_2ch_modes,
8628 .input_mux = &alc883_capture_source,
8629 .unsol_event = alc883_clevo_m720_unsol_event,
8630 .init_hook = alc883_clevo_m720_automute,
8631 },
8632 [ALC883_LENOVO_101E_2ch] = {
8633 .mixers = { alc883_lenovo_101e_2ch_mixer},
8634 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
8635 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8636 .dac_nids = alc883_dac_nids,
8637 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8638 .channel_mode = alc883_3ST_2ch_modes,
8639 .input_mux = &alc883_lenovo_101e_capture_source,
8640 .unsol_event = alc883_lenovo_101e_unsol_event,
8641 .init_hook = alc883_lenovo_101e_all_automute,
8642 },
8643 [ALC883_LENOVO_NB0763] = {
8644 .mixers = { alc883_lenovo_nb0763_mixer },
8645 .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
8646 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8647 .dac_nids = alc883_dac_nids,
8648 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8649 .channel_mode = alc883_3ST_2ch_modes,
8650 .need_dac_fix = 1,
8651 .input_mux = &alc883_lenovo_nb0763_capture_source,
8652 .unsol_event = alc883_medion_md2_unsol_event,
8653 .init_hook = alc883_medion_md2_automute,
8654 },
8655 [ALC888_LENOVO_MS7195_DIG] = {
8656 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8657 .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
8658 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8659 .dac_nids = alc883_dac_nids,
8660 .dig_out_nid = ALC883_DIGOUT_NID,
8661 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8662 .channel_mode = alc883_3ST_6ch_modes,
8663 .need_dac_fix = 1,
8664 .input_mux = &alc883_capture_source,
8665 .unsol_event = alc883_lenovo_ms7195_unsol_event,
8666 .init_hook = alc888_lenovo_ms7195_front_automute,
8667 },
8668 [ALC883_HAIER_W66] = {
8669 .mixers = { alc883_tagra_2ch_mixer},
8670 .init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs},
8671 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8672 .dac_nids = alc883_dac_nids,
8673 .dig_out_nid = ALC883_DIGOUT_NID,
8674 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8675 .channel_mode = alc883_3ST_2ch_modes,
8676 .input_mux = &alc883_capture_source,
8677 .unsol_event = alc883_haier_w66_unsol_event,
8678 .init_hook = alc883_haier_w66_automute,
8679 },
8680 [ALC888_3ST_HP] = {
8681 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8682 .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
8683 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8684 .dac_nids = alc883_dac_nids,
8685 .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
8686 .channel_mode = alc888_3st_hp_modes,
8687 .need_dac_fix = 1,
8688 .input_mux = &alc883_capture_source,
8689 },
8690 [ALC888_6ST_DELL] = {
8691 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
8692 .init_verbs = { alc883_init_verbs, alc888_6st_dell_verbs },
8693 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8694 .dac_nids = alc883_dac_nids,
8695 .dig_out_nid = ALC883_DIGOUT_NID,
8696 .dig_in_nid = ALC883_DIGIN_NID,
8697 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8698 .channel_mode = alc883_sixstack_modes,
8699 .input_mux = &alc883_capture_source,
8700 .unsol_event = alc888_6st_dell_unsol_event,
8701 .init_hook = alc888_6st_dell_front_automute,
8702 },
8703 [ALC883_MITAC] = {
8704 .mixers = { alc883_mitac_mixer },
8705 .init_verbs = { alc883_init_verbs, alc883_mitac_verbs },
8706 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8707 .dac_nids = alc883_dac_nids,
8708 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8709 .channel_mode = alc883_3ST_2ch_modes,
8710 .input_mux = &alc883_capture_source,
8711 .unsol_event = alc883_mitac_unsol_event,
8712 .init_hook = alc883_mitac_automute,
8713 },
8714 [ALC883_FUJITSU_PI2515] = {
8715 .mixers = { alc883_2ch_fujitsu_pi2515_mixer },
8716 .init_verbs = { alc883_init_verbs,
8717 alc883_2ch_fujitsu_pi2515_verbs},
8718 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8719 .dac_nids = alc883_dac_nids,
8720 .dig_out_nid = ALC883_DIGOUT_NID,
8721 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8722 .channel_mode = alc883_3ST_2ch_modes,
8723 .input_mux = &alc883_fujitsu_pi2515_capture_source,
8724 .unsol_event = alc883_2ch_fujitsu_pi2515_unsol_event,
8725 .init_hook = alc883_2ch_fujitsu_pi2515_automute,
8726 },
8727 [ALC888_LENOVO_SKY] = {
8728 .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer },
8729 .init_verbs = { alc883_init_verbs, alc888_lenovo_sky_verbs},
8730 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8731 .dac_nids = alc883_dac_nids,
8732 .dig_out_nid = ALC883_DIGOUT_NID,
8733 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
8734 .adc_nids = alc883_adc_nids,
8735 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8736 .channel_mode = alc883_sixstack_modes,
8737 .need_dac_fix = 1,
8738 .input_mux = &alc883_lenovo_sky_capture_source,
8739 .unsol_event = alc883_lenovo_sky_unsol_event,
8740 .init_hook = alc888_lenovo_sky_front_automute,
8741 },
8742 [ALC888_ASUS_M90V] = {
8743 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
8744 .init_verbs = { alc883_init_verbs, alc888_asus_m90v_verbs },
8745 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8746 .dac_nids = alc883_dac_nids,
8747 .dig_out_nid = ALC883_DIGOUT_NID,
8748 .dig_in_nid = ALC883_DIGIN_NID,
8749 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8750 .channel_mode = alc883_3ST_6ch_modes,
8751 .need_dac_fix = 1,
8752 .input_mux = &alc883_fujitsu_pi2515_capture_source,
8753 .unsol_event = alc883_mode2_unsol_event,
8754 .init_hook = alc883_mode2_inithook,
8755 },
8756 [ALC888_ASUS_EEE1601] = {
8757 .mixers = { alc883_asus_eee1601_mixer },
8758 .init_verbs = { alc883_init_verbs, alc888_asus_eee1601_verbs },
8759 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8760 .dac_nids = alc883_dac_nids,
8761 .dig_out_nid = ALC883_DIGOUT_NID,
8762 .dig_in_nid = ALC883_DIGIN_NID,
8763 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8764 .channel_mode = alc883_3ST_2ch_modes,
8765 .need_dac_fix = 1,
8766 .input_mux = &alc883_asus_eee1601_capture_source,
8767 .unsol_event = alc883_eee1601_unsol_event,
8768 .init_hook = alc883_eee1601_inithook,
8769 },
8770 };
8771
8772
8773 /*
8774 * BIOS auto configuration
8775 */
8776 static void alc883_auto_set_output_and_unmute(struct hda_codec *codec,
8777 hda_nid_t nid, int pin_type,
8778 int dac_idx)
8779 {
8780 /* set as output */
8781 struct alc_spec *spec = codec->spec;
8782 int idx;
8783
8784 alc_set_pin_output(codec, nid, pin_type);
8785 if (spec->multiout.dac_nids[dac_idx] == 0x25)
8786 idx = 4;
8787 else
8788 idx = spec->multiout.dac_nids[dac_idx] - 2;
8789 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
8790
8791 }
8792
8793 static void alc883_auto_init_multi_out(struct hda_codec *codec)
8794 {
8795 struct alc_spec *spec = codec->spec;
8796 int i;
8797
8798 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
8799 for (i = 0; i <= HDA_SIDE; i++) {
8800 hda_nid_t nid = spec->autocfg.line_out_pins[i];
8801 int pin_type = get_pin_type(spec->autocfg.line_out_type);
8802 if (nid)
8803 alc883_auto_set_output_and_unmute(codec, nid, pin_type,
8804 i);
8805 }
8806 }
8807
8808 static void alc883_auto_init_hp_out(struct hda_codec *codec)
8809 {
8810 struct alc_spec *spec = codec->spec;
8811 hda_nid_t pin;
8812
8813 pin = spec->autocfg.hp_pins[0];
8814 if (pin) /* connect to front */
8815 /* use dac 0 */
8816 alc883_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
8817 pin = spec->autocfg.speaker_pins[0];
8818 if (pin)
8819 alc883_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
8820 }
8821
8822 #define alc883_is_input_pin(nid) alc880_is_input_pin(nid)
8823 #define ALC883_PIN_CD_NID ALC880_PIN_CD_NID
8824
8825 static void alc883_auto_init_analog_input(struct hda_codec *codec)
8826 {
8827 struct alc_spec *spec = codec->spec;
8828 int i;
8829
8830 for (i = 0; i < AUTO_PIN_LAST; i++) {
8831 hda_nid_t nid = spec->autocfg.input_pins[i];
8832 if (alc883_is_input_pin(nid)) {
8833 snd_hda_codec_write(codec, nid, 0,
8834 AC_VERB_SET_PIN_WIDGET_CONTROL,
8835 (i <= AUTO_PIN_FRONT_MIC ?
8836 PIN_VREF80 : PIN_IN));
8837 if (nid != ALC883_PIN_CD_NID)
8838 snd_hda_codec_write(codec, nid, 0,
8839 AC_VERB_SET_AMP_GAIN_MUTE,
8840 AMP_OUT_MUTE);
8841 }
8842 }
8843 }
8844
8845 #define alc883_auto_init_input_src alc882_auto_init_input_src
8846
8847 /* almost identical with ALC880 parser... */
8848 static int alc883_parse_auto_config(struct hda_codec *codec)
8849 {
8850 struct alc_spec *spec = codec->spec;
8851 int err = alc880_parse_auto_config(codec);
8852
8853 if (err < 0)
8854 return err;
8855 else if (!err)
8856 return 0; /* no config found */
8857
8858 err = alc_auto_add_mic_boost(codec);
8859 if (err < 0)
8860 return err;
8861
8862 /* hack - override the init verbs */
8863 spec->init_verbs[0] = alc883_auto_init_verbs;
8864 add_mixer(spec, alc883_capture_mixer);
8865
8866 return 1; /* config found */
8867 }
8868
8869 /* additional initialization for auto-configuration model */
8870 static void alc883_auto_init(struct hda_codec *codec)
8871 {
8872 struct alc_spec *spec = codec->spec;
8873 alc883_auto_init_multi_out(codec);
8874 alc883_auto_init_hp_out(codec);
8875 alc883_auto_init_analog_input(codec);
8876 alc883_auto_init_input_src(codec);
8877 if (spec->unsol_event)
8878 alc_inithook(codec);
8879 }
8880
8881 static int patch_alc883(struct hda_codec *codec)
8882 {
8883 struct alc_spec *spec;
8884 int err, board_config;
8885
8886 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
8887 if (spec == NULL)
8888 return -ENOMEM;
8889
8890 codec->spec = spec;
8891
8892 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
8893
8894 board_config = snd_hda_check_board_config(codec, ALC883_MODEL_LAST,
8895 alc883_models,
8896 alc883_cfg_tbl);
8897 if (board_config < 0) {
8898 printk(KERN_INFO "hda_codec: Unknown model for ALC883, "
8899 "trying auto-probe from BIOS...\n");
8900 board_config = ALC883_AUTO;
8901 }
8902
8903 if (board_config == ALC883_AUTO) {
8904 /* automatic parse from the BIOS config */
8905 err = alc883_parse_auto_config(codec);
8906 if (err < 0) {
8907 alc_free(codec);
8908 return err;
8909 } else if (!err) {
8910 printk(KERN_INFO
8911 "hda_codec: Cannot set up configuration "
8912 "from BIOS. Using base mode...\n");
8913 board_config = ALC883_3ST_2ch_DIG;
8914 }
8915 }
8916
8917 if (board_config != ALC883_AUTO)
8918 setup_preset(spec, &alc883_presets[board_config]);
8919
8920 switch (codec->vendor_id) {
8921 case 0x10ec0888:
8922 if (codec->revision_id == 0x100101) {
8923 spec->stream_name_analog = "ALC1200 Analog";
8924 spec->stream_name_digital = "ALC1200 Digital";
8925 } else {
8926 spec->stream_name_analog = "ALC888 Analog";
8927 spec->stream_name_digital = "ALC888 Digital";
8928 }
8929 break;
8930 case 0x10ec0889:
8931 spec->stream_name_analog = "ALC889 Analog";
8932 spec->stream_name_digital = "ALC889 Digital";
8933 break;
8934 default:
8935 spec->stream_name_analog = "ALC883 Analog";
8936 spec->stream_name_digital = "ALC883 Digital";
8937 break;
8938 }
8939
8940 spec->stream_analog_playback = &alc883_pcm_analog_playback;
8941 spec->stream_analog_capture = &alc883_pcm_analog_capture;
8942 spec->stream_analog_alt_capture = &alc883_pcm_analog_alt_capture;
8943
8944 spec->stream_digital_playback = &alc883_pcm_digital_playback;
8945 spec->stream_digital_capture = &alc883_pcm_digital_capture;
8946
8947 spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids);
8948 spec->adc_nids = alc883_adc_nids;
8949 spec->capsrc_nids = alc883_capsrc_nids;
8950
8951 spec->vmaster_nid = 0x0c;
8952
8953 codec->patch_ops = alc_patch_ops;
8954 if (board_config == ALC883_AUTO)
8955 spec->init_hook = alc883_auto_init;
8956
8957 #ifdef CONFIG_SND_HDA_POWER_SAVE
8958 if (!spec->loopback.amplist)
8959 spec->loopback.amplist = alc883_loopbacks;
8960 #endif
8961
8962 return 0;
8963 }
8964
8965 /*
8966 * ALC262 support
8967 */
8968
8969 #define ALC262_DIGOUT_NID ALC880_DIGOUT_NID
8970 #define ALC262_DIGIN_NID ALC880_DIGIN_NID
8971
8972 #define alc262_dac_nids alc260_dac_nids
8973 #define alc262_adc_nids alc882_adc_nids
8974 #define alc262_adc_nids_alt alc882_adc_nids_alt
8975 #define alc262_capsrc_nids alc882_capsrc_nids
8976 #define alc262_capsrc_nids_alt alc882_capsrc_nids_alt
8977
8978 #define alc262_modes alc260_modes
8979 #define alc262_capture_source alc882_capture_source
8980
8981 static hda_nid_t alc262_dmic_adc_nids[1] = {
8982 /* ADC0 */
8983 0x09
8984 };
8985
8986 static hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 };
8987
8988 static struct snd_kcontrol_new alc262_base_mixer[] = {
8989 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8990 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8991 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8992 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8993 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8994 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8995 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8996 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8997 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8998 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8999 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9000 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9001 /* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
9002 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT), */
9003 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
9004 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9005 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9006 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
9007 { } /* end */
9008 };
9009
9010 static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
9011 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9012 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9013 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9014 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9015 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9016 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9017 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9018 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9019 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9020 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9021 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9022 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9023 /* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
9024 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT), */
9025 /*HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),*/
9026 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9027 { } /* end */
9028 };
9029
9030 /* update HP, line and mono-out pins according to the master switch */
9031 static void alc262_hp_master_update(struct hda_codec *codec)
9032 {
9033 struct alc_spec *spec = codec->spec;
9034 int val = spec->master_sw;
9035
9036 /* HP & line-out */
9037 snd_hda_codec_write_cache(codec, 0x1b, 0,
9038 AC_VERB_SET_PIN_WIDGET_CONTROL,
9039 val ? PIN_HP : 0);
9040 snd_hda_codec_write_cache(codec, 0x15, 0,
9041 AC_VERB_SET_PIN_WIDGET_CONTROL,
9042 val ? PIN_HP : 0);
9043 /* mono (speaker) depending on the HP jack sense */
9044 val = val && !spec->jack_present;
9045 snd_hda_codec_write_cache(codec, 0x16, 0,
9046 AC_VERB_SET_PIN_WIDGET_CONTROL,
9047 val ? PIN_OUT : 0);
9048 }
9049
9050 static void alc262_hp_bpc_automute(struct hda_codec *codec)
9051 {
9052 struct alc_spec *spec = codec->spec;
9053 unsigned int presence;
9054 presence = snd_hda_codec_read(codec, 0x1b, 0,
9055 AC_VERB_GET_PIN_SENSE, 0);
9056 spec->jack_present = !!(presence & AC_PINSENSE_PRESENCE);
9057 alc262_hp_master_update(codec);
9058 }
9059
9060 static void alc262_hp_bpc_unsol_event(struct hda_codec *codec, unsigned int res)
9061 {
9062 if ((res >> 26) != ALC880_HP_EVENT)
9063 return;
9064 alc262_hp_bpc_automute(codec);
9065 }
9066
9067 static void alc262_hp_wildwest_automute(struct hda_codec *codec)
9068 {
9069 struct alc_spec *spec = codec->spec;
9070 unsigned int presence;
9071 presence = snd_hda_codec_read(codec, 0x15, 0,
9072 AC_VERB_GET_PIN_SENSE, 0);
9073 spec->jack_present = !!(presence & AC_PINSENSE_PRESENCE);
9074 alc262_hp_master_update(codec);
9075 }
9076
9077 static void alc262_hp_wildwest_unsol_event(struct hda_codec *codec,
9078 unsigned int res)
9079 {
9080 if ((res >> 26) != ALC880_HP_EVENT)
9081 return;
9082 alc262_hp_wildwest_automute(codec);
9083 }
9084
9085 static int alc262_hp_master_sw_get(struct snd_kcontrol *kcontrol,
9086 struct snd_ctl_elem_value *ucontrol)
9087 {
9088 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9089 struct alc_spec *spec = codec->spec;
9090 *ucontrol->value.integer.value = spec->master_sw;
9091 return 0;
9092 }
9093
9094 static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol,
9095 struct snd_ctl_elem_value *ucontrol)
9096 {
9097 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9098 struct alc_spec *spec = codec->spec;
9099 int val = !!*ucontrol->value.integer.value;
9100
9101 if (val == spec->master_sw)
9102 return 0;
9103 spec->master_sw = val;
9104 alc262_hp_master_update(codec);
9105 return 1;
9106 }
9107
9108 static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
9109 {
9110 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9111 .name = "Master Playback Switch",
9112 .info = snd_ctl_boolean_mono_info,
9113 .get = alc262_hp_master_sw_get,
9114 .put = alc262_hp_master_sw_put,
9115 },
9116 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9117 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9118 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9119 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
9120 HDA_OUTPUT),
9121 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
9122 HDA_OUTPUT),
9123 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9124 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9125 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9126 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9127 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9128 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9129 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9130 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9131 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9132 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9133 HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
9134 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT),
9135 HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
9136 HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
9137 { } /* end */
9138 };
9139
9140 static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
9141 {
9142 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9143 .name = "Master Playback Switch",
9144 .info = snd_ctl_boolean_mono_info,
9145 .get = alc262_hp_master_sw_get,
9146 .put = alc262_hp_master_sw_put,
9147 },
9148 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9149 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9150 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9151 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9152 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
9153 HDA_OUTPUT),
9154 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
9155 HDA_OUTPUT),
9156 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
9157 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
9158 HDA_CODEC_VOLUME("Front Mic Boost", 0x1a, 0, HDA_INPUT),
9159 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
9160 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
9161 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9162 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9163 HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
9164 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT),
9165 { } /* end */
9166 };
9167
9168 static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
9169 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9170 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9171 HDA_CODEC_VOLUME("Rear Mic Boost", 0x18, 0, HDA_INPUT),
9172 { } /* end */
9173 };
9174
9175 /* mute/unmute internal speaker according to the hp jack and mute state */
9176 static void alc262_hp_t5735_automute(struct hda_codec *codec, int force)
9177 {
9178 struct alc_spec *spec = codec->spec;
9179
9180 if (force || !spec->sense_updated) {
9181 unsigned int present;
9182 present = snd_hda_codec_read(codec, 0x15, 0,
9183 AC_VERB_GET_PIN_SENSE, 0);
9184 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
9185 spec->sense_updated = 1;
9186 }
9187 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0, HDA_AMP_MUTE,
9188 spec->jack_present ? HDA_AMP_MUTE : 0);
9189 }
9190
9191 static void alc262_hp_t5735_unsol_event(struct hda_codec *codec,
9192 unsigned int res)
9193 {
9194 if ((res >> 26) != ALC880_HP_EVENT)
9195 return;
9196 alc262_hp_t5735_automute(codec, 1);
9197 }
9198
9199 static void alc262_hp_t5735_init_hook(struct hda_codec *codec)
9200 {
9201 alc262_hp_t5735_automute(codec, 1);
9202 }
9203
9204 static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
9205 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9206 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9207 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9208 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9209 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9210 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9211 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9212 { } /* end */
9213 };
9214
9215 static struct hda_verb alc262_hp_t5735_verbs[] = {
9216 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9217 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9218
9219 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9220 { }
9221 };
9222
9223 static struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = {
9224 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9225 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9226 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
9227 HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT),
9228 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
9229 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
9230 { } /* end */
9231 };
9232
9233 static struct hda_verb alc262_hp_rp5700_verbs[] = {
9234 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9235 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9236 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9237 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9238 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
9239 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9240 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
9241 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
9242 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
9243 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
9244 {}
9245 };
9246
9247 static struct hda_input_mux alc262_hp_rp5700_capture_source = {
9248 .num_items = 1,
9249 .items = {
9250 { "Line", 0x1 },
9251 },
9252 };
9253
9254 /* bind hp and internal speaker mute (with plug check) */
9255 static int alc262_sony_master_sw_put(struct snd_kcontrol *kcontrol,
9256 struct snd_ctl_elem_value *ucontrol)
9257 {
9258 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9259 long *valp = ucontrol->value.integer.value;
9260 int change;
9261
9262 /* change hp mute */
9263 change = snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
9264 HDA_AMP_MUTE,
9265 valp[0] ? 0 : HDA_AMP_MUTE);
9266 change |= snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
9267 HDA_AMP_MUTE,
9268 valp[1] ? 0 : HDA_AMP_MUTE);
9269 if (change) {
9270 /* change speaker according to HP jack state */
9271 struct alc_spec *spec = codec->spec;
9272 unsigned int mute;
9273 if (spec->jack_present)
9274 mute = HDA_AMP_MUTE;
9275 else
9276 mute = snd_hda_codec_amp_read(codec, 0x15, 0,
9277 HDA_OUTPUT, 0);
9278 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9279 HDA_AMP_MUTE, mute);
9280 }
9281 return change;
9282 }
9283
9284 static struct snd_kcontrol_new alc262_sony_mixer[] = {
9285 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9286 {
9287 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9288 .name = "Master Playback Switch",
9289 .info = snd_hda_mixer_amp_switch_info,
9290 .get = snd_hda_mixer_amp_switch_get,
9291 .put = alc262_sony_master_sw_put,
9292 .private_value = HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
9293 },
9294 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9295 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9296 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9297 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9298 { } /* end */
9299 };
9300
9301 static struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
9302 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9303 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9304 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9305 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9306 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9307 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9308 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9309 { } /* end */
9310 };
9311
9312 #define alc262_capture_mixer alc882_capture_mixer
9313 #define alc262_capture_alt_mixer alc882_capture_alt_mixer
9314
9315 /*
9316 * generic initialization of ADC, input mixers and output mixers
9317 */
9318 static struct hda_verb alc262_init_verbs[] = {
9319 /*
9320 * Unmute ADC0-2 and set the default input to mic-in
9321 */
9322 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
9323 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9324 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9325 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9326 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
9327 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9328
9329 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9330 * mixer widget
9331 * Note: PASD motherboards uses the Line In 2 as the input for
9332 * front panel mic (mic 2)
9333 */
9334 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
9335 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9336 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9337 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
9338 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
9339 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9340
9341 /*
9342 * Set up output mixers (0x0c - 0x0e)
9343 */
9344 /* set vol=0 to output mixers */
9345 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9346 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9347 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9348 /* set up input amps for analog loopback */
9349 /* Amp Indices: DAC = 0, mixer = 1 */
9350 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9351 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9352 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9353 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9354 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9355 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9356
9357 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
9358 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
9359 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
9360 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9361 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9362 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
9363
9364 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9365 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9366 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9367 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9368 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9369
9370 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9371 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
9372
9373 /* FIXME: use matrix-type input source selection */
9374 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
9375 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
9376 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9377 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9378 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9379 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9380 /* Input mixer2 */
9381 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9382 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9383 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9384 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9385 /* Input mixer3 */
9386 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
9387 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
9388 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
9389 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
9390
9391 { }
9392 };
9393
9394 static struct hda_verb alc262_eapd_verbs[] = {
9395 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
9396 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
9397 { }
9398 };
9399
9400 static struct hda_verb alc262_hippo_unsol_verbs[] = {
9401 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9402 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9403 {}
9404 };
9405
9406 static struct hda_verb alc262_hippo1_unsol_verbs[] = {
9407 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
9408 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9409 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
9410
9411 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9412 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9413 {}
9414 };
9415
9416 static struct hda_verb alc262_sony_unsol_verbs[] = {
9417 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
9418 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9419 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic
9420
9421 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9422 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9423 {}
9424 };
9425
9426 static struct hda_input_mux alc262_dmic_capture_source = {
9427 .num_items = 2,
9428 .items = {
9429 { "Int DMic", 0x9 },
9430 { "Mic", 0x0 },
9431 },
9432 };
9433
9434 static struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = {
9435 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9436 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9437 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9438 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9439 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9440 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
9441 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
9442 {
9443 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9444 /* The multiple "Capture Source" controls confuse alsamixer
9445 * So call somewhat different..
9446 */
9447 /* .name = "Capture Source", */
9448 .name = "Input Source",
9449 .count = 1,
9450 .info = alc_mux_enum_info,
9451 .get = alc_mux_enum_get,
9452 .put = alc_mux_enum_put,
9453 },
9454 { } /* end */
9455 };
9456
9457 static struct hda_verb alc262_toshiba_s06_verbs[] = {
9458 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
9459 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9460 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9461 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9462 {0x22, AC_VERB_SET_CONNECT_SEL, 0x09},
9463 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9464 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
9465 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9466 {}
9467 };
9468
9469 static void alc262_dmic_automute(struct hda_codec *codec)
9470 {
9471 unsigned int present;
9472
9473 present = snd_hda_codec_read(codec, 0x18, 0,
9474 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
9475 snd_hda_codec_write(codec, 0x22, 0,
9476 AC_VERB_SET_CONNECT_SEL, present ? 0x0 : 0x09);
9477 }
9478
9479 /* toggle speaker-output according to the hp-jack state */
9480 static void alc262_toshiba_s06_speaker_automute(struct hda_codec *codec)
9481 {
9482 unsigned int present;
9483 unsigned char bits;
9484
9485 present = snd_hda_codec_read(codec, 0x15, 0,
9486 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
9487 bits = present ? 0 : PIN_OUT;
9488 snd_hda_codec_write(codec, 0x14, 0,
9489 AC_VERB_SET_PIN_WIDGET_CONTROL, bits);
9490 }
9491
9492
9493
9494 /* unsolicited event for HP jack sensing */
9495 static void alc262_toshiba_s06_unsol_event(struct hda_codec *codec,
9496 unsigned int res)
9497 {
9498 if ((res >> 26) == ALC880_HP_EVENT)
9499 alc262_toshiba_s06_speaker_automute(codec);
9500 if ((res >> 26) == ALC880_MIC_EVENT)
9501 alc262_dmic_automute(codec);
9502
9503 }
9504
9505 static void alc262_toshiba_s06_init_hook(struct hda_codec *codec)
9506 {
9507 alc262_toshiba_s06_speaker_automute(codec);
9508 alc262_dmic_automute(codec);
9509 }
9510
9511 /* mute/unmute internal speaker according to the hp jack and mute state */
9512 static void alc262_hippo_automute(struct hda_codec *codec)
9513 {
9514 struct alc_spec *spec = codec->spec;
9515 unsigned int mute;
9516 unsigned int present;
9517
9518 /* need to execute and sync at first */
9519 snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
9520 present = snd_hda_codec_read(codec, 0x15, 0,
9521 AC_VERB_GET_PIN_SENSE, 0);
9522 spec->jack_present = (present & 0x80000000) != 0;
9523 if (spec->jack_present) {
9524 /* mute internal speaker */
9525 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9526 HDA_AMP_MUTE, HDA_AMP_MUTE);
9527 } else {
9528 /* unmute internal speaker if necessary */
9529 mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
9530 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9531 HDA_AMP_MUTE, mute);
9532 }
9533 }
9534
9535 /* unsolicited event for HP jack sensing */
9536 static void alc262_hippo_unsol_event(struct hda_codec *codec,
9537 unsigned int res)
9538 {
9539 if ((res >> 26) != ALC880_HP_EVENT)
9540 return;
9541 alc262_hippo_automute(codec);
9542 }
9543
9544 static void alc262_hippo1_automute(struct hda_codec *codec)
9545 {
9546 unsigned int mute;
9547 unsigned int present;
9548
9549 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
9550 present = snd_hda_codec_read(codec, 0x1b, 0,
9551 AC_VERB_GET_PIN_SENSE, 0);
9552 present = (present & 0x80000000) != 0;
9553 if (present) {
9554 /* mute internal speaker */
9555 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9556 HDA_AMP_MUTE, HDA_AMP_MUTE);
9557 } else {
9558 /* unmute internal speaker if necessary */
9559 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
9560 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9561 HDA_AMP_MUTE, mute);
9562 }
9563 }
9564
9565 /* unsolicited event for HP jack sensing */
9566 static void alc262_hippo1_unsol_event(struct hda_codec *codec,
9567 unsigned int res)
9568 {
9569 if ((res >> 26) != ALC880_HP_EVENT)
9570 return;
9571 alc262_hippo1_automute(codec);
9572 }
9573
9574 /*
9575 * nec model
9576 * 0x15 = headphone
9577 * 0x16 = internal speaker
9578 * 0x18 = external mic
9579 */
9580
9581 static struct snd_kcontrol_new alc262_nec_mixer[] = {
9582 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
9583 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 0x0, HDA_OUTPUT),
9584
9585 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9586 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9587 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9588
9589 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9590 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9591 { } /* end */
9592 };
9593
9594 static struct hda_verb alc262_nec_verbs[] = {
9595 /* Unmute Speaker */
9596 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9597
9598 /* Headphone */
9599 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9600 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9601
9602 /* External mic to headphone */
9603 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9604 /* External mic to speaker */
9605 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9606 {}
9607 };
9608
9609 /*
9610 * fujitsu model
9611 * 0x14 = headphone/spdif-out, 0x15 = internal speaker,
9612 * 0x1b = port replicator headphone out
9613 */
9614
9615 #define ALC_HP_EVENT 0x37
9616
9617 static struct hda_verb alc262_fujitsu_unsol_verbs[] = {
9618 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
9619 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9620 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
9621 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9622 {}
9623 };
9624
9625 static struct hda_verb alc262_lenovo_3000_unsol_verbs[] = {
9626 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
9627 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9628 {}
9629 };
9630
9631 static struct hda_input_mux alc262_fujitsu_capture_source = {
9632 .num_items = 3,
9633 .items = {
9634 { "Mic", 0x0 },
9635 { "Int Mic", 0x1 },
9636 { "CD", 0x4 },
9637 },
9638 };
9639
9640 static struct hda_input_mux alc262_HP_capture_source = {
9641 .num_items = 5,
9642 .items = {
9643 { "Mic", 0x0 },
9644 { "Front Mic", 0x1 },
9645 { "Line", 0x2 },
9646 { "CD", 0x4 },
9647 { "AUX IN", 0x6 },
9648 },
9649 };
9650
9651 static struct hda_input_mux alc262_HP_D7000_capture_source = {
9652 .num_items = 4,
9653 .items = {
9654 { "Mic", 0x0 },
9655 { "Front Mic", 0x2 },
9656 { "Line", 0x1 },
9657 { "CD", 0x4 },
9658 },
9659 };
9660
9661 /* mute/unmute internal speaker according to the hp jacks and mute state */
9662 static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
9663 {
9664 struct alc_spec *spec = codec->spec;
9665 unsigned int mute;
9666
9667 if (force || !spec->sense_updated) {
9668 unsigned int present;
9669 /* need to execute and sync at first */
9670 snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
9671 /* check laptop HP jack */
9672 present = snd_hda_codec_read(codec, 0x14, 0,
9673 AC_VERB_GET_PIN_SENSE, 0);
9674 /* need to execute and sync at first */
9675 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
9676 /* check docking HP jack */
9677 present |= snd_hda_codec_read(codec, 0x1b, 0,
9678 AC_VERB_GET_PIN_SENSE, 0);
9679 if (present & AC_PINSENSE_PRESENCE)
9680 spec->jack_present = 1;
9681 else
9682 spec->jack_present = 0;
9683 spec->sense_updated = 1;
9684 }
9685 /* unmute internal speaker only if both HPs are unplugged and
9686 * master switch is on
9687 */
9688 if (spec->jack_present)
9689 mute = HDA_AMP_MUTE;
9690 else
9691 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
9692 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9693 HDA_AMP_MUTE, mute);
9694 }
9695
9696 /* unsolicited event for HP jack sensing */
9697 static void alc262_fujitsu_unsol_event(struct hda_codec *codec,
9698 unsigned int res)
9699 {
9700 if ((res >> 26) != ALC_HP_EVENT)
9701 return;
9702 alc262_fujitsu_automute(codec, 1);
9703 }
9704
9705 static void alc262_fujitsu_init_hook(struct hda_codec *codec)
9706 {
9707 alc262_fujitsu_automute(codec, 1);
9708 }
9709
9710 /* bind volumes of both NID 0x0c and 0x0d */
9711 static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
9712 .ops = &snd_hda_bind_vol,
9713 .values = {
9714 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
9715 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
9716 0
9717 },
9718 };
9719
9720 /* mute/unmute internal speaker according to the hp jack and mute state */
9721 static void alc262_lenovo_3000_automute(struct hda_codec *codec, int force)
9722 {
9723 struct alc_spec *spec = codec->spec;
9724 unsigned int mute;
9725
9726 if (force || !spec->sense_updated) {
9727 unsigned int present_int_hp;
9728 /* need to execute and sync at first */
9729 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
9730 present_int_hp = snd_hda_codec_read(codec, 0x1b, 0,
9731 AC_VERB_GET_PIN_SENSE, 0);
9732 spec->jack_present = (present_int_hp & 0x80000000) != 0;
9733 spec->sense_updated = 1;
9734 }
9735 if (spec->jack_present) {
9736 /* mute internal speaker */
9737 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9738 HDA_AMP_MUTE, HDA_AMP_MUTE);
9739 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
9740 HDA_AMP_MUTE, HDA_AMP_MUTE);
9741 } else {
9742 /* unmute internal speaker if necessary */
9743 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
9744 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9745 HDA_AMP_MUTE, mute);
9746 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
9747 HDA_AMP_MUTE, mute);
9748 }
9749 }
9750
9751 /* unsolicited event for HP jack sensing */
9752 static void alc262_lenovo_3000_unsol_event(struct hda_codec *codec,
9753 unsigned int res)
9754 {
9755 if ((res >> 26) != ALC_HP_EVENT)
9756 return;
9757 alc262_lenovo_3000_automute(codec, 1);
9758 }
9759
9760 /* bind hp and internal speaker mute (with plug check) */
9761 static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
9762 struct snd_ctl_elem_value *ucontrol)
9763 {
9764 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9765 long *valp = ucontrol->value.integer.value;
9766 int change;
9767
9768 change = snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9769 HDA_AMP_MUTE,
9770 valp ? 0 : HDA_AMP_MUTE);
9771 change |= snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
9772 HDA_AMP_MUTE,
9773 valp ? 0 : HDA_AMP_MUTE);
9774
9775 if (change)
9776 alc262_fujitsu_automute(codec, 0);
9777 return change;
9778 }
9779
9780 static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
9781 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
9782 {
9783 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9784 .name = "Master Playback Switch",
9785 .info = snd_hda_mixer_amp_switch_info,
9786 .get = snd_hda_mixer_amp_switch_get,
9787 .put = alc262_fujitsu_master_sw_put,
9788 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
9789 },
9790 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9791 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9792 HDA_CODEC_VOLUME("PC Speaker Volume", 0x0b, 0x05, HDA_INPUT),
9793 HDA_CODEC_MUTE("PC Speaker Switch", 0x0b, 0x05, HDA_INPUT),
9794 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9795 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9796 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9797 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
9798 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9799 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9800 { } /* end */
9801 };
9802
9803 /* bind hp and internal speaker mute (with plug check) */
9804 static int alc262_lenovo_3000_master_sw_put(struct snd_kcontrol *kcontrol,
9805 struct snd_ctl_elem_value *ucontrol)
9806 {
9807 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9808 long *valp = ucontrol->value.integer.value;
9809 int change;
9810
9811 change = snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
9812 HDA_AMP_MUTE,
9813 valp ? 0 : HDA_AMP_MUTE);
9814
9815 if (change)
9816 alc262_lenovo_3000_automute(codec, 0);
9817 return change;
9818 }
9819
9820 static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
9821 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
9822 {
9823 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9824 .name = "Master Playback Switch",
9825 .info = snd_hda_mixer_amp_switch_info,
9826 .get = snd_hda_mixer_amp_switch_get,
9827 .put = alc262_lenovo_3000_master_sw_put,
9828 .private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
9829 },
9830 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9831 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9832 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9833 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9834 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9835 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
9836 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9837 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9838 { } /* end */
9839 };
9840
9841 static struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = {
9842 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
9843 {
9844 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9845 .name = "Master Playback Switch",
9846 .info = snd_hda_mixer_amp_switch_info,
9847 .get = snd_hda_mixer_amp_switch_get,
9848 .put = alc262_sony_master_sw_put,
9849 .private_value = HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
9850 },
9851 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9852 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9853 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
9854 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9855 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9856 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
9857 { } /* end */
9858 };
9859
9860 /* additional init verbs for Benq laptops */
9861 static struct hda_verb alc262_EAPD_verbs[] = {
9862 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
9863 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
9864 {}
9865 };
9866
9867 static struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
9868 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9869 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
9870
9871 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
9872 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
9873 {}
9874 };
9875
9876 /* Samsung Q1 Ultra Vista model setup */
9877 static struct snd_kcontrol_new alc262_ultra_mixer[] = {
9878 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9879 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
9880 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
9881 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
9882 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT),
9883 HDA_CODEC_VOLUME("Headphone Mic Boost", 0x15, 0, HDA_INPUT),
9884 { } /* end */
9885 };
9886
9887 static struct hda_verb alc262_ultra_verbs[] = {
9888 /* output mixer */
9889 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9890 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9891 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9892 /* speaker */
9893 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9894 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9895 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9896 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9897 /* HP */
9898 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9899 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9900 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9901 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9902 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
9903 /* internal mic */
9904 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
9905 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9906 /* ADC, choose mic */
9907 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9908 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9909 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9910 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
9911 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
9912 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9913 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
9914 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
9915 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
9916 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(8)},
9917 {}
9918 };
9919
9920 /* mute/unmute internal speaker according to the hp jack and mute state */
9921 static void alc262_ultra_automute(struct hda_codec *codec)
9922 {
9923 struct alc_spec *spec = codec->spec;
9924 unsigned int mute;
9925
9926 mute = 0;
9927 /* auto-mute only when HP is used as HP */
9928 if (!spec->cur_mux[0]) {
9929 unsigned int present;
9930 /* need to execute and sync at first */
9931 snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
9932 present = snd_hda_codec_read(codec, 0x15, 0,
9933 AC_VERB_GET_PIN_SENSE, 0);
9934 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
9935 if (spec->jack_present)
9936 mute = HDA_AMP_MUTE;
9937 }
9938 /* mute/unmute internal speaker */
9939 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9940 HDA_AMP_MUTE, mute);
9941 /* mute/unmute HP */
9942 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
9943 HDA_AMP_MUTE, mute ? 0 : HDA_AMP_MUTE);
9944 }
9945
9946 /* unsolicited event for HP jack sensing */
9947 static void alc262_ultra_unsol_event(struct hda_codec *codec,
9948 unsigned int res)
9949 {
9950 if ((res >> 26) != ALC880_HP_EVENT)
9951 return;
9952 alc262_ultra_automute(codec);
9953 }
9954
9955 static struct hda_input_mux alc262_ultra_capture_source = {
9956 .num_items = 2,
9957 .items = {
9958 { "Mic", 0x1 },
9959 { "Headphone", 0x7 },
9960 },
9961 };
9962
9963 static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol,
9964 struct snd_ctl_elem_value *ucontrol)
9965 {
9966 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
9967 struct alc_spec *spec = codec->spec;
9968 int ret;
9969
9970 ret = alc882_mux_enum_put(kcontrol, ucontrol);
9971 if (!ret)
9972 return 0;
9973 /* reprogram the HP pin as mic or HP according to the input source */
9974 snd_hda_codec_write_cache(codec, 0x15, 0,
9975 AC_VERB_SET_PIN_WIDGET_CONTROL,
9976 spec->cur_mux[0] ? PIN_VREF80 : PIN_HP);
9977 alc262_ultra_automute(codec); /* mute/unmute HP */
9978 return ret;
9979 }
9980
9981 static struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
9982 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
9983 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
9984 {
9985 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9986 .name = "Capture Source",
9987 .info = alc882_mux_enum_info,
9988 .get = alc882_mux_enum_get,
9989 .put = alc262_ultra_mux_enum_put,
9990 },
9991 { } /* end */
9992 };
9993
9994 /* add playback controls from the parsed DAC table */
9995 static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
9996 const struct auto_pin_cfg *cfg)
9997 {
9998 hda_nid_t nid;
9999 int err;
10000
10001 spec->multiout.num_dacs = 1; /* only use one dac */
10002 spec->multiout.dac_nids = spec->private_dac_nids;
10003 spec->multiout.dac_nids[0] = 2;
10004
10005 nid = cfg->line_out_pins[0];
10006 if (nid) {
10007 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10008 "Front Playback Volume",
10009 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT));
10010 if (err < 0)
10011 return err;
10012 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10013 "Front Playback Switch",
10014 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
10015 if (err < 0)
10016 return err;
10017 }
10018
10019 nid = cfg->speaker_pins[0];
10020 if (nid) {
10021 if (nid == 0x16) {
10022 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10023 "Speaker Playback Volume",
10024 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
10025 HDA_OUTPUT));
10026 if (err < 0)
10027 return err;
10028 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10029 "Speaker Playback Switch",
10030 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
10031 HDA_OUTPUT));
10032 if (err < 0)
10033 return err;
10034 } else {
10035 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10036 "Speaker Playback Switch",
10037 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
10038 HDA_OUTPUT));
10039 if (err < 0)
10040 return err;
10041 }
10042 }
10043 nid = cfg->hp_pins[0];
10044 if (nid) {
10045 /* spec->multiout.hp_nid = 2; */
10046 if (nid == 0x16) {
10047 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10048 "Headphone Playback Volume",
10049 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
10050 HDA_OUTPUT));
10051 if (err < 0)
10052 return err;
10053 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10054 "Headphone Playback Switch",
10055 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
10056 HDA_OUTPUT));
10057 if (err < 0)
10058 return err;
10059 } else {
10060 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10061 "Headphone Playback Switch",
10062 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
10063 HDA_OUTPUT));
10064 if (err < 0)
10065 return err;
10066 }
10067 }
10068 return 0;
10069 }
10070
10071 /* identical with ALC880 */
10072 #define alc262_auto_create_analog_input_ctls \
10073 alc880_auto_create_analog_input_ctls
10074
10075 /*
10076 * generic initialization of ADC, input mixers and output mixers
10077 */
10078 static struct hda_verb alc262_volume_init_verbs[] = {
10079 /*
10080 * Unmute ADC0-2 and set the default input to mic-in
10081 */
10082 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
10083 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10084 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10085 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10086 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10087 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10088
10089 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
10090 * mixer widget
10091 * Note: PASD motherboards uses the Line In 2 as the input for
10092 * front panel mic (mic 2)
10093 */
10094 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
10095 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10096 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10097 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10098 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10099 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10100
10101 /*
10102 * Set up output mixers (0x0c - 0x0f)
10103 */
10104 /* set vol=0 to output mixers */
10105 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10106 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10107 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10108
10109 /* set up input amps for analog loopback */
10110 /* Amp Indices: DAC = 0, mixer = 1 */
10111 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10112 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10113 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10114 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10115 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10116 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10117
10118 /* FIXME: use matrix-type input source selection */
10119 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
10120 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
10121 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10122 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10123 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10124 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10125 /* Input mixer2 */
10126 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10127 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10128 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10129 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10130 /* Input mixer3 */
10131 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10132 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
10133 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
10134 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
10135
10136 { }
10137 };
10138
10139 static struct hda_verb alc262_HP_BPC_init_verbs[] = {
10140 /*
10141 * Unmute ADC0-2 and set the default input to mic-in
10142 */
10143 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
10144 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10145 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10146 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10147 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10148 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10149
10150 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
10151 * mixer widget
10152 * Note: PASD motherboards uses the Line In 2 as the input for
10153 * front panel mic (mic 2)
10154 */
10155 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
10156 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10157 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10158 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10159 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10160 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10161 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
10162 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
10163
10164 /*
10165 * Set up output mixers (0x0c - 0x0e)
10166 */
10167 /* set vol=0 to output mixers */
10168 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10169 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10170 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10171
10172 /* set up input amps for analog loopback */
10173 /* Amp Indices: DAC = 0, mixer = 1 */
10174 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10175 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10176 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10177 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10178 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10179 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10180
10181 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10182 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10183 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10184
10185 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10186 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10187
10188 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
10189 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10190
10191 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10192 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10193 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
10194 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10195 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
10196
10197 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
10198 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10199 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10200 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
10201 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10202 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10203
10204
10205 /* FIXME: use matrix-type input source selection */
10206 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
10207 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
10208 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10209 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10210 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10211 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10212 /* Input mixer2 */
10213 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10214 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10215 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10216 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10217 /* Input mixer3 */
10218 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10219 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10220 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10221 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10222
10223 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10224
10225 { }
10226 };
10227
10228 static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
10229 /*
10230 * Unmute ADC0-2 and set the default input to mic-in
10231 */
10232 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
10233 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10234 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
10235 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10236 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10237 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10238
10239 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
10240 * mixer widget
10241 * Note: PASD motherboards uses the Line In 2 as the input for front
10242 * panel mic (mic 2)
10243 */
10244 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
10245 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10246 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10247 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10248 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10249 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10250 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
10251 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
10252 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
10253 /*
10254 * Set up output mixers (0x0c - 0x0e)
10255 */
10256 /* set vol=0 to output mixers */
10257 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10258 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10259 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10260
10261 /* set up input amps for analog loopback */
10262 /* Amp Indices: DAC = 0, mixer = 1 */
10263 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10264 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10265 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10266 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10267 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10268 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10269
10270
10271 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP */
10272 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Mono */
10273 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* rear MIC */
10274 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* Line in */
10275 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
10276 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Line out */
10277 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD in */
10278
10279 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10280 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10281
10282 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
10283 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
10284
10285 /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
10286 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10287 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10288 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
10289 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10290 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
10291
10292 /* FIXME: use matrix-type input source selection */
10293 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
10294 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
10295 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
10296 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
10297 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
10298 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
10299 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
10300 /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
10301 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
10302 /* Input mixer2 */
10303 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10304 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
10305 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10306 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10307 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10308 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
10309 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
10310 /* Input mixer3 */
10311 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
10312 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
10313 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
10314 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
10315 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
10316 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
10317 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
10318
10319 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10320
10321 { }
10322 };
10323
10324 static struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = {
10325
10326 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Front Speaker */
10327 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
10328 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
10329
10330 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* MIC jack */
10331 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
10332 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
10333 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
10334
10335 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP jack */
10336 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
10337 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10338 {}
10339 };
10340
10341
10342 #ifdef CONFIG_SND_HDA_POWER_SAVE
10343 #define alc262_loopbacks alc880_loopbacks
10344 #endif
10345
10346 /* pcm configuration: identiacal with ALC880 */
10347 #define alc262_pcm_analog_playback alc880_pcm_analog_playback
10348 #define alc262_pcm_analog_capture alc880_pcm_analog_capture
10349 #define alc262_pcm_digital_playback alc880_pcm_digital_playback
10350 #define alc262_pcm_digital_capture alc880_pcm_digital_capture
10351
10352 /*
10353 * BIOS auto configuration
10354 */
10355 static int alc262_parse_auto_config(struct hda_codec *codec)
10356 {
10357 struct alc_spec *spec = codec->spec;
10358 int err;
10359 static hda_nid_t alc262_ignore[] = { 0x1d, 0 };
10360
10361 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
10362 alc262_ignore);
10363 if (err < 0)
10364 return err;
10365 if (!spec->autocfg.line_outs)
10366 return 0; /* can't find valid BIOS pin config */
10367 err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
10368 if (err < 0)
10369 return err;
10370 err = alc262_auto_create_analog_input_ctls(spec, &spec->autocfg);
10371 if (err < 0)
10372 return err;
10373
10374 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
10375
10376 if (spec->autocfg.dig_out_pin)
10377 spec->multiout.dig_out_nid = ALC262_DIGOUT_NID;
10378 if (spec->autocfg.dig_in_pin)
10379 spec->dig_in_nid = ALC262_DIGIN_NID;
10380
10381 if (spec->kctls.list)
10382 add_mixer(spec, spec->kctls.list);
10383
10384 add_verb(spec, alc262_volume_init_verbs);
10385 spec->num_mux_defs = 1;
10386 spec->input_mux = &spec->private_imux;
10387
10388 err = alc_auto_add_mic_boost(codec);
10389 if (err < 0)
10390 return err;
10391
10392 store_pin_configs(codec);
10393 return 1;
10394 }
10395
10396 #define alc262_auto_init_multi_out alc882_auto_init_multi_out
10397 #define alc262_auto_init_hp_out alc882_auto_init_hp_out
10398 #define alc262_auto_init_analog_input alc882_auto_init_analog_input
10399 #define alc262_auto_init_input_src alc882_auto_init_input_src
10400
10401
10402 /* init callback for auto-configuration model -- overriding the default init */
10403 static void alc262_auto_init(struct hda_codec *codec)
10404 {
10405 struct alc_spec *spec = codec->spec;
10406 alc262_auto_init_multi_out(codec);
10407 alc262_auto_init_hp_out(codec);
10408 alc262_auto_init_analog_input(codec);
10409 alc262_auto_init_input_src(codec);
10410 if (spec->unsol_event)
10411 alc_inithook(codec);
10412 }
10413
10414 /*
10415 * configuration and preset
10416 */
10417 static const char *alc262_models[ALC262_MODEL_LAST] = {
10418 [ALC262_BASIC] = "basic",
10419 [ALC262_HIPPO] = "hippo",
10420 [ALC262_HIPPO_1] = "hippo_1",
10421 [ALC262_FUJITSU] = "fujitsu",
10422 [ALC262_HP_BPC] = "hp-bpc",
10423 [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
10424 [ALC262_HP_TC_T5735] = "hp-tc-t5735",
10425 [ALC262_HP_RP5700] = "hp-rp5700",
10426 [ALC262_BENQ_ED8] = "benq",
10427 [ALC262_BENQ_T31] = "benq-t31",
10428 [ALC262_SONY_ASSAMD] = "sony-assamd",
10429 [ALC262_TOSHIBA_S06] = "toshiba-s06",
10430 [ALC262_TOSHIBA_RX1] = "toshiba-rx1",
10431 [ALC262_ULTRA] = "ultra",
10432 [ALC262_LENOVO_3000] = "lenovo-3000",
10433 [ALC262_NEC] = "nec",
10434 [ALC262_AUTO] = "auto",
10435 };
10436
10437 static struct snd_pci_quirk alc262_cfg_tbl[] = {
10438 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
10439 SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC),
10440 SND_PCI_QUIRK(0x103c, 0x12fe, "HP xw9400", ALC262_HP_BPC),
10441 SND_PCI_QUIRK(0x103c, 0x12ff, "HP xw4550", ALC262_HP_BPC),
10442 SND_PCI_QUIRK(0x103c, 0x1306, "HP xw8600", ALC262_HP_BPC),
10443 SND_PCI_QUIRK(0x103c, 0x1307, "HP xw6600", ALC262_HP_BPC),
10444 SND_PCI_QUIRK(0x103c, 0x1308, "HP xw4600", ALC262_HP_BPC),
10445 SND_PCI_QUIRK(0x103c, 0x1309, "HP xw4*00", ALC262_HP_BPC),
10446 SND_PCI_QUIRK(0x103c, 0x130a, "HP xw6*00", ALC262_HP_BPC),
10447 SND_PCI_QUIRK(0x103c, 0x130b, "HP xw8*00", ALC262_HP_BPC),
10448 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
10449 SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
10450 SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
10451 SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
10452 SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
10453 SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
10454 SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
10455 SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
10456 SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
10457 SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
10458 SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
10459 SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
10460 ALC262_HP_TC_T5735),
10461 SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700),
10462 SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
10463 SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
10464 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
10465 SND_PCI_QUIRK(0x104d, 0x900e, "Sony ASSAMD", ALC262_SONY_ASSAMD),
10466 SND_PCI_QUIRK(0x104d, 0x9015, "Sony 0x9015", ALC262_SONY_ASSAMD),
10467 SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
10468 ALC262_TOSHIBA_RX1),
10469 SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06),
10470 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
10471 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU),
10472 SND_PCI_QUIRK(0x144d, 0xc032, "Samsung Q1 Ultra", ALC262_ULTRA),
10473 SND_PCI_QUIRK(0x144d, 0xc039, "Samsung Q1U EL", ALC262_ULTRA),
10474 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000),
10475 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
10476 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
10477 SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
10478 {}
10479 };
10480
10481 static struct alc_config_preset alc262_presets[] = {
10482 [ALC262_BASIC] = {
10483 .mixers = { alc262_base_mixer },
10484 .init_verbs = { alc262_init_verbs },
10485 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10486 .dac_nids = alc262_dac_nids,
10487 .hp_nid = 0x03,
10488 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10489 .channel_mode = alc262_modes,
10490 .input_mux = &alc262_capture_source,
10491 },
10492 [ALC262_HIPPO] = {
10493 .mixers = { alc262_base_mixer },
10494 .init_verbs = { alc262_init_verbs, alc262_hippo_unsol_verbs},
10495 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10496 .dac_nids = alc262_dac_nids,
10497 .hp_nid = 0x03,
10498 .dig_out_nid = ALC262_DIGOUT_NID,
10499 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10500 .channel_mode = alc262_modes,
10501 .input_mux = &alc262_capture_source,
10502 .unsol_event = alc262_hippo_unsol_event,
10503 .init_hook = alc262_hippo_automute,
10504 },
10505 [ALC262_HIPPO_1] = {
10506 .mixers = { alc262_hippo1_mixer },
10507 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
10508 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10509 .dac_nids = alc262_dac_nids,
10510 .hp_nid = 0x02,
10511 .dig_out_nid = ALC262_DIGOUT_NID,
10512 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10513 .channel_mode = alc262_modes,
10514 .input_mux = &alc262_capture_source,
10515 .unsol_event = alc262_hippo1_unsol_event,
10516 .init_hook = alc262_hippo1_automute,
10517 },
10518 [ALC262_FUJITSU] = {
10519 .mixers = { alc262_fujitsu_mixer },
10520 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
10521 alc262_fujitsu_unsol_verbs },
10522 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10523 .dac_nids = alc262_dac_nids,
10524 .hp_nid = 0x03,
10525 .dig_out_nid = ALC262_DIGOUT_NID,
10526 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10527 .channel_mode = alc262_modes,
10528 .input_mux = &alc262_fujitsu_capture_source,
10529 .unsol_event = alc262_fujitsu_unsol_event,
10530 .init_hook = alc262_fujitsu_init_hook,
10531 },
10532 [ALC262_HP_BPC] = {
10533 .mixers = { alc262_HP_BPC_mixer },
10534 .init_verbs = { alc262_HP_BPC_init_verbs },
10535 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10536 .dac_nids = alc262_dac_nids,
10537 .hp_nid = 0x03,
10538 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10539 .channel_mode = alc262_modes,
10540 .input_mux = &alc262_HP_capture_source,
10541 .unsol_event = alc262_hp_bpc_unsol_event,
10542 .init_hook = alc262_hp_bpc_automute,
10543 },
10544 [ALC262_HP_BPC_D7000_WF] = {
10545 .mixers = { alc262_HP_BPC_WildWest_mixer },
10546 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
10547 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10548 .dac_nids = alc262_dac_nids,
10549 .hp_nid = 0x03,
10550 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10551 .channel_mode = alc262_modes,
10552 .input_mux = &alc262_HP_D7000_capture_source,
10553 .unsol_event = alc262_hp_wildwest_unsol_event,
10554 .init_hook = alc262_hp_wildwest_automute,
10555 },
10556 [ALC262_HP_BPC_D7000_WL] = {
10557 .mixers = { alc262_HP_BPC_WildWest_mixer,
10558 alc262_HP_BPC_WildWest_option_mixer },
10559 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
10560 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10561 .dac_nids = alc262_dac_nids,
10562 .hp_nid = 0x03,
10563 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10564 .channel_mode = alc262_modes,
10565 .input_mux = &alc262_HP_D7000_capture_source,
10566 .unsol_event = alc262_hp_wildwest_unsol_event,
10567 .init_hook = alc262_hp_wildwest_automute,
10568 },
10569 [ALC262_HP_TC_T5735] = {
10570 .mixers = { alc262_hp_t5735_mixer },
10571 .init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs },
10572 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10573 .dac_nids = alc262_dac_nids,
10574 .hp_nid = 0x03,
10575 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10576 .channel_mode = alc262_modes,
10577 .input_mux = &alc262_capture_source,
10578 .unsol_event = alc262_hp_t5735_unsol_event,
10579 .init_hook = alc262_hp_t5735_init_hook,
10580 },
10581 [ALC262_HP_RP5700] = {
10582 .mixers = { alc262_hp_rp5700_mixer },
10583 .init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs },
10584 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10585 .dac_nids = alc262_dac_nids,
10586 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10587 .channel_mode = alc262_modes,
10588 .input_mux = &alc262_hp_rp5700_capture_source,
10589 },
10590 [ALC262_BENQ_ED8] = {
10591 .mixers = { alc262_base_mixer },
10592 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
10593 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10594 .dac_nids = alc262_dac_nids,
10595 .hp_nid = 0x03,
10596 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10597 .channel_mode = alc262_modes,
10598 .input_mux = &alc262_capture_source,
10599 },
10600 [ALC262_SONY_ASSAMD] = {
10601 .mixers = { alc262_sony_mixer },
10602 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
10603 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10604 .dac_nids = alc262_dac_nids,
10605 .hp_nid = 0x02,
10606 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10607 .channel_mode = alc262_modes,
10608 .input_mux = &alc262_capture_source,
10609 .unsol_event = alc262_hippo_unsol_event,
10610 .init_hook = alc262_hippo_automute,
10611 },
10612 [ALC262_BENQ_T31] = {
10613 .mixers = { alc262_benq_t31_mixer },
10614 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs, alc262_hippo_unsol_verbs },
10615 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10616 .dac_nids = alc262_dac_nids,
10617 .hp_nid = 0x03,
10618 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10619 .channel_mode = alc262_modes,
10620 .input_mux = &alc262_capture_source,
10621 .unsol_event = alc262_hippo_unsol_event,
10622 .init_hook = alc262_hippo_automute,
10623 },
10624 [ALC262_ULTRA] = {
10625 .mixers = { alc262_ultra_mixer, alc262_ultra_capture_mixer },
10626 .init_verbs = { alc262_ultra_verbs },
10627 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10628 .dac_nids = alc262_dac_nids,
10629 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10630 .channel_mode = alc262_modes,
10631 .input_mux = &alc262_ultra_capture_source,
10632 .adc_nids = alc262_adc_nids, /* ADC0 */
10633 .capsrc_nids = alc262_capsrc_nids,
10634 .num_adc_nids = 1, /* single ADC */
10635 .unsol_event = alc262_ultra_unsol_event,
10636 .init_hook = alc262_ultra_automute,
10637 },
10638 [ALC262_LENOVO_3000] = {
10639 .mixers = { alc262_lenovo_3000_mixer },
10640 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
10641 alc262_lenovo_3000_unsol_verbs },
10642 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10643 .dac_nids = alc262_dac_nids,
10644 .hp_nid = 0x03,
10645 .dig_out_nid = ALC262_DIGOUT_NID,
10646 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10647 .channel_mode = alc262_modes,
10648 .input_mux = &alc262_fujitsu_capture_source,
10649 .unsol_event = alc262_lenovo_3000_unsol_event,
10650 },
10651 [ALC262_NEC] = {
10652 .mixers = { alc262_nec_mixer },
10653 .init_verbs = { alc262_nec_verbs },
10654 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10655 .dac_nids = alc262_dac_nids,
10656 .hp_nid = 0x03,
10657 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10658 .channel_mode = alc262_modes,
10659 .input_mux = &alc262_capture_source,
10660 },
10661 [ALC262_TOSHIBA_S06] = {
10662 .mixers = { alc262_toshiba_s06_mixer },
10663 .init_verbs = { alc262_init_verbs, alc262_toshiba_s06_verbs,
10664 alc262_eapd_verbs },
10665 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10666 .capsrc_nids = alc262_dmic_capsrc_nids,
10667 .dac_nids = alc262_dac_nids,
10668 .adc_nids = alc262_dmic_adc_nids, /* ADC0 */
10669 .dig_out_nid = ALC262_DIGOUT_NID,
10670 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10671 .channel_mode = alc262_modes,
10672 .input_mux = &alc262_dmic_capture_source,
10673 .unsol_event = alc262_toshiba_s06_unsol_event,
10674 .init_hook = alc262_toshiba_s06_init_hook,
10675 },
10676 [ALC262_TOSHIBA_RX1] = {
10677 .mixers = { alc262_toshiba_rx1_mixer },
10678 .init_verbs = { alc262_init_verbs, alc262_toshiba_rx1_unsol_verbs },
10679 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10680 .dac_nids = alc262_dac_nids,
10681 .hp_nid = 0x03,
10682 .num_channel_mode = ARRAY_SIZE(alc262_modes),
10683 .channel_mode = alc262_modes,
10684 .input_mux = &alc262_capture_source,
10685 .unsol_event = alc262_hippo_unsol_event,
10686 .init_hook = alc262_hippo_automute,
10687 },
10688 };
10689
10690 static int patch_alc262(struct hda_codec *codec)
10691 {
10692 struct alc_spec *spec;
10693 int board_config;
10694 int err;
10695
10696 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
10697 if (spec == NULL)
10698 return -ENOMEM;
10699
10700 codec->spec = spec;
10701 #if 0
10702 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is
10703 * under-run
10704 */
10705 {
10706 int tmp;
10707 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
10708 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
10709 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
10710 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
10711 }
10712 #endif
10713
10714 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
10715
10716 board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
10717 alc262_models,
10718 alc262_cfg_tbl);
10719
10720 if (board_config < 0) {
10721 printk(KERN_INFO "hda_codec: Unknown model for ALC262, "
10722 "trying auto-probe from BIOS...\n");
10723 board_config = ALC262_AUTO;
10724 }
10725
10726 if (board_config == ALC262_AUTO) {
10727 /* automatic parse from the BIOS config */
10728 err = alc262_parse_auto_config(codec);
10729 if (err < 0) {
10730 alc_free(codec);
10731 return err;
10732 } else if (!err) {
10733 printk(KERN_INFO
10734 "hda_codec: Cannot set up configuration "
10735 "from BIOS. Using base mode...\n");
10736 board_config = ALC262_BASIC;
10737 }
10738 }
10739
10740 if (board_config != ALC262_AUTO)
10741 setup_preset(spec, &alc262_presets[board_config]);
10742
10743 spec->stream_name_analog = "ALC262 Analog";
10744 spec->stream_analog_playback = &alc262_pcm_analog_playback;
10745 spec->stream_analog_capture = &alc262_pcm_analog_capture;
10746
10747 spec->stream_name_digital = "ALC262 Digital";
10748 spec->stream_digital_playback = &alc262_pcm_digital_playback;
10749 spec->stream_digital_capture = &alc262_pcm_digital_capture;
10750
10751 if (!spec->adc_nids && spec->input_mux) {
10752 /* check whether NID 0x07 is valid */
10753 unsigned int wcap = get_wcaps(codec, 0x07);
10754
10755 /* get type */
10756 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
10757 if (wcap != AC_WID_AUD_IN) {
10758 spec->adc_nids = alc262_adc_nids_alt;
10759 spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids_alt);
10760 spec->capsrc_nids = alc262_capsrc_nids_alt;
10761 add_mixer(spec, alc262_capture_alt_mixer);
10762 } else {
10763 spec->adc_nids = alc262_adc_nids;
10764 spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids);
10765 spec->capsrc_nids = alc262_capsrc_nids;
10766 add_mixer(spec, alc262_capture_mixer);
10767 }
10768 }
10769
10770 spec->vmaster_nid = 0x0c;
10771
10772 codec->patch_ops = alc_patch_ops;
10773 if (board_config == ALC262_AUTO)
10774 spec->init_hook = alc262_auto_init;
10775 #ifdef CONFIG_SND_HDA_POWER_SAVE
10776 if (!spec->loopback.amplist)
10777 spec->loopback.amplist = alc262_loopbacks;
10778 #endif
10779
10780 return 0;
10781 }
10782
10783 /*
10784 * ALC268 channel source setting (2 channel)
10785 */
10786 #define ALC268_DIGOUT_NID ALC880_DIGOUT_NID
10787 #define alc268_modes alc260_modes
10788
10789 static hda_nid_t alc268_dac_nids[2] = {
10790 /* front, hp */
10791 0x02, 0x03
10792 };
10793
10794 static hda_nid_t alc268_adc_nids[2] = {
10795 /* ADC0-1 */
10796 0x08, 0x07
10797 };
10798
10799 static hda_nid_t alc268_adc_nids_alt[1] = {
10800 /* ADC0 */
10801 0x08
10802 };
10803
10804 static hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 };
10805
10806 static struct snd_kcontrol_new alc268_base_mixer[] = {
10807 /* output mixer control */
10808 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
10809 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
10810 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
10811 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
10812 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10813 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10814 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
10815 { }
10816 };
10817
10818 /* bind Beep switches of both NID 0x0f and 0x10 */
10819 static struct hda_bind_ctls alc268_bind_beep_sw = {
10820 .ops = &snd_hda_bind_sw,
10821 .values = {
10822 HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT),
10823 HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT),
10824 0
10825 },
10826 };
10827
10828 static struct snd_kcontrol_new alc268_beep_mixer[] = {
10829 HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
10830 HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw),
10831 { }
10832 };
10833
10834 static struct hda_verb alc268_eapd_verbs[] = {
10835 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
10836 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
10837 { }
10838 };
10839
10840 /* Toshiba specific */
10841 #define alc268_toshiba_automute alc262_hippo_automute
10842
10843 static struct hda_verb alc268_toshiba_verbs[] = {
10844 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10845 { } /* end */
10846 };
10847
10848 static struct hda_input_mux alc268_acer_lc_capture_source = {
10849 .num_items = 2,
10850 .items = {
10851 { "i-Mic", 0x6 },
10852 { "E-Mic", 0x0 },
10853 },
10854 };
10855
10856 /* Acer specific */
10857 /* bind volumes of both NID 0x02 and 0x03 */
10858 static struct hda_bind_ctls alc268_acer_bind_master_vol = {
10859 .ops = &snd_hda_bind_vol,
10860 .values = {
10861 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
10862 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
10863 0
10864 },
10865 };
10866
10867 /* mute/unmute internal speaker according to the hp jack and mute state */
10868 static void alc268_acer_automute(struct hda_codec *codec, int force)
10869 {
10870 struct alc_spec *spec = codec->spec;
10871 unsigned int mute;
10872
10873 if (force || !spec->sense_updated) {
10874 unsigned int present;
10875 present = snd_hda_codec_read(codec, 0x14, 0,
10876 AC_VERB_GET_PIN_SENSE, 0);
10877 spec->jack_present = (present & 0x80000000) != 0;
10878 spec->sense_updated = 1;
10879 }
10880 if (spec->jack_present)
10881 mute = HDA_AMP_MUTE; /* mute internal speaker */
10882 else /* unmute internal speaker if necessary */
10883 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
10884 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
10885 HDA_AMP_MUTE, mute);
10886 }
10887
10888
10889 /* bind hp and internal speaker mute (with plug check) */
10890 static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol,
10891 struct snd_ctl_elem_value *ucontrol)
10892 {
10893 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10894 long *valp = ucontrol->value.integer.value;
10895 int change;
10896
10897 change = snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
10898 HDA_AMP_MUTE,
10899 valp[0] ? 0 : HDA_AMP_MUTE);
10900 change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
10901 HDA_AMP_MUTE,
10902 valp[1] ? 0 : HDA_AMP_MUTE);
10903 if (change)
10904 alc268_acer_automute(codec, 0);
10905 return change;
10906 }
10907
10908 static struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = {
10909 /* output mixer control */
10910 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
10911 {
10912 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10913 .name = "Master Playback Switch",
10914 .info = snd_hda_mixer_amp_switch_info,
10915 .get = snd_hda_mixer_amp_switch_get,
10916 .put = alc268_acer_master_sw_put,
10917 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
10918 },
10919 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT),
10920 { }
10921 };
10922
10923 static struct snd_kcontrol_new alc268_acer_mixer[] = {
10924 /* output mixer control */
10925 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
10926 {
10927 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10928 .name = "Master Playback Switch",
10929 .info = snd_hda_mixer_amp_switch_info,
10930 .get = snd_hda_mixer_amp_switch_get,
10931 .put = alc268_acer_master_sw_put,
10932 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
10933 },
10934 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10935 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
10936 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
10937 { }
10938 };
10939
10940 static struct hda_verb alc268_acer_aspire_one_verbs[] = {
10941 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10942 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10943 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10944 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
10945 {0x23, AC_VERB_SET_CONNECT_SEL, 0x06},
10946 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, 0xa017},
10947 { }
10948 };
10949
10950 static struct hda_verb alc268_acer_verbs[] = {
10951 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */
10952 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10953 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10954 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10955 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10956 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10957 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
10958 { }
10959 };
10960
10961 /* unsolicited event for HP jack sensing */
10962 static void alc268_toshiba_unsol_event(struct hda_codec *codec,
10963 unsigned int res)
10964 {
10965 if ((res >> 26) != ALC880_HP_EVENT)
10966 return;
10967 alc268_toshiba_automute(codec);
10968 }
10969
10970 static void alc268_acer_unsol_event(struct hda_codec *codec,
10971 unsigned int res)
10972 {
10973 if ((res >> 26) != ALC880_HP_EVENT)
10974 return;
10975 alc268_acer_automute(codec, 1);
10976 }
10977
10978 static void alc268_acer_init_hook(struct hda_codec *codec)
10979 {
10980 alc268_acer_automute(codec, 1);
10981 }
10982
10983 /* toggle speaker-output according to the hp-jack state */
10984 static void alc268_aspire_one_speaker_automute(struct hda_codec *codec)
10985 {
10986 unsigned int present;
10987 unsigned char bits;
10988
10989 present = snd_hda_codec_read(codec, 0x15, 0,
10990 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
10991 bits = present ? AMP_IN_MUTE(0) : 0;
10992 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 0,
10993 AMP_IN_MUTE(0), bits);
10994 snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 1,
10995 AMP_IN_MUTE(0), bits);
10996 }
10997
10998
10999 static void alc268_acer_mic_automute(struct hda_codec *codec)
11000 {
11001 unsigned int present;
11002
11003 present = snd_hda_codec_read(codec, 0x18, 0,
11004 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11005 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_CONNECT_SEL,
11006 present ? 0x0 : 0x6);
11007 }
11008
11009 static void alc268_acer_lc_unsol_event(struct hda_codec *codec,
11010 unsigned int res)
11011 {
11012 if ((res >> 26) == ALC880_HP_EVENT)
11013 alc268_aspire_one_speaker_automute(codec);
11014 if ((res >> 26) == ALC880_MIC_EVENT)
11015 alc268_acer_mic_automute(codec);
11016 }
11017
11018 static void alc268_acer_lc_init_hook(struct hda_codec *codec)
11019 {
11020 alc268_aspire_one_speaker_automute(codec);
11021 alc268_acer_mic_automute(codec);
11022 }
11023
11024 static struct snd_kcontrol_new alc268_dell_mixer[] = {
11025 /* output mixer control */
11026 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11027 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11028 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
11029 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11030 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11031 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
11032 { }
11033 };
11034
11035 static struct hda_verb alc268_dell_verbs[] = {
11036 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11037 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11038 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11039 { }
11040 };
11041
11042 /* mute/unmute internal speaker according to the hp jack and mute state */
11043 static void alc268_dell_automute(struct hda_codec *codec)
11044 {
11045 unsigned int present;
11046 unsigned int mute;
11047
11048 present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0);
11049 if (present & 0x80000000)
11050 mute = HDA_AMP_MUTE;
11051 else
11052 mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
11053 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11054 HDA_AMP_MUTE, mute);
11055 }
11056
11057 static void alc268_dell_unsol_event(struct hda_codec *codec,
11058 unsigned int res)
11059 {
11060 if ((res >> 26) != ALC880_HP_EVENT)
11061 return;
11062 alc268_dell_automute(codec);
11063 }
11064
11065 #define alc268_dell_init_hook alc268_dell_automute
11066
11067 static struct snd_kcontrol_new alc267_quanta_il1_mixer[] = {
11068 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT),
11069 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11070 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
11071 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11072 HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11073 HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT),
11074 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
11075 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
11076 { }
11077 };
11078
11079 static struct hda_verb alc267_quanta_il1_verbs[] = {
11080 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11081 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
11082 { }
11083 };
11084
11085 static void alc267_quanta_il1_hp_automute(struct hda_codec *codec)
11086 {
11087 unsigned int present;
11088
11089 present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0)
11090 & AC_PINSENSE_PRESENCE;
11091 snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
11092 present ? 0 : PIN_OUT);
11093 }
11094
11095 static void alc267_quanta_il1_mic_automute(struct hda_codec *codec)
11096 {
11097 unsigned int present;
11098
11099 present = snd_hda_codec_read(codec, 0x18, 0,
11100 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11101 snd_hda_codec_write(codec, 0x23, 0,
11102 AC_VERB_SET_CONNECT_SEL,
11103 present ? 0x00 : 0x01);
11104 }
11105
11106 static void alc267_quanta_il1_automute(struct hda_codec *codec)
11107 {
11108 alc267_quanta_il1_hp_automute(codec);
11109 alc267_quanta_il1_mic_automute(codec);
11110 }
11111
11112 static void alc267_quanta_il1_unsol_event(struct hda_codec *codec,
11113 unsigned int res)
11114 {
11115 switch (res >> 26) {
11116 case ALC880_HP_EVENT:
11117 alc267_quanta_il1_hp_automute(codec);
11118 break;
11119 case ALC880_MIC_EVENT:
11120 alc267_quanta_il1_mic_automute(codec);
11121 break;
11122 }
11123 }
11124
11125 /*
11126 * generic initialization of ADC, input mixers and output mixers
11127 */
11128 static struct hda_verb alc268_base_init_verbs[] = {
11129 /* Unmute DAC0-1 and set vol = 0 */
11130 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11131 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11132 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11133 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11134 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11135 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11136
11137 /*
11138 * Set up output mixers (0x0c - 0x0e)
11139 */
11140 /* set vol=0 to output mixers */
11141 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11142 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11143 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11144 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
11145
11146 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11147 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11148
11149 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11150 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11151 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11152 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11153 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11154 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11155 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11156 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11157
11158 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11159 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11160 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11161 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11162 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11163 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11164 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11165
11166 /* set PCBEEP vol = 0, mute connections */
11167 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11168 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11169 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11170
11171 /* Unmute Selector 23h,24h and set the default input to mic-in */
11172
11173 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
11174 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11175 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
11176 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11177
11178 { }
11179 };
11180
11181 /*
11182 * generic initialization of ADC, input mixers and output mixers
11183 */
11184 static struct hda_verb alc268_volume_init_verbs[] = {
11185 /* set output DAC */
11186 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11187 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11188 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11189 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11190
11191 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11192 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11193 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11194 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11195 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11196
11197 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11198 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11199 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11200 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11201 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11202
11203 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11204 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11205 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11206 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11207
11208 /* set PCBEEP vol = 0, mute connections */
11209 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11210 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11211 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11212
11213 { }
11214 };
11215
11216 #define alc268_mux_enum_info alc_mux_enum_info
11217 #define alc268_mux_enum_get alc_mux_enum_get
11218 #define alc268_mux_enum_put alc_mux_enum_put
11219
11220 static struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
11221 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11222 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
11223 {
11224 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11225 /* The multiple "Capture Source" controls confuse alsamixer
11226 * So call somewhat different..
11227 */
11228 /* .name = "Capture Source", */
11229 .name = "Input Source",
11230 .count = 1,
11231 .info = alc268_mux_enum_info,
11232 .get = alc268_mux_enum_get,
11233 .put = alc268_mux_enum_put,
11234 },
11235 { } /* end */
11236 };
11237
11238 static struct snd_kcontrol_new alc268_capture_mixer[] = {
11239 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11240 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
11241 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
11242 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
11243 {
11244 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11245 /* The multiple "Capture Source" controls confuse alsamixer
11246 * So call somewhat different..
11247 */
11248 /* .name = "Capture Source", */
11249 .name = "Input Source",
11250 .count = 2,
11251 .info = alc268_mux_enum_info,
11252 .get = alc268_mux_enum_get,
11253 .put = alc268_mux_enum_put,
11254 },
11255 { } /* end */
11256 };
11257
11258 static struct hda_input_mux alc268_capture_source = {
11259 .num_items = 4,
11260 .items = {
11261 { "Mic", 0x0 },
11262 { "Front Mic", 0x1 },
11263 { "Line", 0x2 },
11264 { "CD", 0x3 },
11265 },
11266 };
11267
11268 static struct hda_input_mux alc268_acer_capture_source = {
11269 .num_items = 3,
11270 .items = {
11271 { "Mic", 0x0 },
11272 { "Internal Mic", 0x6 },
11273 { "Line", 0x2 },
11274 },
11275 };
11276
11277 #ifdef CONFIG_SND_DEBUG
11278 static struct snd_kcontrol_new alc268_test_mixer[] = {
11279 /* Volume widgets */
11280 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11281 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT),
11282 HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT),
11283 HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT),
11284 HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT),
11285 HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT),
11286 HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT),
11287 HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT),
11288 HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT),
11289 HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT),
11290 HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT),
11291 HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT),
11292 HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT),
11293 /* The below appears problematic on some hardwares */
11294 /*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/
11295 HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11296 HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT),
11297 HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT),
11298 HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT),
11299
11300 /* Modes for retasking pin widgets */
11301 ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT),
11302 ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT),
11303 ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT),
11304 ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT),
11305
11306 /* Controls for GPIO pins, assuming they are configured as outputs */
11307 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
11308 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
11309 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
11310 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
11311
11312 /* Switches to allow the digital SPDIF output pin to be enabled.
11313 * The ALC268 does not have an SPDIF input.
11314 */
11315 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01),
11316
11317 /* A switch allowing EAPD to be enabled. Some laptops seem to use
11318 * this output to turn on an external amplifier.
11319 */
11320 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
11321 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
11322
11323 { } /* end */
11324 };
11325 #endif
11326
11327 /* create input playback/capture controls for the given pin */
11328 static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
11329 const char *ctlname, int idx)
11330 {
11331 char name[32];
11332 int err;
11333
11334 sprintf(name, "%s Playback Volume", ctlname);
11335 if (nid == 0x14) {
11336 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
11337 HDA_COMPOSE_AMP_VAL(0x02, 3, idx,
11338 HDA_OUTPUT));
11339 if (err < 0)
11340 return err;
11341 } else if (nid == 0x15) {
11342 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
11343 HDA_COMPOSE_AMP_VAL(0x03, 3, idx,
11344 HDA_OUTPUT));
11345 if (err < 0)
11346 return err;
11347 } else
11348 return -1;
11349 sprintf(name, "%s Playback Switch", ctlname);
11350 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
11351 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
11352 if (err < 0)
11353 return err;
11354 return 0;
11355 }
11356
11357 /* add playback controls from the parsed DAC table */
11358 static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
11359 const struct auto_pin_cfg *cfg)
11360 {
11361 hda_nid_t nid;
11362 int err;
11363
11364 spec->multiout.num_dacs = 2; /* only use one dac */
11365 spec->multiout.dac_nids = spec->private_dac_nids;
11366 spec->multiout.dac_nids[0] = 2;
11367 spec->multiout.dac_nids[1] = 3;
11368
11369 nid = cfg->line_out_pins[0];
11370 if (nid)
11371 alc268_new_analog_output(spec, nid, "Front", 0);
11372
11373 nid = cfg->speaker_pins[0];
11374 if (nid == 0x1d) {
11375 err = add_control(spec, ALC_CTL_WIDGET_VOL,
11376 "Speaker Playback Volume",
11377 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
11378 if (err < 0)
11379 return err;
11380 }
11381 nid = cfg->hp_pins[0];
11382 if (nid)
11383 alc268_new_analog_output(spec, nid, "Headphone", 0);
11384
11385 nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
11386 if (nid == 0x16) {
11387 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
11388 "Mono Playback Switch",
11389 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_INPUT));
11390 if (err < 0)
11391 return err;
11392 }
11393 return 0;
11394 }
11395
11396 /* create playback/capture controls for input pins */
11397 static int alc268_auto_create_analog_input_ctls(struct alc_spec *spec,
11398 const struct auto_pin_cfg *cfg)
11399 {
11400 struct hda_input_mux *imux = &spec->private_imux;
11401 int i, idx1;
11402
11403 for (i = 0; i < AUTO_PIN_LAST; i++) {
11404 switch(cfg->input_pins[i]) {
11405 case 0x18:
11406 idx1 = 0; /* Mic 1 */
11407 break;
11408 case 0x19:
11409 idx1 = 1; /* Mic 2 */
11410 break;
11411 case 0x1a:
11412 idx1 = 2; /* Line In */
11413 break;
11414 case 0x1c:
11415 idx1 = 3; /* CD */
11416 break;
11417 case 0x12:
11418 case 0x13:
11419 idx1 = 6; /* digital mics */
11420 break;
11421 default:
11422 continue;
11423 }
11424 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
11425 imux->items[imux->num_items].index = idx1;
11426 imux->num_items++;
11427 }
11428 return 0;
11429 }
11430
11431 static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
11432 {
11433 struct alc_spec *spec = codec->spec;
11434 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
11435 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
11436 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
11437 unsigned int dac_vol1, dac_vol2;
11438
11439 if (speaker_nid) {
11440 snd_hda_codec_write(codec, speaker_nid, 0,
11441 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
11442 snd_hda_codec_write(codec, 0x0f, 0,
11443 AC_VERB_SET_AMP_GAIN_MUTE,
11444 AMP_IN_UNMUTE(1));
11445 snd_hda_codec_write(codec, 0x10, 0,
11446 AC_VERB_SET_AMP_GAIN_MUTE,
11447 AMP_IN_UNMUTE(1));
11448 } else {
11449 snd_hda_codec_write(codec, 0x0f, 0,
11450 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
11451 snd_hda_codec_write(codec, 0x10, 0,
11452 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
11453 }
11454
11455 dac_vol1 = dac_vol2 = 0xb000 | 0x40; /* set max volume */
11456 if (line_nid == 0x14)
11457 dac_vol2 = AMP_OUT_ZERO;
11458 else if (line_nid == 0x15)
11459 dac_vol1 = AMP_OUT_ZERO;
11460 if (hp_nid == 0x14)
11461 dac_vol2 = AMP_OUT_ZERO;
11462 else if (hp_nid == 0x15)
11463 dac_vol1 = AMP_OUT_ZERO;
11464 if (line_nid != 0x16 || hp_nid != 0x16 ||
11465 spec->autocfg.line_out_pins[1] != 0x16 ||
11466 spec->autocfg.line_out_pins[2] != 0x16)
11467 dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
11468
11469 snd_hda_codec_write(codec, 0x02, 0,
11470 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
11471 snd_hda_codec_write(codec, 0x03, 0,
11472 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
11473 }
11474
11475 /* pcm configuration: identiacal with ALC880 */
11476 #define alc268_pcm_analog_playback alc880_pcm_analog_playback
11477 #define alc268_pcm_analog_capture alc880_pcm_analog_capture
11478 #define alc268_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
11479 #define alc268_pcm_digital_playback alc880_pcm_digital_playback
11480
11481 /*
11482 * BIOS auto configuration
11483 */
11484 static int alc268_parse_auto_config(struct hda_codec *codec)
11485 {
11486 struct alc_spec *spec = codec->spec;
11487 int err;
11488 static hda_nid_t alc268_ignore[] = { 0 };
11489
11490 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
11491 alc268_ignore);
11492 if (err < 0)
11493 return err;
11494 if (!spec->autocfg.line_outs)
11495 return 0; /* can't find valid BIOS pin config */
11496
11497 err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
11498 if (err < 0)
11499 return err;
11500 err = alc268_auto_create_analog_input_ctls(spec, &spec->autocfg);
11501 if (err < 0)
11502 return err;
11503
11504 spec->multiout.max_channels = 2;
11505
11506 /* digital only support output */
11507 if (spec->autocfg.dig_out_pin)
11508 spec->multiout.dig_out_nid = ALC268_DIGOUT_NID;
11509
11510 if (spec->kctls.list)
11511 add_mixer(spec, spec->kctls.list);
11512
11513 if (spec->autocfg.speaker_pins[0] != 0x1d)
11514 add_mixer(spec, alc268_beep_mixer);
11515
11516 add_verb(spec, alc268_volume_init_verbs);
11517 spec->num_mux_defs = 1;
11518 spec->input_mux = &spec->private_imux;
11519
11520 err = alc_auto_add_mic_boost(codec);
11521 if (err < 0)
11522 return err;
11523
11524 store_pin_configs(codec);
11525 return 1;
11526 }
11527
11528 #define alc268_auto_init_multi_out alc882_auto_init_multi_out
11529 #define alc268_auto_init_hp_out alc882_auto_init_hp_out
11530 #define alc268_auto_init_analog_input alc882_auto_init_analog_input
11531
11532 /* init callback for auto-configuration model -- overriding the default init */
11533 static void alc268_auto_init(struct hda_codec *codec)
11534 {
11535 struct alc_spec *spec = codec->spec;
11536 alc268_auto_init_multi_out(codec);
11537 alc268_auto_init_hp_out(codec);
11538 alc268_auto_init_mono_speaker_out(codec);
11539 alc268_auto_init_analog_input(codec);
11540 if (spec->unsol_event)
11541 alc_inithook(codec);
11542 }
11543
11544 /*
11545 * configuration and preset
11546 */
11547 static const char *alc268_models[ALC268_MODEL_LAST] = {
11548 [ALC267_QUANTA_IL1] = "quanta-il1",
11549 [ALC268_3ST] = "3stack",
11550 [ALC268_TOSHIBA] = "toshiba",
11551 [ALC268_ACER] = "acer",
11552 [ALC268_ACER_ASPIRE_ONE] = "acer-aspire",
11553 [ALC268_DELL] = "dell",
11554 [ALC268_ZEPTO] = "zepto",
11555 #ifdef CONFIG_SND_DEBUG
11556 [ALC268_TEST] = "test",
11557 #endif
11558 [ALC268_AUTO] = "auto",
11559 };
11560
11561 static struct snd_pci_quirk alc268_cfg_tbl[] = {
11562 SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER),
11563 SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
11564 SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER),
11565 SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
11566 SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER),
11567 SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One",
11568 ALC268_ACER_ASPIRE_ONE),
11569 SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
11570 SND_PCI_QUIRK(0x103c, 0x30cc, "TOSHIBA", ALC268_TOSHIBA),
11571 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
11572 SND_PCI_QUIRK(0x1179, 0xff10, "TOSHIBA A205", ALC268_TOSHIBA),
11573 SND_PCI_QUIRK(0x1179, 0xff50, "TOSHIBA A305", ALC268_TOSHIBA),
11574 SND_PCI_QUIRK(0x1179, 0xff64, "TOSHIBA L305", ALC268_TOSHIBA),
11575 SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA),
11576 SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER),
11577 SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1),
11578 SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO),
11579 {}
11580 };
11581
11582 static struct alc_config_preset alc268_presets[] = {
11583 [ALC267_QUANTA_IL1] = {
11584 .mixers = { alc267_quanta_il1_mixer },
11585 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11586 alc267_quanta_il1_verbs },
11587 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11588 .dac_nids = alc268_dac_nids,
11589 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11590 .adc_nids = alc268_adc_nids_alt,
11591 .hp_nid = 0x03,
11592 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11593 .channel_mode = alc268_modes,
11594 .input_mux = &alc268_capture_source,
11595 .unsol_event = alc267_quanta_il1_unsol_event,
11596 .init_hook = alc267_quanta_il1_automute,
11597 },
11598 [ALC268_3ST] = {
11599 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
11600 alc268_beep_mixer },
11601 .init_verbs = { alc268_base_init_verbs },
11602 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11603 .dac_nids = alc268_dac_nids,
11604 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11605 .adc_nids = alc268_adc_nids_alt,
11606 .capsrc_nids = alc268_capsrc_nids,
11607 .hp_nid = 0x03,
11608 .dig_out_nid = ALC268_DIGOUT_NID,
11609 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11610 .channel_mode = alc268_modes,
11611 .input_mux = &alc268_capture_source,
11612 },
11613 [ALC268_TOSHIBA] = {
11614 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
11615 alc268_beep_mixer },
11616 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11617 alc268_toshiba_verbs },
11618 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11619 .dac_nids = alc268_dac_nids,
11620 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11621 .adc_nids = alc268_adc_nids_alt,
11622 .capsrc_nids = alc268_capsrc_nids,
11623 .hp_nid = 0x03,
11624 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11625 .channel_mode = alc268_modes,
11626 .input_mux = &alc268_capture_source,
11627 .unsol_event = alc268_toshiba_unsol_event,
11628 .init_hook = alc268_toshiba_automute,
11629 },
11630 [ALC268_ACER] = {
11631 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer,
11632 alc268_beep_mixer },
11633 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11634 alc268_acer_verbs },
11635 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11636 .dac_nids = alc268_dac_nids,
11637 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11638 .adc_nids = alc268_adc_nids_alt,
11639 .capsrc_nids = alc268_capsrc_nids,
11640 .hp_nid = 0x02,
11641 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11642 .channel_mode = alc268_modes,
11643 .input_mux = &alc268_acer_capture_source,
11644 .unsol_event = alc268_acer_unsol_event,
11645 .init_hook = alc268_acer_init_hook,
11646 },
11647 [ALC268_ACER_ASPIRE_ONE] = {
11648 .mixers = { alc268_acer_aspire_one_mixer,
11649 alc268_capture_alt_mixer },
11650 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11651 alc268_acer_aspire_one_verbs },
11652 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11653 .dac_nids = alc268_dac_nids,
11654 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11655 .adc_nids = alc268_adc_nids_alt,
11656 .capsrc_nids = alc268_capsrc_nids,
11657 .hp_nid = 0x03,
11658 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11659 .channel_mode = alc268_modes,
11660 .input_mux = &alc268_acer_lc_capture_source,
11661 .unsol_event = alc268_acer_lc_unsol_event,
11662 .init_hook = alc268_acer_lc_init_hook,
11663 },
11664 [ALC268_DELL] = {
11665 .mixers = { alc268_dell_mixer, alc268_beep_mixer },
11666 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11667 alc268_dell_verbs },
11668 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11669 .dac_nids = alc268_dac_nids,
11670 .hp_nid = 0x02,
11671 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11672 .channel_mode = alc268_modes,
11673 .unsol_event = alc268_dell_unsol_event,
11674 .init_hook = alc268_dell_init_hook,
11675 .input_mux = &alc268_capture_source,
11676 },
11677 [ALC268_ZEPTO] = {
11678 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
11679 alc268_beep_mixer },
11680 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11681 alc268_toshiba_verbs },
11682 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11683 .dac_nids = alc268_dac_nids,
11684 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11685 .adc_nids = alc268_adc_nids_alt,
11686 .capsrc_nids = alc268_capsrc_nids,
11687 .hp_nid = 0x03,
11688 .dig_out_nid = ALC268_DIGOUT_NID,
11689 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11690 .channel_mode = alc268_modes,
11691 .input_mux = &alc268_capture_source,
11692 .unsol_event = alc268_toshiba_unsol_event,
11693 .init_hook = alc268_toshiba_automute
11694 },
11695 #ifdef CONFIG_SND_DEBUG
11696 [ALC268_TEST] = {
11697 .mixers = { alc268_test_mixer, alc268_capture_mixer },
11698 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11699 alc268_volume_init_verbs },
11700 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11701 .dac_nids = alc268_dac_nids,
11702 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11703 .adc_nids = alc268_adc_nids_alt,
11704 .capsrc_nids = alc268_capsrc_nids,
11705 .hp_nid = 0x03,
11706 .dig_out_nid = ALC268_DIGOUT_NID,
11707 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11708 .channel_mode = alc268_modes,
11709 .input_mux = &alc268_capture_source,
11710 },
11711 #endif
11712 };
11713
11714 static int patch_alc268(struct hda_codec *codec)
11715 {
11716 struct alc_spec *spec;
11717 int board_config;
11718 int err;
11719
11720 spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
11721 if (spec == NULL)
11722 return -ENOMEM;
11723
11724 codec->spec = spec;
11725
11726 board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
11727 alc268_models,
11728 alc268_cfg_tbl);
11729
11730 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
11731 printk(KERN_INFO "hda_codec: Unknown model for ALC268, "
11732 "trying auto-probe from BIOS...\n");
11733 board_config = ALC268_AUTO;
11734 }
11735
11736 if (board_config == ALC268_AUTO) {
11737 /* automatic parse from the BIOS config */
11738 err = alc268_parse_auto_config(codec);
11739 if (err < 0) {
11740 alc_free(codec);
11741 return err;
11742 } else if (!err) {
11743 printk(KERN_INFO
11744 "hda_codec: Cannot set up configuration "
11745 "from BIOS. Using base mode...\n");
11746 board_config = ALC268_3ST;
11747 }
11748 }
11749
11750 if (board_config != ALC268_AUTO)
11751 setup_preset(spec, &alc268_presets[board_config]);
11752
11753 if (codec->vendor_id == 0x10ec0267) {
11754 spec->stream_name_analog = "ALC267 Analog";
11755 spec->stream_name_digital = "ALC267 Digital";
11756 } else {
11757 spec->stream_name_analog = "ALC268 Analog";
11758 spec->stream_name_digital = "ALC268 Digital";
11759 }
11760
11761 spec->stream_analog_playback = &alc268_pcm_analog_playback;
11762 spec->stream_analog_capture = &alc268_pcm_analog_capture;
11763 spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture;
11764
11765 spec->stream_digital_playback = &alc268_pcm_digital_playback;
11766
11767 if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
11768 /* override the amp caps for beep generator */
11769 snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
11770 (0x0c << AC_AMPCAP_OFFSET_SHIFT) |
11771 (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
11772 (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
11773 (0 << AC_AMPCAP_MUTE_SHIFT));
11774
11775 if (!spec->adc_nids && spec->input_mux) {
11776 /* check whether NID 0x07 is valid */
11777 unsigned int wcap = get_wcaps(codec, 0x07);
11778 int i;
11779
11780 /* get type */
11781 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
11782 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
11783 spec->adc_nids = alc268_adc_nids_alt;
11784 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt);
11785 add_mixer(spec, alc268_capture_alt_mixer);
11786 } else {
11787 spec->adc_nids = alc268_adc_nids;
11788 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids);
11789 add_mixer(spec, alc268_capture_mixer);
11790 }
11791 spec->capsrc_nids = alc268_capsrc_nids;
11792 /* set default input source */
11793 for (i = 0; i < spec->num_adc_nids; i++)
11794 snd_hda_codec_write_cache(codec, alc268_capsrc_nids[i],
11795 0, AC_VERB_SET_CONNECT_SEL,
11796 spec->input_mux->items[0].index);
11797 }
11798
11799 spec->vmaster_nid = 0x02;
11800
11801 codec->patch_ops = alc_patch_ops;
11802 if (board_config == ALC268_AUTO)
11803 spec->init_hook = alc268_auto_init;
11804
11805 return 0;
11806 }
11807
11808 /*
11809 * ALC269 channel source setting (2 channel)
11810 */
11811 #define ALC269_DIGOUT_NID ALC880_DIGOUT_NID
11812
11813 #define alc269_dac_nids alc260_dac_nids
11814
11815 static hda_nid_t alc269_adc_nids[1] = {
11816 /* ADC1 */
11817 0x08,
11818 };
11819
11820 static hda_nid_t alc269_capsrc_nids[1] = {
11821 0x23,
11822 };
11823
11824 /* NOTE: ADC2 (0x07) is connected from a recording *MIXER* (0x24),
11825 * not a mux!
11826 */
11827
11828 static struct hda_input_mux alc269_eeepc_dmic_capture_source = {
11829 .num_items = 2,
11830 .items = {
11831 { "i-Mic", 0x5 },
11832 { "e-Mic", 0x0 },
11833 },
11834 };
11835
11836 static struct hda_input_mux alc269_eeepc_amic_capture_source = {
11837 .num_items = 2,
11838 .items = {
11839 { "i-Mic", 0x1 },
11840 { "e-Mic", 0x0 },
11841 },
11842 };
11843
11844 #define alc269_modes alc260_modes
11845 #define alc269_capture_source alc880_lg_lw_capture_source
11846
11847 static struct snd_kcontrol_new alc269_base_mixer[] = {
11848 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11849 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11850 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11851 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11852 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11853 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11854 HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x4, HDA_INPUT),
11855 HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x4, HDA_INPUT),
11856 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11857 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11858 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11859 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
11860 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11861 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
11862 { } /* end */
11863 };
11864
11865 static struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
11866 /* output mixer control */
11867 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
11868 {
11869 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11870 .name = "Master Playback Switch",
11871 .info = snd_hda_mixer_amp_switch_info,
11872 .get = snd_hda_mixer_amp_switch_get,
11873 .put = alc268_acer_master_sw_put,
11874 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11875 },
11876 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11877 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11878 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11879 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11880 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11881 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
11882 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x04, HDA_INPUT),
11883 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x04, HDA_INPUT),
11884 { }
11885 };
11886
11887 /* bind volumes of both NID 0x0c and 0x0d */
11888 static struct hda_bind_ctls alc269_epc_bind_vol = {
11889 .ops = &snd_hda_bind_vol,
11890 .values = {
11891 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
11892 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
11893 0
11894 },
11895 };
11896
11897 static struct snd_kcontrol_new alc269_eeepc_mixer[] = {
11898 HDA_CODEC_MUTE("iSpeaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11899 HDA_BIND_VOL("LineOut Playback Volume", &alc269_epc_bind_vol),
11900 HDA_CODEC_MUTE("LineOut Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11901 { } /* end */
11902 };
11903
11904 /* capture mixer elements */
11905 static struct snd_kcontrol_new alc269_capture_mixer[] = {
11906 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
11907 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
11908 {
11909 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11910 /* The multiple "Capture Source" controls confuse alsamixer
11911 * So call somewhat different..
11912 */
11913 /* .name = "Capture Source", */
11914 .name = "Input Source",
11915 .count = 1,
11916 .info = alc_mux_enum_info,
11917 .get = alc_mux_enum_get,
11918 .put = alc_mux_enum_put,
11919 },
11920 { } /* end */
11921 };
11922
11923 /* capture mixer elements */
11924 static struct snd_kcontrol_new alc269_epc_capture_mixer[] = {
11925 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
11926 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
11927 { } /* end */
11928 };
11929
11930 /* beep control */
11931 static struct snd_kcontrol_new alc269_beep_mixer[] = {
11932 HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x4, HDA_INPUT),
11933 HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x4, HDA_INPUT),
11934 { } /* end */
11935 };
11936
11937 static struct hda_verb alc269_quanta_fl1_verbs[] = {
11938 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
11939 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11940 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11941 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11942 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11943 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11944 { }
11945 };
11946
11947 /* toggle speaker-output according to the hp-jack state */
11948 static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec)
11949 {
11950 unsigned int present;
11951 unsigned char bits;
11952
11953 present = snd_hda_codec_read(codec, 0x15, 0,
11954 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11955 bits = present ? AMP_IN_MUTE(0) : 0;
11956 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
11957 AMP_IN_MUTE(0), bits);
11958 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
11959 AMP_IN_MUTE(0), bits);
11960
11961 snd_hda_codec_write(codec, 0x20, 0,
11962 AC_VERB_SET_COEF_INDEX, 0x0c);
11963 snd_hda_codec_write(codec, 0x20, 0,
11964 AC_VERB_SET_PROC_COEF, 0x680);
11965
11966 snd_hda_codec_write(codec, 0x20, 0,
11967 AC_VERB_SET_COEF_INDEX, 0x0c);
11968 snd_hda_codec_write(codec, 0x20, 0,
11969 AC_VERB_SET_PROC_COEF, 0x480);
11970 }
11971
11972 static void alc269_quanta_fl1_mic_automute(struct hda_codec *codec)
11973 {
11974 unsigned int present;
11975
11976 present = snd_hda_codec_read(codec, 0x18, 0,
11977 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11978 snd_hda_codec_write(codec, 0x23, 0,
11979 AC_VERB_SET_CONNECT_SEL, present ? 0x0 : 0x1);
11980 }
11981
11982 static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec,
11983 unsigned int res)
11984 {
11985 if ((res >> 26) == ALC880_HP_EVENT)
11986 alc269_quanta_fl1_speaker_automute(codec);
11987 if ((res >> 26) == ALC880_MIC_EVENT)
11988 alc269_quanta_fl1_mic_automute(codec);
11989 }
11990
11991 static void alc269_quanta_fl1_init_hook(struct hda_codec *codec)
11992 {
11993 alc269_quanta_fl1_speaker_automute(codec);
11994 alc269_quanta_fl1_mic_automute(codec);
11995 }
11996
11997 static struct hda_verb alc269_eeepc_dmic_init_verbs[] = {
11998 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
11999 {0x23, AC_VERB_SET_CONNECT_SEL, 0x05},
12000 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
12001 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
12002 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12003 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12004 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12005 {}
12006 };
12007
12008 static struct hda_verb alc269_eeepc_amic_init_verbs[] = {
12009 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12010 {0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
12011 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
12012 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x701b | (0x00 << 8))},
12013 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12014 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12015 {}
12016 };
12017
12018 /* toggle speaker-output according to the hp-jack state */
12019 static void alc269_speaker_automute(struct hda_codec *codec)
12020 {
12021 unsigned int present;
12022 unsigned char bits;
12023
12024 present = snd_hda_codec_read(codec, 0x15, 0,
12025 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12026 bits = present ? AMP_IN_MUTE(0) : 0;
12027 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
12028 AMP_IN_MUTE(0), bits);
12029 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
12030 AMP_IN_MUTE(0), bits);
12031 }
12032
12033 static void alc269_eeepc_dmic_automute(struct hda_codec *codec)
12034 {
12035 unsigned int present;
12036
12037 present = snd_hda_codec_read(codec, 0x18, 0,
12038 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12039 snd_hda_codec_write(codec, 0x23, 0,
12040 AC_VERB_SET_CONNECT_SEL, (present ? 0 : 5));
12041 }
12042
12043 static void alc269_eeepc_amic_automute(struct hda_codec *codec)
12044 {
12045 unsigned int present;
12046
12047 present = snd_hda_codec_read(codec, 0x18, 0,
12048 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12049 snd_hda_codec_write(codec, 0x24, 0, AC_VERB_SET_AMP_GAIN_MUTE,
12050 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
12051 snd_hda_codec_write(codec, 0x24, 0, AC_VERB_SET_AMP_GAIN_MUTE,
12052 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
12053 }
12054
12055 /* unsolicited event for HP jack sensing */
12056 static void alc269_eeepc_dmic_unsol_event(struct hda_codec *codec,
12057 unsigned int res)
12058 {
12059 if ((res >> 26) == ALC880_HP_EVENT)
12060 alc269_speaker_automute(codec);
12061
12062 if ((res >> 26) == ALC880_MIC_EVENT)
12063 alc269_eeepc_dmic_automute(codec);
12064 }
12065
12066 static void alc269_eeepc_dmic_inithook(struct hda_codec *codec)
12067 {
12068 alc269_speaker_automute(codec);
12069 alc269_eeepc_dmic_automute(codec);
12070 }
12071
12072 /* unsolicited event for HP jack sensing */
12073 static void alc269_eeepc_amic_unsol_event(struct hda_codec *codec,
12074 unsigned int res)
12075 {
12076 if ((res >> 26) == ALC880_HP_EVENT)
12077 alc269_speaker_automute(codec);
12078
12079 if ((res >> 26) == ALC880_MIC_EVENT)
12080 alc269_eeepc_amic_automute(codec);
12081 }
12082
12083 static void alc269_eeepc_amic_inithook(struct hda_codec *codec)
12084 {
12085 alc269_speaker_automute(codec);
12086 alc269_eeepc_amic_automute(codec);
12087 }
12088
12089 /*
12090 * generic initialization of ADC, input mixers and output mixers
12091 */
12092 static struct hda_verb alc269_init_verbs[] = {
12093 /*
12094 * Unmute ADC0 and set the default input to mic-in
12095 */
12096 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12097
12098 /* Mute input amps (PCBeep, Line In, Mic 1 & Mic 2) of the
12099 * analog-loopback mixer widget
12100 * Note: PASD motherboards uses the Line In 2 as the input for
12101 * front panel mic (mic 2)
12102 */
12103 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
12104 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12105 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12106 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12107 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12108 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12109
12110 /*
12111 * Set up output mixers (0x0c - 0x0e)
12112 */
12113 /* set vol=0 to output mixers */
12114 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12115 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12116
12117 /* set up input amps for analog loopback */
12118 /* Amp Indices: DAC = 0, mixer = 1 */
12119 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12120 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12121 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12122 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12123 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12124 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12125
12126 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12127 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12128 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12129 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12130 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12131 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12132 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12133
12134 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12135 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12136 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12137 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12138 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12139 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12140 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12141
12142 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
12143 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12144
12145 /* FIXME: use matrix-type input source selection */
12146 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
12147 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
12148 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12149 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12150 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12151 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12152
12153 /* set EAPD */
12154 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
12155 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
12156 { }
12157 };
12158
12159 /* add playback controls from the parsed DAC table */
12160 static int alc269_auto_create_multi_out_ctls(struct alc_spec *spec,
12161 const struct auto_pin_cfg *cfg)
12162 {
12163 hda_nid_t nid;
12164 int err;
12165
12166 spec->multiout.num_dacs = 1; /* only use one dac */
12167 spec->multiout.dac_nids = spec->private_dac_nids;
12168 spec->multiout.dac_nids[0] = 2;
12169
12170 nid = cfg->line_out_pins[0];
12171 if (nid) {
12172 err = add_control(spec, ALC_CTL_WIDGET_VOL,
12173 "Front Playback Volume",
12174 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT));
12175 if (err < 0)
12176 return err;
12177 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12178 "Front Playback Switch",
12179 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
12180 if (err < 0)
12181 return err;
12182 }
12183
12184 nid = cfg->speaker_pins[0];
12185 if (nid) {
12186 if (!cfg->line_out_pins[0]) {
12187 err = add_control(spec, ALC_CTL_WIDGET_VOL,
12188 "Speaker Playback Volume",
12189 HDA_COMPOSE_AMP_VAL(0x02, 3, 0,
12190 HDA_OUTPUT));
12191 if (err < 0)
12192 return err;
12193 }
12194 if (nid == 0x16) {
12195 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12196 "Speaker Playback Switch",
12197 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
12198 HDA_OUTPUT));
12199 if (err < 0)
12200 return err;
12201 } else {
12202 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12203 "Speaker Playback Switch",
12204 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
12205 HDA_OUTPUT));
12206 if (err < 0)
12207 return err;
12208 }
12209 }
12210 nid = cfg->hp_pins[0];
12211 if (nid) {
12212 /* spec->multiout.hp_nid = 2; */
12213 if (!cfg->line_out_pins[0] && !cfg->speaker_pins[0]) {
12214 err = add_control(spec, ALC_CTL_WIDGET_VOL,
12215 "Headphone Playback Volume",
12216 HDA_COMPOSE_AMP_VAL(0x02, 3, 0,
12217 HDA_OUTPUT));
12218 if (err < 0)
12219 return err;
12220 }
12221 if (nid == 0x16) {
12222 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12223 "Headphone Playback Switch",
12224 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
12225 HDA_OUTPUT));
12226 if (err < 0)
12227 return err;
12228 } else {
12229 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12230 "Headphone Playback Switch",
12231 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
12232 HDA_OUTPUT));
12233 if (err < 0)
12234 return err;
12235 }
12236 }
12237 return 0;
12238 }
12239
12240 static int alc269_auto_create_analog_input_ctls(struct alc_spec *spec,
12241 const struct auto_pin_cfg *cfg)
12242 {
12243 int err;
12244
12245 err = alc880_auto_create_analog_input_ctls(spec, cfg);
12246 if (err < 0)
12247 return err;
12248 /* digital-mic input pin is excluded in alc880_auto_create..()
12249 * because it's under 0x18
12250 */
12251 if (cfg->input_pins[AUTO_PIN_MIC] == 0x12 ||
12252 cfg->input_pins[AUTO_PIN_FRONT_MIC] == 0x12) {
12253 struct hda_input_mux *imux = &spec->private_imux;
12254 imux->items[imux->num_items].label = "Int Mic";
12255 imux->items[imux->num_items].index = 0x05;
12256 imux->num_items++;
12257 }
12258 return 0;
12259 }
12260
12261 #ifdef CONFIG_SND_HDA_POWER_SAVE
12262 #define alc269_loopbacks alc880_loopbacks
12263 #endif
12264
12265 /* pcm configuration: identiacal with ALC880 */
12266 #define alc269_pcm_analog_playback alc880_pcm_analog_playback
12267 #define alc269_pcm_analog_capture alc880_pcm_analog_capture
12268 #define alc269_pcm_digital_playback alc880_pcm_digital_playback
12269 #define alc269_pcm_digital_capture alc880_pcm_digital_capture
12270
12271 /*
12272 * BIOS auto configuration
12273 */
12274 static int alc269_parse_auto_config(struct hda_codec *codec)
12275 {
12276 struct alc_spec *spec = codec->spec;
12277 int i, err;
12278 static hda_nid_t alc269_ignore[] = { 0x1d, 0 };
12279
12280 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
12281 alc269_ignore);
12282 if (err < 0)
12283 return err;
12284
12285 err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg);
12286 if (err < 0)
12287 return err;
12288 err = alc269_auto_create_analog_input_ctls(spec, &spec->autocfg);
12289 if (err < 0)
12290 return err;
12291
12292 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
12293
12294 if (spec->autocfg.dig_out_pin)
12295 spec->multiout.dig_out_nid = ALC269_DIGOUT_NID;
12296
12297 if (spec->kctls.list)
12298 add_mixer(spec, spec->kctls.list);
12299
12300 /* create a beep mixer control if the pin 0x1d isn't assigned */
12301 for (i = 0; i < ARRAY_SIZE(spec->autocfg.input_pins); i++)
12302 if (spec->autocfg.input_pins[i] == 0x1d)
12303 break;
12304 if (i >= ARRAY_SIZE(spec->autocfg.input_pins))
12305 add_mixer(spec, alc269_beep_mixer);
12306
12307 add_verb(spec, alc269_init_verbs);
12308 spec->num_mux_defs = 1;
12309 spec->input_mux = &spec->private_imux;
12310 /* set default input source */
12311 snd_hda_codec_write_cache(codec, alc269_capsrc_nids[0],
12312 0, AC_VERB_SET_CONNECT_SEL,
12313 spec->input_mux->items[0].index);
12314
12315 err = alc_auto_add_mic_boost(codec);
12316 if (err < 0)
12317 return err;
12318
12319 add_mixer(spec, alc269_capture_mixer);
12320
12321 store_pin_configs(codec);
12322 return 1;
12323 }
12324
12325 #define alc269_auto_init_multi_out alc882_auto_init_multi_out
12326 #define alc269_auto_init_hp_out alc882_auto_init_hp_out
12327 #define alc269_auto_init_analog_input alc882_auto_init_analog_input
12328
12329
12330 /* init callback for auto-configuration model -- overriding the default init */
12331 static void alc269_auto_init(struct hda_codec *codec)
12332 {
12333 struct alc_spec *spec = codec->spec;
12334 alc269_auto_init_multi_out(codec);
12335 alc269_auto_init_hp_out(codec);
12336 alc269_auto_init_analog_input(codec);
12337 if (spec->unsol_event)
12338 alc_inithook(codec);
12339 }
12340
12341 /*
12342 * configuration and preset
12343 */
12344 static const char *alc269_models[ALC269_MODEL_LAST] = {
12345 [ALC269_BASIC] = "basic",
12346 [ALC269_QUANTA_FL1] = "quanta",
12347 [ALC269_ASUS_EEEPC_P703] = "eeepc-p703",
12348 [ALC269_ASUS_EEEPC_P901] = "eeepc-p901"
12349 };
12350
12351 static struct snd_pci_quirk alc269_cfg_tbl[] = {
12352 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1),
12353 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
12354 ALC269_ASUS_EEEPC_P703),
12355 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901",
12356 ALC269_ASUS_EEEPC_P901),
12357 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101",
12358 ALC269_ASUS_EEEPC_P901),
12359 {}
12360 };
12361
12362 static struct alc_config_preset alc269_presets[] = {
12363 [ALC269_BASIC] = {
12364 .mixers = { alc269_base_mixer, alc269_capture_mixer },
12365 .init_verbs = { alc269_init_verbs },
12366 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
12367 .dac_nids = alc269_dac_nids,
12368 .hp_nid = 0x03,
12369 .num_channel_mode = ARRAY_SIZE(alc269_modes),
12370 .channel_mode = alc269_modes,
12371 .input_mux = &alc269_capture_source,
12372 },
12373 [ALC269_QUANTA_FL1] = {
12374 .mixers = { alc269_quanta_fl1_mixer },
12375 .init_verbs = { alc269_init_verbs, alc269_quanta_fl1_verbs },
12376 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
12377 .dac_nids = alc269_dac_nids,
12378 .hp_nid = 0x03,
12379 .num_channel_mode = ARRAY_SIZE(alc269_modes),
12380 .channel_mode = alc269_modes,
12381 .input_mux = &alc269_capture_source,
12382 .unsol_event = alc269_quanta_fl1_unsol_event,
12383 .init_hook = alc269_quanta_fl1_init_hook,
12384 },
12385 [ALC269_ASUS_EEEPC_P703] = {
12386 .mixers = { alc269_eeepc_mixer, alc269_epc_capture_mixer },
12387 .init_verbs = { alc269_init_verbs,
12388 alc269_eeepc_amic_init_verbs },
12389 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
12390 .dac_nids = alc269_dac_nids,
12391 .hp_nid = 0x03,
12392 .num_channel_mode = ARRAY_SIZE(alc269_modes),
12393 .channel_mode = alc269_modes,
12394 .input_mux = &alc269_eeepc_amic_capture_source,
12395 .unsol_event = alc269_eeepc_amic_unsol_event,
12396 .init_hook = alc269_eeepc_amic_inithook,
12397 },
12398 [ALC269_ASUS_EEEPC_P901] = {
12399 .mixers = { alc269_eeepc_mixer, alc269_epc_capture_mixer},
12400 .init_verbs = { alc269_init_verbs,
12401 alc269_eeepc_dmic_init_verbs },
12402 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
12403 .dac_nids = alc269_dac_nids,
12404 .hp_nid = 0x03,
12405 .num_channel_mode = ARRAY_SIZE(alc269_modes),
12406 .channel_mode = alc269_modes,
12407 .input_mux = &alc269_eeepc_dmic_capture_source,
12408 .unsol_event = alc269_eeepc_dmic_unsol_event,
12409 .init_hook = alc269_eeepc_dmic_inithook,
12410 },
12411 };
12412
12413 static int patch_alc269(struct hda_codec *codec)
12414 {
12415 struct alc_spec *spec;
12416 int board_config;
12417 int err;
12418
12419 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
12420 if (spec == NULL)
12421 return -ENOMEM;
12422
12423 codec->spec = spec;
12424
12425 alc_fix_pll_init(codec, 0x20, 0x04, 15);
12426
12427 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
12428 alc269_models,
12429 alc269_cfg_tbl);
12430
12431 if (board_config < 0) {
12432 printk(KERN_INFO "hda_codec: Unknown model for ALC269, "
12433 "trying auto-probe from BIOS...\n");
12434 board_config = ALC269_AUTO;
12435 }
12436
12437 if (board_config == ALC269_AUTO) {
12438 /* automatic parse from the BIOS config */
12439 err = alc269_parse_auto_config(codec);
12440 if (err < 0) {
12441 alc_free(codec);
12442 return err;
12443 } else if (!err) {
12444 printk(KERN_INFO
12445 "hda_codec: Cannot set up configuration "
12446 "from BIOS. Using base mode...\n");
12447 board_config = ALC269_BASIC;
12448 }
12449 }
12450
12451 if (board_config != ALC269_AUTO)
12452 setup_preset(spec, &alc269_presets[board_config]);
12453
12454 spec->stream_name_analog = "ALC269 Analog";
12455 spec->stream_analog_playback = &alc269_pcm_analog_playback;
12456 spec->stream_analog_capture = &alc269_pcm_analog_capture;
12457
12458 spec->stream_name_digital = "ALC269 Digital";
12459 spec->stream_digital_playback = &alc269_pcm_digital_playback;
12460 spec->stream_digital_capture = &alc269_pcm_digital_capture;
12461
12462 spec->adc_nids = alc269_adc_nids;
12463 spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
12464 spec->capsrc_nids = alc269_capsrc_nids;
12465
12466 codec->patch_ops = alc_patch_ops;
12467 if (board_config == ALC269_AUTO)
12468 spec->init_hook = alc269_auto_init;
12469 #ifdef CONFIG_SND_HDA_POWER_SAVE
12470 if (!spec->loopback.amplist)
12471 spec->loopback.amplist = alc269_loopbacks;
12472 #endif
12473
12474 return 0;
12475 }
12476
12477 /*
12478 * ALC861 channel source setting (2/6 channel selection for 3-stack)
12479 */
12480
12481 /*
12482 * set the path ways for 2 channel output
12483 * need to set the codec line out and mic 1 pin widgets to inputs
12484 */
12485 static struct hda_verb alc861_threestack_ch2_init[] = {
12486 /* set pin widget 1Ah (line in) for input */
12487 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12488 /* set pin widget 18h (mic1/2) for input, for mic also enable
12489 * the vref
12490 */
12491 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12492
12493 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
12494 #if 0
12495 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
12496 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
12497 #endif
12498 { } /* end */
12499 };
12500 /*
12501 * 6ch mode
12502 * need to set the codec line out and mic 1 pin widgets to outputs
12503 */
12504 static struct hda_verb alc861_threestack_ch6_init[] = {
12505 /* set pin widget 1Ah (line in) for output (Back Surround)*/
12506 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12507 /* set pin widget 18h (mic1) for output (CLFE)*/
12508 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12509
12510 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
12511 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
12512
12513 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
12514 #if 0
12515 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
12516 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
12517 #endif
12518 { } /* end */
12519 };
12520
12521 static struct hda_channel_mode alc861_threestack_modes[2] = {
12522 { 2, alc861_threestack_ch2_init },
12523 { 6, alc861_threestack_ch6_init },
12524 };
12525 /* Set mic1 as input and unmute the mixer */
12526 static struct hda_verb alc861_uniwill_m31_ch2_init[] = {
12527 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12528 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
12529 { } /* end */
12530 };
12531 /* Set mic1 as output and mute mixer */
12532 static struct hda_verb alc861_uniwill_m31_ch4_init[] = {
12533 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12534 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
12535 { } /* end */
12536 };
12537
12538 static struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
12539 { 2, alc861_uniwill_m31_ch2_init },
12540 { 4, alc861_uniwill_m31_ch4_init },
12541 };
12542
12543 /* Set mic1 and line-in as input and unmute the mixer */
12544 static struct hda_verb alc861_asus_ch2_init[] = {
12545 /* set pin widget 1Ah (line in) for input */
12546 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12547 /* set pin widget 18h (mic1/2) for input, for mic also enable
12548 * the vref
12549 */
12550 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12551
12552 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
12553 #if 0
12554 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
12555 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
12556 #endif
12557 { } /* end */
12558 };
12559 /* Set mic1 nad line-in as output and mute mixer */
12560 static struct hda_verb alc861_asus_ch6_init[] = {
12561 /* set pin widget 1Ah (line in) for output (Back Surround)*/
12562 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12563 /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
12564 /* set pin widget 18h (mic1) for output (CLFE)*/
12565 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12566 /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
12567 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
12568 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
12569
12570 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
12571 #if 0
12572 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
12573 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
12574 #endif
12575 { } /* end */
12576 };
12577
12578 static struct hda_channel_mode alc861_asus_modes[2] = {
12579 { 2, alc861_asus_ch2_init },
12580 { 6, alc861_asus_ch6_init },
12581 };
12582
12583 /* patch-ALC861 */
12584
12585 static struct snd_kcontrol_new alc861_base_mixer[] = {
12586 /* output mixer control */
12587 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
12588 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
12589 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
12590 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
12591 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
12592
12593 /*Input mixer control */
12594 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
12595 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
12596 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
12597 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
12598 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
12599 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
12600 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
12601 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
12602 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
12603 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
12604
12605 /* Capture mixer control */
12606 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
12607 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
12608 {
12609 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12610 .name = "Capture Source",
12611 .count = 1,
12612 .info = alc_mux_enum_info,
12613 .get = alc_mux_enum_get,
12614 .put = alc_mux_enum_put,
12615 },
12616 { } /* end */
12617 };
12618
12619 static struct snd_kcontrol_new alc861_3ST_mixer[] = {
12620 /* output mixer control */
12621 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
12622 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
12623 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
12624 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
12625 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
12626
12627 /* Input mixer control */
12628 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
12629 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
12630 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
12631 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
12632 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
12633 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
12634 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
12635 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
12636 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
12637 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
12638
12639 /* Capture mixer control */
12640 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
12641 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
12642 {
12643 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12644 .name = "Capture Source",
12645 .count = 1,
12646 .info = alc_mux_enum_info,
12647 .get = alc_mux_enum_get,
12648 .put = alc_mux_enum_put,
12649 },
12650 {
12651 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12652 .name = "Channel Mode",
12653 .info = alc_ch_mode_info,
12654 .get = alc_ch_mode_get,
12655 .put = alc_ch_mode_put,
12656 .private_value = ARRAY_SIZE(alc861_threestack_modes),
12657 },
12658 { } /* end */
12659 };
12660
12661 static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
12662 /* output mixer control */
12663 HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
12664 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
12665 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
12666
12667 /*Capture mixer control */
12668 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
12669 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
12670 {
12671 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12672 .name = "Capture Source",
12673 .count = 1,
12674 .info = alc_mux_enum_info,
12675 .get = alc_mux_enum_get,
12676 .put = alc_mux_enum_put,
12677 },
12678
12679 { } /* end */
12680 };
12681
12682 static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
12683 /* output mixer control */
12684 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
12685 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
12686 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
12687 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
12688 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
12689
12690 /* Input mixer control */
12691 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
12692 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
12693 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
12694 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
12695 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
12696 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
12697 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
12698 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
12699 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
12700 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
12701
12702 /* Capture mixer control */
12703 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
12704 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
12705 {
12706 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12707 .name = "Capture Source",
12708 .count = 1,
12709 .info = alc_mux_enum_info,
12710 .get = alc_mux_enum_get,
12711 .put = alc_mux_enum_put,
12712 },
12713 {
12714 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12715 .name = "Channel Mode",
12716 .info = alc_ch_mode_info,
12717 .get = alc_ch_mode_get,
12718 .put = alc_ch_mode_put,
12719 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
12720 },
12721 { } /* end */
12722 };
12723
12724 static struct snd_kcontrol_new alc861_asus_mixer[] = {
12725 /* output mixer control */
12726 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
12727 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
12728 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
12729 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
12730 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
12731
12732 /* Input mixer control */
12733 HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
12734 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12735 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
12736 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
12737 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
12738 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
12739 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
12740 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
12741 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
12742 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
12743
12744 /* Capture mixer control */
12745 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
12746 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
12747 {
12748 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12749 .name = "Capture Source",
12750 .count = 1,
12751 .info = alc_mux_enum_info,
12752 .get = alc_mux_enum_get,
12753 .put = alc_mux_enum_put,
12754 },
12755 {
12756 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12757 .name = "Channel Mode",
12758 .info = alc_ch_mode_info,
12759 .get = alc_ch_mode_get,
12760 .put = alc_ch_mode_put,
12761 .private_value = ARRAY_SIZE(alc861_asus_modes),
12762 },
12763 { }
12764 };
12765
12766 /* additional mixer */
12767 static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
12768 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
12769 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
12770 HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x23, 0x0, HDA_OUTPUT),
12771 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x23, 0x0, HDA_OUTPUT),
12772 { }
12773 };
12774
12775 /*
12776 * generic initialization of ADC, input mixers and output mixers
12777 */
12778 static struct hda_verb alc861_base_init_verbs[] = {
12779 /*
12780 * Unmute ADC0 and set the default input to mic-in
12781 */
12782 /* port-A for surround (rear panel) */
12783 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12784 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
12785 /* port-B for mic-in (rear panel) with vref */
12786 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12787 /* port-C for line-in (rear panel) */
12788 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12789 /* port-D for Front */
12790 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12791 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
12792 /* port-E for HP out (front panel) */
12793 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
12794 /* route front PCM to HP */
12795 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
12796 /* port-F for mic-in (front panel) with vref */
12797 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12798 /* port-G for CLFE (rear panel) */
12799 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12800 { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
12801 /* port-H for side (rear panel) */
12802 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12803 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
12804 /* CD-in */
12805 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12806 /* route front mic to ADC1*/
12807 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12808 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12809
12810 /* Unmute DAC0~3 & spdif out*/
12811 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12812 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12813 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12814 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12815 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12816
12817 /* Unmute Mixer 14 (mic) 1c (Line in)*/
12818 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12819 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12820 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12821 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12822
12823 /* Unmute Stereo Mixer 15 */
12824 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12825 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12826 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12827 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
12828
12829 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12830 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12831 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12832 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12833 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12834 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12835 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12836 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12837 /* hp used DAC 3 (Front) */
12838 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
12839 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12840
12841 { }
12842 };
12843
12844 static struct hda_verb alc861_threestack_init_verbs[] = {
12845 /*
12846 * Unmute ADC0 and set the default input to mic-in
12847 */
12848 /* port-A for surround (rear panel) */
12849 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12850 /* port-B for mic-in (rear panel) with vref */
12851 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12852 /* port-C for line-in (rear panel) */
12853 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12854 /* port-D for Front */
12855 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12856 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
12857 /* port-E for HP out (front panel) */
12858 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
12859 /* route front PCM to HP */
12860 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
12861 /* port-F for mic-in (front panel) with vref */
12862 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12863 /* port-G for CLFE (rear panel) */
12864 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12865 /* port-H for side (rear panel) */
12866 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12867 /* CD-in */
12868 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12869 /* route front mic to ADC1*/
12870 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12871 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12872 /* Unmute DAC0~3 & spdif out*/
12873 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12874 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12875 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12876 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12877 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12878
12879 /* Unmute Mixer 14 (mic) 1c (Line in)*/
12880 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12881 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12882 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12883 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12884
12885 /* Unmute Stereo Mixer 15 */
12886 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12887 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12888 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12889 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
12890
12891 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12892 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12893 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12894 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12895 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12896 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12897 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12898 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12899 /* hp used DAC 3 (Front) */
12900 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
12901 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12902 { }
12903 };
12904
12905 static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
12906 /*
12907 * Unmute ADC0 and set the default input to mic-in
12908 */
12909 /* port-A for surround (rear panel) */
12910 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12911 /* port-B for mic-in (rear panel) with vref */
12912 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12913 /* port-C for line-in (rear panel) */
12914 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12915 /* port-D for Front */
12916 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12917 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
12918 /* port-E for HP out (front panel) */
12919 /* this has to be set to VREF80 */
12920 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12921 /* route front PCM to HP */
12922 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
12923 /* port-F for mic-in (front panel) with vref */
12924 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12925 /* port-G for CLFE (rear panel) */
12926 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12927 /* port-H for side (rear panel) */
12928 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
12929 /* CD-in */
12930 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12931 /* route front mic to ADC1*/
12932 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12933 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12934 /* Unmute DAC0~3 & spdif out*/
12935 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12936 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12937 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12938 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12939 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12940
12941 /* Unmute Mixer 14 (mic) 1c (Line in)*/
12942 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12943 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12944 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12945 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12946
12947 /* Unmute Stereo Mixer 15 */
12948 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12949 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12950 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12951 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
12952
12953 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12954 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12955 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12956 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12957 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12958 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12959 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12960 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12961 /* hp used DAC 3 (Front) */
12962 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
12963 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
12964 { }
12965 };
12966
12967 static struct hda_verb alc861_asus_init_verbs[] = {
12968 /*
12969 * Unmute ADC0 and set the default input to mic-in
12970 */
12971 /* port-A for surround (rear panel)
12972 * according to codec#0 this is the HP jack
12973 */
12974 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
12975 /* route front PCM to HP */
12976 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
12977 /* port-B for mic-in (rear panel) with vref */
12978 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12979 /* port-C for line-in (rear panel) */
12980 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12981 /* port-D for Front */
12982 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12983 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
12984 /* port-E for HP out (front panel) */
12985 /* this has to be set to VREF80 */
12986 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12987 /* route front PCM to HP */
12988 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
12989 /* port-F for mic-in (front panel) with vref */
12990 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
12991 /* port-G for CLFE (rear panel) */
12992 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12993 /* port-H for side (rear panel) */
12994 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
12995 /* CD-in */
12996 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
12997 /* route front mic to ADC1*/
12998 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12999 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13000 /* Unmute DAC0~3 & spdif out*/
13001 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13002 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13003 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13004 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13005 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13006 /* Unmute Mixer 14 (mic) 1c (Line in)*/
13007 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13008 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13009 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13010 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13011
13012 /* Unmute Stereo Mixer 15 */
13013 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13014 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13015 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13016 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
13017
13018 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13019 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13020 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13021 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13022 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13023 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13024 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13025 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13026 /* hp used DAC 3 (Front) */
13027 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
13028 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13029 { }
13030 };
13031
13032 /* additional init verbs for ASUS laptops */
13033 static struct hda_verb alc861_asus_laptop_init_verbs[] = {
13034 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
13035 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
13036 { }
13037 };
13038
13039 /*
13040 * generic initialization of ADC, input mixers and output mixers
13041 */
13042 static struct hda_verb alc861_auto_init_verbs[] = {
13043 /*
13044 * Unmute ADC0 and set the default input to mic-in
13045 */
13046 /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
13047 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13048
13049 /* Unmute DAC0~3 & spdif out*/
13050 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13051 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13052 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13053 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13054 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13055
13056 /* Unmute Mixer 14 (mic) 1c (Line in)*/
13057 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13058 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13059 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13060 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13061
13062 /* Unmute Stereo Mixer 15 */
13063 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13064 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13065 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13066 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
13067
13068 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13069 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13070 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13071 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13072 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13073 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13074 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13075 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13076
13077 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13078 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13079 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13080 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
13081 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13082 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13083 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13084 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
13085
13086 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, /* set Mic 1 */
13087
13088 { }
13089 };
13090
13091 static struct hda_verb alc861_toshiba_init_verbs[] = {
13092 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13093
13094 { }
13095 };
13096
13097 /* toggle speaker-output according to the hp-jack state */
13098 static void alc861_toshiba_automute(struct hda_codec *codec)
13099 {
13100 unsigned int present;
13101
13102 present = snd_hda_codec_read(codec, 0x0f, 0,
13103 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
13104 snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
13105 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
13106 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
13107 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
13108 }
13109
13110 static void alc861_toshiba_unsol_event(struct hda_codec *codec,
13111 unsigned int res)
13112 {
13113 if ((res >> 26) == ALC880_HP_EVENT)
13114 alc861_toshiba_automute(codec);
13115 }
13116
13117 /* pcm configuration: identiacal with ALC880 */
13118 #define alc861_pcm_analog_playback alc880_pcm_analog_playback
13119 #define alc861_pcm_analog_capture alc880_pcm_analog_capture
13120 #define alc861_pcm_digital_playback alc880_pcm_digital_playback
13121 #define alc861_pcm_digital_capture alc880_pcm_digital_capture
13122
13123
13124 #define ALC861_DIGOUT_NID 0x07
13125
13126 static struct hda_channel_mode alc861_8ch_modes[1] = {
13127 { 8, NULL }
13128 };
13129
13130 static hda_nid_t alc861_dac_nids[4] = {
13131 /* front, surround, clfe, side */
13132 0x03, 0x06, 0x05, 0x04
13133 };
13134
13135 static hda_nid_t alc660_dac_nids[3] = {
13136 /* front, clfe, surround */
13137 0x03, 0x05, 0x06
13138 };
13139
13140 static hda_nid_t alc861_adc_nids[1] = {
13141 /* ADC0-2 */
13142 0x08,
13143 };
13144
13145 static struct hda_input_mux alc861_capture_source = {
13146 .num_items = 5,
13147 .items = {
13148 { "Mic", 0x0 },
13149 { "Front Mic", 0x3 },
13150 { "Line", 0x1 },
13151 { "CD", 0x4 },
13152 { "Mixer", 0x5 },
13153 },
13154 };
13155
13156 /* fill in the dac_nids table from the parsed pin configuration */
13157 static int alc861_auto_fill_dac_nids(struct alc_spec *spec,
13158 const struct auto_pin_cfg *cfg)
13159 {
13160 int i;
13161 hda_nid_t nid;
13162
13163 spec->multiout.dac_nids = spec->private_dac_nids;
13164 for (i = 0; i < cfg->line_outs; i++) {
13165 nid = cfg->line_out_pins[i];
13166 if (nid) {
13167 if (i >= ARRAY_SIZE(alc861_dac_nids))
13168 continue;
13169 spec->multiout.dac_nids[i] = alc861_dac_nids[i];
13170 }
13171 }
13172 spec->multiout.num_dacs = cfg->line_outs;
13173 return 0;
13174 }
13175
13176 /* add playback controls from the parsed DAC table */
13177 static int alc861_auto_create_multi_out_ctls(struct alc_spec *spec,
13178 const struct auto_pin_cfg *cfg)
13179 {
13180 char name[32];
13181 static const char *chname[4] = {
13182 "Front", "Surround", NULL /*CLFE*/, "Side"
13183 };
13184 hda_nid_t nid;
13185 int i, idx, err;
13186
13187 for (i = 0; i < cfg->line_outs; i++) {
13188 nid = spec->multiout.dac_nids[i];
13189 if (!nid)
13190 continue;
13191 if (nid == 0x05) {
13192 /* Center/LFE */
13193 err = add_control(spec, ALC_CTL_BIND_MUTE,
13194 "Center Playback Switch",
13195 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
13196 HDA_OUTPUT));
13197 if (err < 0)
13198 return err;
13199 err = add_control(spec, ALC_CTL_BIND_MUTE,
13200 "LFE Playback Switch",
13201 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
13202 HDA_OUTPUT));
13203 if (err < 0)
13204 return err;
13205 } else {
13206 for (idx = 0; idx < ARRAY_SIZE(alc861_dac_nids) - 1;
13207 idx++)
13208 if (nid == alc861_dac_nids[idx])
13209 break;
13210 sprintf(name, "%s Playback Switch", chname[idx]);
13211 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
13212 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
13213 HDA_OUTPUT));
13214 if (err < 0)
13215 return err;
13216 }
13217 }
13218 return 0;
13219 }
13220
13221 static int alc861_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin)
13222 {
13223 int err;
13224 hda_nid_t nid;
13225
13226 if (!pin)
13227 return 0;
13228
13229 if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
13230 nid = 0x03;
13231 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
13232 "Headphone Playback Switch",
13233 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
13234 if (err < 0)
13235 return err;
13236 spec->multiout.hp_nid = nid;
13237 }
13238 return 0;
13239 }
13240
13241 /* create playback/capture controls for input pins */
13242 static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec,
13243 const struct auto_pin_cfg *cfg)
13244 {
13245 struct hda_input_mux *imux = &spec->private_imux;
13246 int i, err, idx, idx1;
13247
13248 for (i = 0; i < AUTO_PIN_LAST; i++) {
13249 switch (cfg->input_pins[i]) {
13250 case 0x0c:
13251 idx1 = 1;
13252 idx = 2; /* Line In */
13253 break;
13254 case 0x0f:
13255 idx1 = 2;
13256 idx = 2; /* Line In */
13257 break;
13258 case 0x0d:
13259 idx1 = 0;
13260 idx = 1; /* Mic In */
13261 break;
13262 case 0x10:
13263 idx1 = 3;
13264 idx = 1; /* Mic In */
13265 break;
13266 case 0x11:
13267 idx1 = 4;
13268 idx = 0; /* CD */
13269 break;
13270 default:
13271 continue;
13272 }
13273
13274 err = new_analog_input(spec, cfg->input_pins[i],
13275 auto_pin_cfg_labels[i], idx, 0x15);
13276 if (err < 0)
13277 return err;
13278
13279 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
13280 imux->items[imux->num_items].index = idx1;
13281 imux->num_items++;
13282 }
13283 return 0;
13284 }
13285
13286 static struct snd_kcontrol_new alc861_capture_mixer[] = {
13287 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
13288 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
13289
13290 {
13291 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13292 /* The multiple "Capture Source" controls confuse alsamixer
13293 * So call somewhat different..
13294 */
13295 /* .name = "Capture Source", */
13296 .name = "Input Source",
13297 .count = 1,
13298 .info = alc_mux_enum_info,
13299 .get = alc_mux_enum_get,
13300 .put = alc_mux_enum_put,
13301 },
13302 { } /* end */
13303 };
13304
13305 static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
13306 hda_nid_t nid,
13307 int pin_type, int dac_idx)
13308 {
13309 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
13310 pin_type);
13311 snd_hda_codec_write(codec, dac_idx, 0, AC_VERB_SET_AMP_GAIN_MUTE,
13312 AMP_OUT_UNMUTE);
13313 }
13314
13315 static void alc861_auto_init_multi_out(struct hda_codec *codec)
13316 {
13317 struct alc_spec *spec = codec->spec;
13318 int i;
13319
13320 alc_subsystem_id(codec, 0x0e, 0x0f, 0x0b);
13321 for (i = 0; i < spec->autocfg.line_outs; i++) {
13322 hda_nid_t nid = spec->autocfg.line_out_pins[i];
13323 int pin_type = get_pin_type(spec->autocfg.line_out_type);
13324 if (nid)
13325 alc861_auto_set_output_and_unmute(codec, nid, pin_type,
13326 spec->multiout.dac_nids[i]);
13327 }
13328 }
13329
13330 static void alc861_auto_init_hp_out(struct hda_codec *codec)
13331 {
13332 struct alc_spec *spec = codec->spec;
13333 hda_nid_t pin;
13334
13335 pin = spec->autocfg.hp_pins[0];
13336 if (pin) /* connect to front */
13337 alc861_auto_set_output_and_unmute(codec, pin, PIN_HP,
13338 spec->multiout.dac_nids[0]);
13339 pin = spec->autocfg.speaker_pins[0];
13340 if (pin)
13341 alc861_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
13342 }
13343
13344 static void alc861_auto_init_analog_input(struct hda_codec *codec)
13345 {
13346 struct alc_spec *spec = codec->spec;
13347 int i;
13348
13349 for (i = 0; i < AUTO_PIN_LAST; i++) {
13350 hda_nid_t nid = spec->autocfg.input_pins[i];
13351 if (nid >= 0x0c && nid <= 0x11) {
13352 snd_hda_codec_write(codec, nid, 0,
13353 AC_VERB_SET_PIN_WIDGET_CONTROL,
13354 i <= AUTO_PIN_FRONT_MIC ?
13355 PIN_VREF80 : PIN_IN);
13356 }
13357 }
13358 }
13359
13360 /* parse the BIOS configuration and set up the alc_spec */
13361 /* return 1 if successful, 0 if the proper config is not found,
13362 * or a negative error code
13363 */
13364 static int alc861_parse_auto_config(struct hda_codec *codec)
13365 {
13366 struct alc_spec *spec = codec->spec;
13367 int err;
13368 static hda_nid_t alc861_ignore[] = { 0x1d, 0 };
13369
13370 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
13371 alc861_ignore);
13372 if (err < 0)
13373 return err;
13374 if (!spec->autocfg.line_outs)
13375 return 0; /* can't find valid BIOS pin config */
13376
13377 err = alc861_auto_fill_dac_nids(spec, &spec->autocfg);
13378 if (err < 0)
13379 return err;
13380 err = alc861_auto_create_multi_out_ctls(spec, &spec->autocfg);
13381 if (err < 0)
13382 return err;
13383 err = alc861_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
13384 if (err < 0)
13385 return err;
13386 err = alc861_auto_create_analog_input_ctls(spec, &spec->autocfg);
13387 if (err < 0)
13388 return err;
13389
13390 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
13391
13392 if (spec->autocfg.dig_out_pin)
13393 spec->multiout.dig_out_nid = ALC861_DIGOUT_NID;
13394
13395 if (spec->kctls.list)
13396 add_mixer(spec, spec->kctls.list);
13397
13398 add_verb(spec, alc861_auto_init_verbs);
13399
13400 spec->num_mux_defs = 1;
13401 spec->input_mux = &spec->private_imux;
13402
13403 spec->adc_nids = alc861_adc_nids;
13404 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
13405 add_mixer(spec, alc861_capture_mixer);
13406
13407 store_pin_configs(codec);
13408 return 1;
13409 }
13410
13411 /* additional initialization for auto-configuration model */
13412 static void alc861_auto_init(struct hda_codec *codec)
13413 {
13414 struct alc_spec *spec = codec->spec;
13415 alc861_auto_init_multi_out(codec);
13416 alc861_auto_init_hp_out(codec);
13417 alc861_auto_init_analog_input(codec);
13418 if (spec->unsol_event)
13419 alc_inithook(codec);
13420 }
13421
13422 #ifdef CONFIG_SND_HDA_POWER_SAVE
13423 static struct hda_amp_list alc861_loopbacks[] = {
13424 { 0x15, HDA_INPUT, 0 },
13425 { 0x15, HDA_INPUT, 1 },
13426 { 0x15, HDA_INPUT, 2 },
13427 { 0x15, HDA_INPUT, 3 },
13428 { } /* end */
13429 };
13430 #endif
13431
13432
13433 /*
13434 * configuration and preset
13435 */
13436 static const char *alc861_models[ALC861_MODEL_LAST] = {
13437 [ALC861_3ST] = "3stack",
13438 [ALC660_3ST] = "3stack-660",
13439 [ALC861_3ST_DIG] = "3stack-dig",
13440 [ALC861_6ST_DIG] = "6stack-dig",
13441 [ALC861_UNIWILL_M31] = "uniwill-m31",
13442 [ALC861_TOSHIBA] = "toshiba",
13443 [ALC861_ASUS] = "asus",
13444 [ALC861_ASUS_LAPTOP] = "asus-laptop",
13445 [ALC861_AUTO] = "auto",
13446 };
13447
13448 static struct snd_pci_quirk alc861_cfg_tbl[] = {
13449 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
13450 SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
13451 SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
13452 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
13453 SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
13454 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
13455 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
13456 /* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
13457 * Any other models that need this preset?
13458 */
13459 /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
13460 SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
13461 SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
13462 SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
13463 SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
13464 SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
13465 /* FIXME: the below seems conflict */
13466 /* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */
13467 SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
13468 SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
13469 {}
13470 };
13471
13472 static struct alc_config_preset alc861_presets[] = {
13473 [ALC861_3ST] = {
13474 .mixers = { alc861_3ST_mixer },
13475 .init_verbs = { alc861_threestack_init_verbs },
13476 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
13477 .dac_nids = alc861_dac_nids,
13478 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
13479 .channel_mode = alc861_threestack_modes,
13480 .need_dac_fix = 1,
13481 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13482 .adc_nids = alc861_adc_nids,
13483 .input_mux = &alc861_capture_source,
13484 },
13485 [ALC861_3ST_DIG] = {
13486 .mixers = { alc861_base_mixer },
13487 .init_verbs = { alc861_threestack_init_verbs },
13488 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
13489 .dac_nids = alc861_dac_nids,
13490 .dig_out_nid = ALC861_DIGOUT_NID,
13491 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
13492 .channel_mode = alc861_threestack_modes,
13493 .need_dac_fix = 1,
13494 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13495 .adc_nids = alc861_adc_nids,
13496 .input_mux = &alc861_capture_source,
13497 },
13498 [ALC861_6ST_DIG] = {
13499 .mixers = { alc861_base_mixer },
13500 .init_verbs = { alc861_base_init_verbs },
13501 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
13502 .dac_nids = alc861_dac_nids,
13503 .dig_out_nid = ALC861_DIGOUT_NID,
13504 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
13505 .channel_mode = alc861_8ch_modes,
13506 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13507 .adc_nids = alc861_adc_nids,
13508 .input_mux = &alc861_capture_source,
13509 },
13510 [ALC660_3ST] = {
13511 .mixers = { alc861_3ST_mixer },
13512 .init_verbs = { alc861_threestack_init_verbs },
13513 .num_dacs = ARRAY_SIZE(alc660_dac_nids),
13514 .dac_nids = alc660_dac_nids,
13515 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
13516 .channel_mode = alc861_threestack_modes,
13517 .need_dac_fix = 1,
13518 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13519 .adc_nids = alc861_adc_nids,
13520 .input_mux = &alc861_capture_source,
13521 },
13522 [ALC861_UNIWILL_M31] = {
13523 .mixers = { alc861_uniwill_m31_mixer },
13524 .init_verbs = { alc861_uniwill_m31_init_verbs },
13525 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
13526 .dac_nids = alc861_dac_nids,
13527 .dig_out_nid = ALC861_DIGOUT_NID,
13528 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
13529 .channel_mode = alc861_uniwill_m31_modes,
13530 .need_dac_fix = 1,
13531 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13532 .adc_nids = alc861_adc_nids,
13533 .input_mux = &alc861_capture_source,
13534 },
13535 [ALC861_TOSHIBA] = {
13536 .mixers = { alc861_toshiba_mixer },
13537 .init_verbs = { alc861_base_init_verbs,
13538 alc861_toshiba_init_verbs },
13539 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
13540 .dac_nids = alc861_dac_nids,
13541 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
13542 .channel_mode = alc883_3ST_2ch_modes,
13543 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13544 .adc_nids = alc861_adc_nids,
13545 .input_mux = &alc861_capture_source,
13546 .unsol_event = alc861_toshiba_unsol_event,
13547 .init_hook = alc861_toshiba_automute,
13548 },
13549 [ALC861_ASUS] = {
13550 .mixers = { alc861_asus_mixer },
13551 .init_verbs = { alc861_asus_init_verbs },
13552 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
13553 .dac_nids = alc861_dac_nids,
13554 .dig_out_nid = ALC861_DIGOUT_NID,
13555 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
13556 .channel_mode = alc861_asus_modes,
13557 .need_dac_fix = 1,
13558 .hp_nid = 0x06,
13559 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13560 .adc_nids = alc861_adc_nids,
13561 .input_mux = &alc861_capture_source,
13562 },
13563 [ALC861_ASUS_LAPTOP] = {
13564 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
13565 .init_verbs = { alc861_asus_init_verbs,
13566 alc861_asus_laptop_init_verbs },
13567 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
13568 .dac_nids = alc861_dac_nids,
13569 .dig_out_nid = ALC861_DIGOUT_NID,
13570 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
13571 .channel_mode = alc883_3ST_2ch_modes,
13572 .need_dac_fix = 1,
13573 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
13574 .adc_nids = alc861_adc_nids,
13575 .input_mux = &alc861_capture_source,
13576 },
13577 };
13578
13579
13580 static int patch_alc861(struct hda_codec *codec)
13581 {
13582 struct alc_spec *spec;
13583 int board_config;
13584 int err;
13585
13586 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
13587 if (spec == NULL)
13588 return -ENOMEM;
13589
13590 codec->spec = spec;
13591
13592 board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
13593 alc861_models,
13594 alc861_cfg_tbl);
13595
13596 if (board_config < 0) {
13597 printk(KERN_INFO "hda_codec: Unknown model for ALC861, "
13598 "trying auto-probe from BIOS...\n");
13599 board_config = ALC861_AUTO;
13600 }
13601
13602 if (board_config == ALC861_AUTO) {
13603 /* automatic parse from the BIOS config */
13604 err = alc861_parse_auto_config(codec);
13605 if (err < 0) {
13606 alc_free(codec);
13607 return err;
13608 } else if (!err) {
13609 printk(KERN_INFO
13610 "hda_codec: Cannot set up configuration "
13611 "from BIOS. Using base mode...\n");
13612 board_config = ALC861_3ST_DIG;
13613 }
13614 }
13615
13616 if (board_config != ALC861_AUTO)
13617 setup_preset(spec, &alc861_presets[board_config]);
13618
13619 spec->stream_name_analog = "ALC861 Analog";
13620 spec->stream_analog_playback = &alc861_pcm_analog_playback;
13621 spec->stream_analog_capture = &alc861_pcm_analog_capture;
13622
13623 spec->stream_name_digital = "ALC861 Digital";
13624 spec->stream_digital_playback = &alc861_pcm_digital_playback;
13625 spec->stream_digital_capture = &alc861_pcm_digital_capture;
13626
13627 spec->vmaster_nid = 0x03;
13628
13629 codec->patch_ops = alc_patch_ops;
13630 if (board_config == ALC861_AUTO)
13631 spec->init_hook = alc861_auto_init;
13632 #ifdef CONFIG_SND_HDA_POWER_SAVE
13633 if (!spec->loopback.amplist)
13634 spec->loopback.amplist = alc861_loopbacks;
13635 #endif
13636
13637 return 0;
13638 }
13639
13640 /*
13641 * ALC861-VD support
13642 *
13643 * Based on ALC882
13644 *
13645 * In addition, an independent DAC
13646 */
13647 #define ALC861VD_DIGOUT_NID 0x06
13648
13649 static hda_nid_t alc861vd_dac_nids[4] = {
13650 /* front, surr, clfe, side surr */
13651 0x02, 0x03, 0x04, 0x05
13652 };
13653
13654 /* dac_nids for ALC660vd are in a different order - according to
13655 * Realtek's driver.
13656 * This should probably tesult in a different mixer for 6stack models
13657 * of ALC660vd codecs, but for now there is only 3stack mixer
13658 * - and it is the same as in 861vd.
13659 * adc_nids in ALC660vd are (is) the same as in 861vd
13660 */
13661 static hda_nid_t alc660vd_dac_nids[3] = {
13662 /* front, rear, clfe, rear_surr */
13663 0x02, 0x04, 0x03
13664 };
13665
13666 static hda_nid_t alc861vd_adc_nids[1] = {
13667 /* ADC0 */
13668 0x09,
13669 };
13670
13671 static hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 };
13672
13673 /* input MUX */
13674 /* FIXME: should be a matrix-type input source selection */
13675 static struct hda_input_mux alc861vd_capture_source = {
13676 .num_items = 4,
13677 .items = {
13678 { "Mic", 0x0 },
13679 { "Front Mic", 0x1 },
13680 { "Line", 0x2 },
13681 { "CD", 0x4 },
13682 },
13683 };
13684
13685 static struct hda_input_mux alc861vd_dallas_capture_source = {
13686 .num_items = 2,
13687 .items = {
13688 { "Ext Mic", 0x0 },
13689 { "Int Mic", 0x1 },
13690 },
13691 };
13692
13693 static struct hda_input_mux alc861vd_hp_capture_source = {
13694 .num_items = 2,
13695 .items = {
13696 { "Front Mic", 0x0 },
13697 { "ATAPI Mic", 0x1 },
13698 },
13699 };
13700
13701 #define alc861vd_mux_enum_info alc_mux_enum_info
13702 #define alc861vd_mux_enum_get alc_mux_enum_get
13703 /* ALC861VD has the ALC882-type input selection (but has only one ADC) */
13704 #define alc861vd_mux_enum_put alc882_mux_enum_put
13705
13706 /*
13707 * 2ch mode
13708 */
13709 static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
13710 { 2, NULL }
13711 };
13712
13713 /*
13714 * 6ch mode
13715 */
13716 static struct hda_verb alc861vd_6stack_ch6_init[] = {
13717 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
13718 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13719 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13720 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13721 { } /* end */
13722 };
13723
13724 /*
13725 * 8ch mode
13726 */
13727 static struct hda_verb alc861vd_6stack_ch8_init[] = {
13728 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13729 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13730 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13731 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
13732 { } /* end */
13733 };
13734
13735 static struct hda_channel_mode alc861vd_6stack_modes[2] = {
13736 { 6, alc861vd_6stack_ch6_init },
13737 { 8, alc861vd_6stack_ch8_init },
13738 };
13739
13740 static struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
13741 {
13742 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13743 .name = "Channel Mode",
13744 .info = alc_ch_mode_info,
13745 .get = alc_ch_mode_get,
13746 .put = alc_ch_mode_put,
13747 },
13748 { } /* end */
13749 };
13750
13751 static struct snd_kcontrol_new alc861vd_capture_mixer[] = {
13752 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
13753 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
13754
13755 {
13756 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13757 /* The multiple "Capture Source" controls confuse alsamixer
13758 * So call somewhat different..
13759 */
13760 /* .name = "Capture Source", */
13761 .name = "Input Source",
13762 .count = 1,
13763 .info = alc861vd_mux_enum_info,
13764 .get = alc861vd_mux_enum_get,
13765 .put = alc861vd_mux_enum_put,
13766 },
13767 { } /* end */
13768 };
13769
13770 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
13771 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
13772 */
13773 static struct snd_kcontrol_new alc861vd_6st_mixer[] = {
13774 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13775 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
13776
13777 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13778 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
13779
13780 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
13781 HDA_OUTPUT),
13782 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
13783 HDA_OUTPUT),
13784 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
13785 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
13786
13787 HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
13788 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
13789
13790 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
13791
13792 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13793 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13794 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13795
13796 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
13797 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13798 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
13799
13800 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
13801 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
13802
13803 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
13804 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
13805
13806 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
13807 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
13808
13809 { } /* end */
13810 };
13811
13812 static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
13813 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13814 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
13815
13816 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
13817
13818 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13819 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13820 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13821
13822 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
13823 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13824 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
13825
13826 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
13827 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
13828
13829 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
13830 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
13831
13832 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
13833 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
13834
13835 { } /* end */
13836 };
13837
13838 static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
13839 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13840 /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
13841 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13842
13843 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
13844
13845 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13846 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13847 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13848
13849 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
13850 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13851 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
13852
13853 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
13854 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
13855
13856 { } /* end */
13857 };
13858
13859 /* Pin assignment: Speaker=0x14, HP = 0x15,
13860 * Ext Mic=0x18, Int Mic = 0x19, CD = 0x1c, PC Beep = 0x1d
13861 */
13862 static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
13863 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13864 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
13865 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13866 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
13867 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT),
13868 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13869 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13870 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
13871 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13872 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
13873 HDA_CODEC_VOLUME("PC Beep Volume", 0x0b, 0x05, HDA_INPUT),
13874 HDA_CODEC_MUTE("PC Beep Switch", 0x0b, 0x05, HDA_INPUT),
13875 { } /* end */
13876 };
13877
13878 /* Pin assignment: Speaker=0x14, Line-out = 0x15,
13879 * Front Mic=0x18, ATAPI Mic = 0x19,
13880 */
13881 static struct snd_kcontrol_new alc861vd_hp_mixer[] = {
13882 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13883 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
13884 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13885 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
13886 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13887 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13888 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
13889 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
13890
13891 { } /* end */
13892 };
13893
13894 /*
13895 * generic initialization of ADC, input mixers and output mixers
13896 */
13897 static struct hda_verb alc861vd_volume_init_verbs[] = {
13898 /*
13899 * Unmute ADC0 and set the default input to mic-in
13900 */
13901 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
13902 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13903
13904 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
13905 * the analog-loopback mixer widget
13906 */
13907 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
13908 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13909 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13910 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
13911 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
13912 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
13913
13914 /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
13915 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13916 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13917 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
13918 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
13919
13920 /*
13921 * Set up output mixers (0x02 - 0x05)
13922 */
13923 /* set vol=0 to output mixers */
13924 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13925 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13926 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13927 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13928
13929 /* set up input amps for analog loopback */
13930 /* Amp Indices: DAC = 0, mixer = 1 */
13931 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13932 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13933 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13934 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13935 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13936 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13937 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13938 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13939
13940 { }
13941 };
13942
13943 /*
13944 * 3-stack pin configuration:
13945 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
13946 */
13947 static struct hda_verb alc861vd_3stack_init_verbs[] = {
13948 /*
13949 * Set pin mode and muting
13950 */
13951 /* set front pin widgets 0x14 for output */
13952 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13953 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13954 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
13955
13956 /* Mic (rear) pin: input vref at 80% */
13957 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13958 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13959 /* Front Mic pin: input vref at 80% */
13960 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13961 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13962 /* Line In pin: input */
13963 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13964 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13965 /* Line-2 In: Headphone output (output 0 - 0x0c) */
13966 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13967 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13968 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
13969 /* CD pin widget for input */
13970 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13971
13972 { }
13973 };
13974
13975 /*
13976 * 6-stack pin configuration:
13977 */
13978 static struct hda_verb alc861vd_6stack_init_verbs[] = {
13979 /*
13980 * Set pin mode and muting
13981 */
13982 /* set front pin widgets 0x14 for output */
13983 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13984 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13985 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
13986
13987 /* Rear Pin: output 1 (0x0d) */
13988 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13989 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13990 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
13991 /* CLFE Pin: output 2 (0x0e) */
13992 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13993 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13994 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
13995 /* Side Pin: output 3 (0x0f) */
13996 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13997 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13998 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
13999
14000 /* Mic (rear) pin: input vref at 80% */
14001 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14002 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14003 /* Front Mic pin: input vref at 80% */
14004 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14005 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14006 /* Line In pin: input */
14007 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14008 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14009 /* Line-2 In: Headphone output (output 0 - 0x0c) */
14010 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14011 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14012 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
14013 /* CD pin widget for input */
14014 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14015
14016 { }
14017 };
14018
14019 static struct hda_verb alc861vd_eapd_verbs[] = {
14020 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14021 { }
14022 };
14023
14024 static struct hda_verb alc660vd_eapd_verbs[] = {
14025 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14026 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
14027 { }
14028 };
14029
14030 static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
14031 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14032 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14033 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
14034 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14035 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14036 {}
14037 };
14038
14039 /* toggle speaker-output according to the hp-jack state */
14040 static void alc861vd_lenovo_hp_automute(struct hda_codec *codec)
14041 {
14042 unsigned int present;
14043 unsigned char bits;
14044
14045 present = snd_hda_codec_read(codec, 0x1b, 0,
14046 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
14047 bits = present ? HDA_AMP_MUTE : 0;
14048 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
14049 HDA_AMP_MUTE, bits);
14050 }
14051
14052 static void alc861vd_lenovo_mic_automute(struct hda_codec *codec)
14053 {
14054 unsigned int present;
14055 unsigned char bits;
14056
14057 present = snd_hda_codec_read(codec, 0x18, 0,
14058 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
14059 bits = present ? HDA_AMP_MUTE : 0;
14060 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
14061 HDA_AMP_MUTE, bits);
14062 }
14063
14064 static void alc861vd_lenovo_automute(struct hda_codec *codec)
14065 {
14066 alc861vd_lenovo_hp_automute(codec);
14067 alc861vd_lenovo_mic_automute(codec);
14068 }
14069
14070 static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
14071 unsigned int res)
14072 {
14073 switch (res >> 26) {
14074 case ALC880_HP_EVENT:
14075 alc861vd_lenovo_hp_automute(codec);
14076 break;
14077 case ALC880_MIC_EVENT:
14078 alc861vd_lenovo_mic_automute(codec);
14079 break;
14080 }
14081 }
14082
14083 static struct hda_verb alc861vd_dallas_verbs[] = {
14084 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14085 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14086 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14087 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14088
14089 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14090 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14091 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14092 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14093 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14094 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14095 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14096 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14097
14098 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14099 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14100 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14101 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14102 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14103 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14104 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14105 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14106
14107 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
14108 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14109 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
14110 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
14111 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14112 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14113 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14114 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14115
14116 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14117 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
14118 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
14119 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
14120
14121 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14122 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
14123 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14124
14125 { } /* end */
14126 };
14127
14128 /* toggle speaker-output according to the hp-jack state */
14129 static void alc861vd_dallas_automute(struct hda_codec *codec)
14130 {
14131 unsigned int present;
14132
14133 present = snd_hda_codec_read(codec, 0x15, 0,
14134 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
14135 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
14136 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
14137 }
14138
14139 static void alc861vd_dallas_unsol_event(struct hda_codec *codec, unsigned int res)
14140 {
14141 if ((res >> 26) == ALC880_HP_EVENT)
14142 alc861vd_dallas_automute(codec);
14143 }
14144
14145 #ifdef CONFIG_SND_HDA_POWER_SAVE
14146 #define alc861vd_loopbacks alc880_loopbacks
14147 #endif
14148
14149 /* pcm configuration: identiacal with ALC880 */
14150 #define alc861vd_pcm_analog_playback alc880_pcm_analog_playback
14151 #define alc861vd_pcm_analog_capture alc880_pcm_analog_capture
14152 #define alc861vd_pcm_digital_playback alc880_pcm_digital_playback
14153 #define alc861vd_pcm_digital_capture alc880_pcm_digital_capture
14154
14155 /*
14156 * configuration and preset
14157 */
14158 static const char *alc861vd_models[ALC861VD_MODEL_LAST] = {
14159 [ALC660VD_3ST] = "3stack-660",
14160 [ALC660VD_3ST_DIG] = "3stack-660-digout",
14161 [ALC861VD_3ST] = "3stack",
14162 [ALC861VD_3ST_DIG] = "3stack-digout",
14163 [ALC861VD_6ST_DIG] = "6stack-digout",
14164 [ALC861VD_LENOVO] = "lenovo",
14165 [ALC861VD_DALLAS] = "dallas",
14166 [ALC861VD_HP] = "hp",
14167 [ALC861VD_AUTO] = "auto",
14168 };
14169
14170 static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
14171 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
14172 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
14173 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
14174 SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),
14175 SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC861VD_LENOVO),
14176 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
14177 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
14178 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
14179 /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
14180 SND_PCI_QUIRK(0x1179, 0xff01, "DALLAS", ALC861VD_DALLAS),
14181 SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
14182 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS),
14183 SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
14184 SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo", ALC861VD_LENOVO),
14185 SND_PCI_QUIRK(0x17aa, 0x3802, "Lenovo 3000 C200", ALC861VD_LENOVO),
14186 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 N200", ALC861VD_LENOVO),
14187 SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
14188 {}
14189 };
14190
14191 static struct alc_config_preset alc861vd_presets[] = {
14192 [ALC660VD_3ST] = {
14193 .mixers = { alc861vd_3st_mixer },
14194 .init_verbs = { alc861vd_volume_init_verbs,
14195 alc861vd_3stack_init_verbs },
14196 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14197 .dac_nids = alc660vd_dac_nids,
14198 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14199 .channel_mode = alc861vd_3stack_2ch_modes,
14200 .input_mux = &alc861vd_capture_source,
14201 },
14202 [ALC660VD_3ST_DIG] = {
14203 .mixers = { alc861vd_3st_mixer },
14204 .init_verbs = { alc861vd_volume_init_verbs,
14205 alc861vd_3stack_init_verbs },
14206 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14207 .dac_nids = alc660vd_dac_nids,
14208 .dig_out_nid = ALC861VD_DIGOUT_NID,
14209 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14210 .channel_mode = alc861vd_3stack_2ch_modes,
14211 .input_mux = &alc861vd_capture_source,
14212 },
14213 [ALC861VD_3ST] = {
14214 .mixers = { alc861vd_3st_mixer },
14215 .init_verbs = { alc861vd_volume_init_verbs,
14216 alc861vd_3stack_init_verbs },
14217 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14218 .dac_nids = alc861vd_dac_nids,
14219 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14220 .channel_mode = alc861vd_3stack_2ch_modes,
14221 .input_mux = &alc861vd_capture_source,
14222 },
14223 [ALC861VD_3ST_DIG] = {
14224 .mixers = { alc861vd_3st_mixer },
14225 .init_verbs = { alc861vd_volume_init_verbs,
14226 alc861vd_3stack_init_verbs },
14227 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14228 .dac_nids = alc861vd_dac_nids,
14229 .dig_out_nid = ALC861VD_DIGOUT_NID,
14230 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14231 .channel_mode = alc861vd_3stack_2ch_modes,
14232 .input_mux = &alc861vd_capture_source,
14233 },
14234 [ALC861VD_6ST_DIG] = {
14235 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
14236 .init_verbs = { alc861vd_volume_init_verbs,
14237 alc861vd_6stack_init_verbs },
14238 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14239 .dac_nids = alc861vd_dac_nids,
14240 .dig_out_nid = ALC861VD_DIGOUT_NID,
14241 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
14242 .channel_mode = alc861vd_6stack_modes,
14243 .input_mux = &alc861vd_capture_source,
14244 },
14245 [ALC861VD_LENOVO] = {
14246 .mixers = { alc861vd_lenovo_mixer },
14247 .init_verbs = { alc861vd_volume_init_verbs,
14248 alc861vd_3stack_init_verbs,
14249 alc861vd_eapd_verbs,
14250 alc861vd_lenovo_unsol_verbs },
14251 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14252 .dac_nids = alc660vd_dac_nids,
14253 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14254 .channel_mode = alc861vd_3stack_2ch_modes,
14255 .input_mux = &alc861vd_capture_source,
14256 .unsol_event = alc861vd_lenovo_unsol_event,
14257 .init_hook = alc861vd_lenovo_automute,
14258 },
14259 [ALC861VD_DALLAS] = {
14260 .mixers = { alc861vd_dallas_mixer },
14261 .init_verbs = { alc861vd_dallas_verbs },
14262 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14263 .dac_nids = alc861vd_dac_nids,
14264 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14265 .channel_mode = alc861vd_3stack_2ch_modes,
14266 .input_mux = &alc861vd_dallas_capture_source,
14267 .unsol_event = alc861vd_dallas_unsol_event,
14268 .init_hook = alc861vd_dallas_automute,
14269 },
14270 [ALC861VD_HP] = {
14271 .mixers = { alc861vd_hp_mixer },
14272 .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
14273 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
14274 .dac_nids = alc861vd_dac_nids,
14275 .dig_out_nid = ALC861VD_DIGOUT_NID,
14276 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14277 .channel_mode = alc861vd_3stack_2ch_modes,
14278 .input_mux = &alc861vd_hp_capture_source,
14279 .unsol_event = alc861vd_dallas_unsol_event,
14280 .init_hook = alc861vd_dallas_automute,
14281 },
14282 };
14283
14284 /*
14285 * BIOS auto configuration
14286 */
14287 static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
14288 hda_nid_t nid, int pin_type, int dac_idx)
14289 {
14290 alc_set_pin_output(codec, nid, pin_type);
14291 }
14292
14293 static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
14294 {
14295 struct alc_spec *spec = codec->spec;
14296 int i;
14297
14298 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
14299 for (i = 0; i <= HDA_SIDE; i++) {
14300 hda_nid_t nid = spec->autocfg.line_out_pins[i];
14301 int pin_type = get_pin_type(spec->autocfg.line_out_type);
14302 if (nid)
14303 alc861vd_auto_set_output_and_unmute(codec, nid,
14304 pin_type, i);
14305 }
14306 }
14307
14308
14309 static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
14310 {
14311 struct alc_spec *spec = codec->spec;
14312 hda_nid_t pin;
14313
14314 pin = spec->autocfg.hp_pins[0];
14315 if (pin) /* connect to front and use dac 0 */
14316 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
14317 pin = spec->autocfg.speaker_pins[0];
14318 if (pin)
14319 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
14320 }
14321
14322 #define alc861vd_is_input_pin(nid) alc880_is_input_pin(nid)
14323 #define ALC861VD_PIN_CD_NID ALC880_PIN_CD_NID
14324
14325 static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
14326 {
14327 struct alc_spec *spec = codec->spec;
14328 int i;
14329
14330 for (i = 0; i < AUTO_PIN_LAST; i++) {
14331 hda_nid_t nid = spec->autocfg.input_pins[i];
14332 if (alc861vd_is_input_pin(nid)) {
14333 snd_hda_codec_write(codec, nid, 0,
14334 AC_VERB_SET_PIN_WIDGET_CONTROL,
14335 i <= AUTO_PIN_FRONT_MIC ?
14336 PIN_VREF80 : PIN_IN);
14337 if (nid != ALC861VD_PIN_CD_NID)
14338 snd_hda_codec_write(codec, nid, 0,
14339 AC_VERB_SET_AMP_GAIN_MUTE,
14340 AMP_OUT_MUTE);
14341 }
14342 }
14343 }
14344
14345 #define alc861vd_auto_init_input_src alc882_auto_init_input_src
14346
14347 #define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02)
14348 #define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c)
14349
14350 /* add playback controls from the parsed DAC table */
14351 /* Based on ALC880 version. But ALC861VD has separate,
14352 * different NIDs for mute/unmute switch and volume control */
14353 static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
14354 const struct auto_pin_cfg *cfg)
14355 {
14356 char name[32];
14357 static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"};
14358 hda_nid_t nid_v, nid_s;
14359 int i, err;
14360
14361 for (i = 0; i < cfg->line_outs; i++) {
14362 if (!spec->multiout.dac_nids[i])
14363 continue;
14364 nid_v = alc861vd_idx_to_mixer_vol(
14365 alc880_dac_to_idx(
14366 spec->multiout.dac_nids[i]));
14367 nid_s = alc861vd_idx_to_mixer_switch(
14368 alc880_dac_to_idx(
14369 spec->multiout.dac_nids[i]));
14370
14371 if (i == 2) {
14372 /* Center/LFE */
14373 err = add_control(spec, ALC_CTL_WIDGET_VOL,
14374 "Center Playback Volume",
14375 HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
14376 HDA_OUTPUT));
14377 if (err < 0)
14378 return err;
14379 err = add_control(spec, ALC_CTL_WIDGET_VOL,
14380 "LFE Playback Volume",
14381 HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
14382 HDA_OUTPUT));
14383 if (err < 0)
14384 return err;
14385 err = add_control(spec, ALC_CTL_BIND_MUTE,
14386 "Center Playback Switch",
14387 HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
14388 HDA_INPUT));
14389 if (err < 0)
14390 return err;
14391 err = add_control(spec, ALC_CTL_BIND_MUTE,
14392 "LFE Playback Switch",
14393 HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
14394 HDA_INPUT));
14395 if (err < 0)
14396 return err;
14397 } else {
14398 sprintf(name, "%s Playback Volume", chname[i]);
14399 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
14400 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
14401 HDA_OUTPUT));
14402 if (err < 0)
14403 return err;
14404 sprintf(name, "%s Playback Switch", chname[i]);
14405 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
14406 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
14407 HDA_INPUT));
14408 if (err < 0)
14409 return err;
14410 }
14411 }
14412 return 0;
14413 }
14414
14415 /* add playback controls for speaker and HP outputs */
14416 /* Based on ALC880 version. But ALC861VD has separate,
14417 * different NIDs for mute/unmute switch and volume control */
14418 static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
14419 hda_nid_t pin, const char *pfx)
14420 {
14421 hda_nid_t nid_v, nid_s;
14422 int err;
14423 char name[32];
14424
14425 if (!pin)
14426 return 0;
14427
14428 if (alc880_is_fixed_pin(pin)) {
14429 nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
14430 /* specify the DAC as the extra output */
14431 if (!spec->multiout.hp_nid)
14432 spec->multiout.hp_nid = nid_v;
14433 else
14434 spec->multiout.extra_out_nid[0] = nid_v;
14435 /* control HP volume/switch on the output mixer amp */
14436 nid_v = alc861vd_idx_to_mixer_vol(
14437 alc880_fixed_pin_idx(pin));
14438 nid_s = alc861vd_idx_to_mixer_switch(
14439 alc880_fixed_pin_idx(pin));
14440
14441 sprintf(name, "%s Playback Volume", pfx);
14442 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
14443 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
14444 if (err < 0)
14445 return err;
14446 sprintf(name, "%s Playback Switch", pfx);
14447 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
14448 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
14449 if (err < 0)
14450 return err;
14451 } else if (alc880_is_multi_pin(pin)) {
14452 /* set manual connection */
14453 /* we have only a switch on HP-out PIN */
14454 sprintf(name, "%s Playback Switch", pfx);
14455 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
14456 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
14457 if (err < 0)
14458 return err;
14459 }
14460 return 0;
14461 }
14462
14463 /* parse the BIOS configuration and set up the alc_spec
14464 * return 1 if successful, 0 if the proper config is not found,
14465 * or a negative error code
14466 * Based on ALC880 version - had to change it to override
14467 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
14468 static int alc861vd_parse_auto_config(struct hda_codec *codec)
14469 {
14470 struct alc_spec *spec = codec->spec;
14471 int err;
14472 static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
14473
14474 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
14475 alc861vd_ignore);
14476 if (err < 0)
14477 return err;
14478 if (!spec->autocfg.line_outs)
14479 return 0; /* can't find valid BIOS pin config */
14480
14481 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
14482 if (err < 0)
14483 return err;
14484 err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
14485 if (err < 0)
14486 return err;
14487 err = alc861vd_auto_create_extra_out(spec,
14488 spec->autocfg.speaker_pins[0],
14489 "Speaker");
14490 if (err < 0)
14491 return err;
14492 err = alc861vd_auto_create_extra_out(spec,
14493 spec->autocfg.hp_pins[0],
14494 "Headphone");
14495 if (err < 0)
14496 return err;
14497 err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
14498 if (err < 0)
14499 return err;
14500
14501 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
14502
14503 if (spec->autocfg.dig_out_pin)
14504 spec->multiout.dig_out_nid = ALC861VD_DIGOUT_NID;
14505
14506 if (spec->kctls.list)
14507 add_mixer(spec, spec->kctls.list);
14508
14509 add_verb(spec, alc861vd_volume_init_verbs);
14510
14511 spec->num_mux_defs = 1;
14512 spec->input_mux = &spec->private_imux;
14513
14514 err = alc_auto_add_mic_boost(codec);
14515 if (err < 0)
14516 return err;
14517
14518 store_pin_configs(codec);
14519 return 1;
14520 }
14521
14522 /* additional initialization for auto-configuration model */
14523 static void alc861vd_auto_init(struct hda_codec *codec)
14524 {
14525 struct alc_spec *spec = codec->spec;
14526 alc861vd_auto_init_multi_out(codec);
14527 alc861vd_auto_init_hp_out(codec);
14528 alc861vd_auto_init_analog_input(codec);
14529 alc861vd_auto_init_input_src(codec);
14530 if (spec->unsol_event)
14531 alc_inithook(codec);
14532 }
14533
14534 static int patch_alc861vd(struct hda_codec *codec)
14535 {
14536 struct alc_spec *spec;
14537 int err, board_config;
14538
14539 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
14540 if (spec == NULL)
14541 return -ENOMEM;
14542
14543 codec->spec = spec;
14544
14545 board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
14546 alc861vd_models,
14547 alc861vd_cfg_tbl);
14548
14549 if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
14550 printk(KERN_INFO "hda_codec: Unknown model for ALC660VD/"
14551 "ALC861VD, trying auto-probe from BIOS...\n");
14552 board_config = ALC861VD_AUTO;
14553 }
14554
14555 if (board_config == ALC861VD_AUTO) {
14556 /* automatic parse from the BIOS config */
14557 err = alc861vd_parse_auto_config(codec);
14558 if (err < 0) {
14559 alc_free(codec);
14560 return err;
14561 } else if (!err) {
14562 printk(KERN_INFO
14563 "hda_codec: Cannot set up configuration "
14564 "from BIOS. Using base mode...\n");
14565 board_config = ALC861VD_3ST;
14566 }
14567 }
14568
14569 if (board_config != ALC861VD_AUTO)
14570 setup_preset(spec, &alc861vd_presets[board_config]);
14571
14572 if (codec->vendor_id == 0x10ec0660) {
14573 spec->stream_name_analog = "ALC660-VD Analog";
14574 spec->stream_name_digital = "ALC660-VD Digital";
14575 /* always turn on EAPD */
14576 add_verb(spec, alc660vd_eapd_verbs);
14577 } else {
14578 spec->stream_name_analog = "ALC861VD Analog";
14579 spec->stream_name_digital = "ALC861VD Digital";
14580 }
14581
14582 spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
14583 spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
14584
14585 spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
14586 spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
14587
14588 spec->adc_nids = alc861vd_adc_nids;
14589 spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
14590 spec->capsrc_nids = alc861vd_capsrc_nids;
14591
14592 add_mixer(spec, alc861vd_capture_mixer);
14593
14594 spec->vmaster_nid = 0x02;
14595
14596 codec->patch_ops = alc_patch_ops;
14597
14598 if (board_config == ALC861VD_AUTO)
14599 spec->init_hook = alc861vd_auto_init;
14600 #ifdef CONFIG_SND_HDA_POWER_SAVE
14601 if (!spec->loopback.amplist)
14602 spec->loopback.amplist = alc861vd_loopbacks;
14603 #endif
14604
14605 return 0;
14606 }
14607
14608 /*
14609 * ALC662 support
14610 *
14611 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
14612 * configuration. Each pin widget can choose any input DACs and a mixer.
14613 * Each ADC is connected from a mixer of all inputs. This makes possible
14614 * 6-channel independent captures.
14615 *
14616 * In addition, an independent DAC for the multi-playback (not used in this
14617 * driver yet).
14618 */
14619 #define ALC662_DIGOUT_NID 0x06
14620 #define ALC662_DIGIN_NID 0x0a
14621
14622 static hda_nid_t alc662_dac_nids[4] = {
14623 /* front, rear, clfe, rear_surr */
14624 0x02, 0x03, 0x04
14625 };
14626
14627 static hda_nid_t alc662_adc_nids[1] = {
14628 /* ADC1-2 */
14629 0x09,
14630 };
14631
14632 static hda_nid_t alc662_capsrc_nids[1] = { 0x22 };
14633
14634 /* input MUX */
14635 /* FIXME: should be a matrix-type input source selection */
14636 static struct hda_input_mux alc662_capture_source = {
14637 .num_items = 4,
14638 .items = {
14639 { "Mic", 0x0 },
14640 { "Front Mic", 0x1 },
14641 { "Line", 0x2 },
14642 { "CD", 0x4 },
14643 },
14644 };
14645
14646 static struct hda_input_mux alc662_lenovo_101e_capture_source = {
14647 .num_items = 2,
14648 .items = {
14649 { "Mic", 0x1 },
14650 { "Line", 0x2 },
14651 },
14652 };
14653
14654 static struct hda_input_mux alc662_eeepc_capture_source = {
14655 .num_items = 2,
14656 .items = {
14657 { "i-Mic", 0x1 },
14658 { "e-Mic", 0x0 },
14659 },
14660 };
14661
14662 static struct hda_input_mux alc663_capture_source = {
14663 .num_items = 3,
14664 .items = {
14665 { "Mic", 0x0 },
14666 { "Front Mic", 0x1 },
14667 { "Line", 0x2 },
14668 },
14669 };
14670
14671 static struct hda_input_mux alc663_m51va_capture_source = {
14672 .num_items = 2,
14673 .items = {
14674 { "Ext-Mic", 0x0 },
14675 { "D-Mic", 0x9 },
14676 },
14677 };
14678
14679 #define alc662_mux_enum_info alc_mux_enum_info
14680 #define alc662_mux_enum_get alc_mux_enum_get
14681 #define alc662_mux_enum_put alc882_mux_enum_put
14682
14683 /*
14684 * 2ch mode
14685 */
14686 static struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
14687 { 2, NULL }
14688 };
14689
14690 /*
14691 * 2ch mode
14692 */
14693 static struct hda_verb alc662_3ST_ch2_init[] = {
14694 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
14695 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
14696 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
14697 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
14698 { } /* end */
14699 };
14700
14701 /*
14702 * 6ch mode
14703 */
14704 static struct hda_verb alc662_3ST_ch6_init[] = {
14705 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14706 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
14707 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
14708 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14709 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
14710 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
14711 { } /* end */
14712 };
14713
14714 static struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
14715 { 2, alc662_3ST_ch2_init },
14716 { 6, alc662_3ST_ch6_init },
14717 };
14718
14719 /*
14720 * 2ch mode
14721 */
14722 static struct hda_verb alc662_sixstack_ch6_init[] = {
14723 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
14724 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
14725 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14726 { } /* end */
14727 };
14728
14729 /*
14730 * 6ch mode
14731 */
14732 static struct hda_verb alc662_sixstack_ch8_init[] = {
14733 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14734 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14735 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
14736 { } /* end */
14737 };
14738
14739 static struct hda_channel_mode alc662_5stack_modes[2] = {
14740 { 2, alc662_sixstack_ch6_init },
14741 { 6, alc662_sixstack_ch8_init },
14742 };
14743
14744 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
14745 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
14746 */
14747
14748 static struct snd_kcontrol_new alc662_base_mixer[] = {
14749 /* output mixer control */
14750 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
14751 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
14752 HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
14753 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
14754 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
14755 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
14756 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
14757 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
14758 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14759
14760 /*Input mixer control */
14761 HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
14762 HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
14763 HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
14764 HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
14765 HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
14766 HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
14767 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
14768 HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
14769 { } /* end */
14770 };
14771
14772 static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
14773 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14774 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
14775 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14776 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
14777 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
14778 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14779 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14780 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14781 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14782 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14783 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14784 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
14785 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
14786 { } /* end */
14787 };
14788
14789 static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
14790 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14791 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
14792 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14793 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
14794 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
14795 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
14796 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
14797 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
14798 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14799 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
14800 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
14801 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14802 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14803 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14804 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14805 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14806 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14807 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
14808 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
14809 { } /* end */
14810 };
14811
14812 static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
14813 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14814 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
14815 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14816 HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT),
14817 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14818 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14819 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14820 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14821 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14822 { } /* end */
14823 };
14824
14825 static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
14826 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14827
14828 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14829 HDA_CODEC_MUTE("Line-Out Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14830
14831 HDA_CODEC_VOLUME("e-Mic Boost", 0x18, 0, HDA_INPUT),
14832 HDA_CODEC_VOLUME("e-Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14833 HDA_CODEC_MUTE("e-Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14834
14835 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
14836 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14837 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14838 { } /* end */
14839 };
14840
14841 static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
14842 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14843 HDA_CODEC_MUTE("Line-Out Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14844 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14845 HDA_BIND_MUTE("Surround Playback Switch", 0x03, 2, HDA_INPUT),
14846 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
14847 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
14848 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT),
14849 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT),
14850 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14851 HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT),
14852 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14853 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14854 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14855 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14856 { } /* end */
14857 };
14858
14859 static struct hda_bind_ctls alc663_asus_bind_master_vol = {
14860 .ops = &snd_hda_bind_vol,
14861 .values = {
14862 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
14863 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
14864 0
14865 },
14866 };
14867
14868 static struct hda_bind_ctls alc663_asus_one_bind_switch = {
14869 .ops = &snd_hda_bind_sw,
14870 .values = {
14871 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14872 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
14873 0
14874 },
14875 };
14876
14877 static struct snd_kcontrol_new alc663_m51va_mixer[] = {
14878 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
14879 HDA_BIND_SW("Master Playback Switch", &alc663_asus_one_bind_switch),
14880 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14881 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14882 { } /* end */
14883 };
14884
14885 static struct hda_bind_ctls alc663_asus_tree_bind_switch = {
14886 .ops = &snd_hda_bind_sw,
14887 .values = {
14888 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14889 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
14890 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
14891 0
14892 },
14893 };
14894
14895 static struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = {
14896 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
14897 HDA_BIND_SW("Master Playback Switch", &alc663_asus_tree_bind_switch),
14898 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14899 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14900 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14901 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14902
14903 { } /* end */
14904 };
14905
14906 static struct hda_bind_ctls alc663_asus_four_bind_switch = {
14907 .ops = &snd_hda_bind_sw,
14908 .values = {
14909 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14910 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
14911 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
14912 0
14913 },
14914 };
14915
14916 static struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = {
14917 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
14918 HDA_BIND_SW("Master Playback Switch", &alc663_asus_four_bind_switch),
14919 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14920 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14921 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14922 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14923 { } /* end */
14924 };
14925
14926 static struct snd_kcontrol_new alc662_1bjd_mixer[] = {
14927 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14928 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14929 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
14930 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14931 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14932 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14933 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14934 { } /* end */
14935 };
14936
14937 static struct hda_bind_ctls alc663_asus_two_bind_master_vol = {
14938 .ops = &snd_hda_bind_vol,
14939 .values = {
14940 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
14941 HDA_COMPOSE_AMP_VAL(0x04, 3, 0, HDA_OUTPUT),
14942 0
14943 },
14944 };
14945
14946 static struct hda_bind_ctls alc663_asus_two_bind_switch = {
14947 .ops = &snd_hda_bind_sw,
14948 .values = {
14949 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14950 HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT),
14951 0
14952 },
14953 };
14954
14955 static struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = {
14956 HDA_BIND_VOL("Master Playback Volume",
14957 &alc663_asus_two_bind_master_vol),
14958 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
14959 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14960 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
14961 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14962 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14963 { } /* end */
14964 };
14965
14966 static struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = {
14967 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
14968 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
14969 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14970 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
14971 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14972 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14973 { } /* end */
14974 };
14975
14976 static struct snd_kcontrol_new alc663_g71v_mixer[] = {
14977 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14978 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14979 HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14980 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
14981 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
14982
14983 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14984 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14985 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14986 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14987 { } /* end */
14988 };
14989
14990 static struct snd_kcontrol_new alc663_g50v_mixer[] = {
14991 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14992 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14993 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
14994
14995 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14996 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14997 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
14998 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
14999 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15000 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15001 { } /* end */
15002 };
15003
15004 static struct snd_kcontrol_new alc662_chmode_mixer[] = {
15005 {
15006 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15007 .name = "Channel Mode",
15008 .info = alc_ch_mode_info,
15009 .get = alc_ch_mode_get,
15010 .put = alc_ch_mode_put,
15011 },
15012 { } /* end */
15013 };
15014
15015 static struct hda_verb alc662_init_verbs[] = {
15016 /* ADC: mute amp left and right */
15017 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15018 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
15019 /* Front mixer: unmute input/output amp left and right (volume = 0) */
15020
15021 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15022 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15023 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15024 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
15025 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
15026
15027 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15028 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15029 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15030 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15031 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15032 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15033
15034 /* Front Pin: output 0 (0x0c) */
15035 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15036 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15037
15038 /* Rear Pin: output 1 (0x0d) */
15039 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15040 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15041
15042 /* CLFE Pin: output 2 (0x0e) */
15043 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15044 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15045
15046 /* Mic (rear) pin: input vref at 80% */
15047 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
15048 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15049 /* Front Mic pin: input vref at 80% */
15050 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
15051 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15052 /* Line In pin: input */
15053 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15054 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15055 /* Line-2 In: Headphone output (output 0 - 0x0c) */
15056 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15057 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15058 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
15059 /* CD pin widget for input */
15060 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15061
15062 /* FIXME: use matrix-type input source selection */
15063 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
15064 /* Input mixer */
15065 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15066 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15067 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15068 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
15069
15070 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15071 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15072 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15073 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
15074
15075 /* always trun on EAPD */
15076 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
15077 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
15078
15079 { }
15080 };
15081
15082 static struct hda_verb alc662_sue_init_verbs[] = {
15083 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
15084 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
15085 {}
15086 };
15087
15088 static struct hda_verb alc662_eeepc_sue_init_verbs[] = {
15089 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15090 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15091 {}
15092 };
15093
15094 /* Set Unsolicited Event*/
15095 static struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
15096 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
15097 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15098 {}
15099 };
15100
15101 /*
15102 * generic initialization of ADC, input mixers and output mixers
15103 */
15104 static struct hda_verb alc662_auto_init_verbs[] = {
15105 /*
15106 * Unmute ADC and set the default input to mic-in
15107 */
15108 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
15109 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15110
15111 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
15112 * mixer widget
15113 * Note: PASD motherboards uses the Line In 2 as the input for front
15114 * panel mic (mic 2)
15115 */
15116 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
15117 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15118 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15119 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15120 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
15121 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
15122
15123 /*
15124 * Set up output mixers (0x0c - 0x0f)
15125 */
15126 /* set vol=0 to output mixers */
15127 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15128 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15129 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
15130
15131 /* set up input amps for analog loopback */
15132 /* Amp Indices: DAC = 0, mixer = 1 */
15133 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15134 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15135 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15136 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15137 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15138 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15139
15140
15141 /* FIXME: use matrix-type input source selection */
15142 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
15143 /* Input mixer */
15144 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15145 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15146 { }
15147 };
15148
15149 /* additional verbs for ALC663 */
15150 static struct hda_verb alc663_auto_init_verbs[] = {
15151 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15152 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15153 { }
15154 };
15155
15156 static struct hda_verb alc663_m51va_init_verbs[] = {
15157 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15158 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15159 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15160 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15161 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15162 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15163 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
15164 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15165 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15166 {}
15167 };
15168
15169 static struct hda_verb alc663_21jd_amic_init_verbs[] = {
15170 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15171 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15172 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15173 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15174 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15175 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15176 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15177 {}
15178 };
15179
15180 static struct hda_verb alc662_1bjd_amic_init_verbs[] = {
15181 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15182 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15183 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15184 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
15185 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15186 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15187 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15188 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15189 {}
15190 };
15191
15192 static struct hda_verb alc663_15jd_amic_init_verbs[] = {
15193 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15194 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15195 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15196 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15197 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15198 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15199 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15200 {}
15201 };
15202
15203 static struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = {
15204 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15205 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15206 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15207 {0x21, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
15208 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15209 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15210 {0x15, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
15211 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15212 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15213 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15214 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15215 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15216 {}
15217 };
15218
15219 static struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = {
15220 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
15221 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15222 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15223 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15224 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15225 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15226 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
15227 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15228 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15229 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15230 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15231 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15232 {}
15233 };
15234
15235 static struct hda_verb alc663_g71v_init_verbs[] = {
15236 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15237 /* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
15238 /* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */
15239
15240 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15241 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15242 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
15243
15244 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
15245 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_MIC_EVENT},
15246 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
15247 {}
15248 };
15249
15250 static struct hda_verb alc663_g50v_init_verbs[] = {
15251 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
15252 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15253 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
15254
15255 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15256 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15257 {}
15258 };
15259
15260 static struct hda_verb alc662_ecs_init_verbs[] = {
15261 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f},
15262 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15263 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
15264 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15265 {}
15266 };
15267
15268 /* capture mixer elements */
15269 static struct snd_kcontrol_new alc662_capture_mixer[] = {
15270 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
15271 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
15272 {
15273 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15274 /* The multiple "Capture Source" controls confuse alsamixer
15275 * So call somewhat different..
15276 */
15277 /* .name = "Capture Source", */
15278 .name = "Input Source",
15279 .count = 1,
15280 .info = alc662_mux_enum_info,
15281 .get = alc662_mux_enum_get,
15282 .put = alc662_mux_enum_put,
15283 },
15284 { } /* end */
15285 };
15286
15287 static struct snd_kcontrol_new alc662_auto_capture_mixer[] = {
15288 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
15289 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
15290 { } /* end */
15291 };
15292
15293 static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
15294 {
15295 unsigned int present;
15296 unsigned char bits;
15297
15298 present = snd_hda_codec_read(codec, 0x14, 0,
15299 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
15300 bits = present ? HDA_AMP_MUTE : 0;
15301 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
15302 HDA_AMP_MUTE, bits);
15303 }
15304
15305 static void alc662_lenovo_101e_all_automute(struct hda_codec *codec)
15306 {
15307 unsigned int present;
15308 unsigned char bits;
15309
15310 present = snd_hda_codec_read(codec, 0x1b, 0,
15311 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
15312 bits = present ? HDA_AMP_MUTE : 0;
15313 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
15314 HDA_AMP_MUTE, bits);
15315 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
15316 HDA_AMP_MUTE, bits);
15317 }
15318
15319 static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec,
15320 unsigned int res)
15321 {
15322 if ((res >> 26) == ALC880_HP_EVENT)
15323 alc662_lenovo_101e_all_automute(codec);
15324 if ((res >> 26) == ALC880_FRONT_EVENT)
15325 alc662_lenovo_101e_ispeaker_automute(codec);
15326 }
15327
15328 static void alc662_eeepc_mic_automute(struct hda_codec *codec)
15329 {
15330 unsigned int present;
15331
15332 present = snd_hda_codec_read(codec, 0x18, 0,
15333 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
15334 snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15335 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
15336 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15337 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
15338 snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15339 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
15340 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15341 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
15342 }
15343
15344 /* unsolicited event for HP jack sensing */
15345 static void alc662_eeepc_unsol_event(struct hda_codec *codec,
15346 unsigned int res)
15347 {
15348 if ((res >> 26) == ALC880_HP_EVENT)
15349 alc262_hippo1_automute( codec );
15350
15351 if ((res >> 26) == ALC880_MIC_EVENT)
15352 alc662_eeepc_mic_automute(codec);
15353 }
15354
15355 static void alc662_eeepc_inithook(struct hda_codec *codec)
15356 {
15357 alc262_hippo1_automute( codec );
15358 alc662_eeepc_mic_automute(codec);
15359 }
15360
15361 static void alc662_eeepc_ep20_automute(struct hda_codec *codec)
15362 {
15363 unsigned int mute;
15364 unsigned int present;
15365
15366 snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
15367 present = snd_hda_codec_read(codec, 0x14, 0,
15368 AC_VERB_GET_PIN_SENSE, 0);
15369 present = (present & 0x80000000) != 0;
15370 if (present) {
15371 /* mute internal speaker */
15372 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
15373 HDA_AMP_MUTE, HDA_AMP_MUTE);
15374 } else {
15375 /* unmute internal speaker if necessary */
15376 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
15377 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
15378 HDA_AMP_MUTE, mute);
15379 }
15380 }
15381
15382 /* unsolicited event for HP jack sensing */
15383 static void alc662_eeepc_ep20_unsol_event(struct hda_codec *codec,
15384 unsigned int res)
15385 {
15386 if ((res >> 26) == ALC880_HP_EVENT)
15387 alc662_eeepc_ep20_automute(codec);
15388 }
15389
15390 static void alc662_eeepc_ep20_inithook(struct hda_codec *codec)
15391 {
15392 alc662_eeepc_ep20_automute(codec);
15393 }
15394
15395 static void alc663_m51va_speaker_automute(struct hda_codec *codec)
15396 {
15397 unsigned int present;
15398 unsigned char bits;
15399
15400 present = snd_hda_codec_read(codec, 0x21, 0,
15401 AC_VERB_GET_PIN_SENSE, 0)
15402 & AC_PINSENSE_PRESENCE;
15403 bits = present ? HDA_AMP_MUTE : 0;
15404 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
15405 AMP_IN_MUTE(0), bits);
15406 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
15407 AMP_IN_MUTE(0), bits);
15408 }
15409
15410 static void alc663_21jd_two_speaker_automute(struct hda_codec *codec)
15411 {
15412 unsigned int present;
15413 unsigned char bits;
15414
15415 present = snd_hda_codec_read(codec, 0x21, 0,
15416 AC_VERB_GET_PIN_SENSE, 0)
15417 & AC_PINSENSE_PRESENCE;
15418 bits = present ? HDA_AMP_MUTE : 0;
15419 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
15420 AMP_IN_MUTE(0), bits);
15421 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
15422 AMP_IN_MUTE(0), bits);
15423 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
15424 AMP_IN_MUTE(0), bits);
15425 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
15426 AMP_IN_MUTE(0), bits);
15427 }
15428
15429 static void alc663_15jd_two_speaker_automute(struct hda_codec *codec)
15430 {
15431 unsigned int present;
15432 unsigned char bits;
15433
15434 present = snd_hda_codec_read(codec, 0x15, 0,
15435 AC_VERB_GET_PIN_SENSE, 0)
15436 & AC_PINSENSE_PRESENCE;
15437 bits = present ? HDA_AMP_MUTE : 0;
15438 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
15439 AMP_IN_MUTE(0), bits);
15440 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
15441 AMP_IN_MUTE(0), bits);
15442 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0,
15443 AMP_IN_MUTE(0), bits);
15444 snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1,
15445 AMP_IN_MUTE(0), bits);
15446 }
15447
15448 static void alc662_f5z_speaker_automute(struct hda_codec *codec)
15449 {
15450 unsigned int present;
15451 unsigned char bits;
15452
15453 present = snd_hda_codec_read(codec, 0x1b, 0,
15454 AC_VERB_GET_PIN_SENSE, 0)
15455 & AC_PINSENSE_PRESENCE;
15456 bits = present ? 0 : PIN_OUT;
15457 snd_hda_codec_write(codec, 0x14, 0,
15458 AC_VERB_SET_PIN_WIDGET_CONTROL, bits);
15459 }
15460
15461 static void alc663_two_hp_m1_speaker_automute(struct hda_codec *codec)
15462 {
15463 unsigned int present1, present2;
15464
15465 present1 = snd_hda_codec_read(codec, 0x21, 0,
15466 AC_VERB_GET_PIN_SENSE, 0)
15467 & AC_PINSENSE_PRESENCE;
15468 present2 = snd_hda_codec_read(codec, 0x15, 0,
15469 AC_VERB_GET_PIN_SENSE, 0)
15470 & AC_PINSENSE_PRESENCE;
15471
15472 if (present1 || present2) {
15473 snd_hda_codec_write_cache(codec, 0x14, 0,
15474 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
15475 } else {
15476 snd_hda_codec_write_cache(codec, 0x14, 0,
15477 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
15478 }
15479 }
15480
15481 static void alc663_two_hp_m2_speaker_automute(struct hda_codec *codec)
15482 {
15483 unsigned int present1, present2;
15484
15485 present1 = snd_hda_codec_read(codec, 0x1b, 0,
15486 AC_VERB_GET_PIN_SENSE, 0)
15487 & AC_PINSENSE_PRESENCE;
15488 present2 = snd_hda_codec_read(codec, 0x15, 0,
15489 AC_VERB_GET_PIN_SENSE, 0)
15490 & AC_PINSENSE_PRESENCE;
15491
15492 if (present1 || present2) {
15493 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
15494 AMP_IN_MUTE(0), AMP_IN_MUTE(0));
15495 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
15496 AMP_IN_MUTE(0), AMP_IN_MUTE(0));
15497 } else {
15498 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
15499 AMP_IN_MUTE(0), 0);
15500 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
15501 AMP_IN_MUTE(0), 0);
15502 }
15503 }
15504
15505 static void alc663_m51va_mic_automute(struct hda_codec *codec)
15506 {
15507 unsigned int present;
15508
15509 present = snd_hda_codec_read(codec, 0x18, 0,
15510 AC_VERB_GET_PIN_SENSE, 0)
15511 & AC_PINSENSE_PRESENCE;
15512 snd_hda_codec_write_cache(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15513 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
15514 snd_hda_codec_write_cache(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15515 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
15516 snd_hda_codec_write_cache(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15517 0x7000 | (0x09 << 8) | (present ? 0x80 : 0));
15518 snd_hda_codec_write_cache(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15519 0x7000 | (0x09 << 8) | (present ? 0x80 : 0));
15520 }
15521
15522 static void alc663_m51va_unsol_event(struct hda_codec *codec,
15523 unsigned int res)
15524 {
15525 switch (res >> 26) {
15526 case ALC880_HP_EVENT:
15527 alc663_m51va_speaker_automute(codec);
15528 break;
15529 case ALC880_MIC_EVENT:
15530 alc663_m51va_mic_automute(codec);
15531 break;
15532 }
15533 }
15534
15535 static void alc663_m51va_inithook(struct hda_codec *codec)
15536 {
15537 alc663_m51va_speaker_automute(codec);
15538 alc663_m51va_mic_automute(codec);
15539 }
15540
15541 /* ***************** Mode1 ******************************/
15542 static void alc663_mode1_unsol_event(struct hda_codec *codec,
15543 unsigned int res)
15544 {
15545 switch (res >> 26) {
15546 case ALC880_HP_EVENT:
15547 alc663_m51va_speaker_automute(codec);
15548 break;
15549 case ALC880_MIC_EVENT:
15550 alc662_eeepc_mic_automute(codec);
15551 break;
15552 }
15553 }
15554
15555 static void alc663_mode1_inithook(struct hda_codec *codec)
15556 {
15557 alc663_m51va_speaker_automute(codec);
15558 alc662_eeepc_mic_automute(codec);
15559 }
15560 /* ***************** Mode2 ******************************/
15561 static void alc662_mode2_unsol_event(struct hda_codec *codec,
15562 unsigned int res)
15563 {
15564 switch (res >> 26) {
15565 case ALC880_HP_EVENT:
15566 alc662_f5z_speaker_automute(codec);
15567 break;
15568 case ALC880_MIC_EVENT:
15569 alc662_eeepc_mic_automute(codec);
15570 break;
15571 }
15572 }
15573
15574 static void alc662_mode2_inithook(struct hda_codec *codec)
15575 {
15576 alc662_f5z_speaker_automute(codec);
15577 alc662_eeepc_mic_automute(codec);
15578 }
15579 /* ***************** Mode3 ******************************/
15580 static void alc663_mode3_unsol_event(struct hda_codec *codec,
15581 unsigned int res)
15582 {
15583 switch (res >> 26) {
15584 case ALC880_HP_EVENT:
15585 alc663_two_hp_m1_speaker_automute(codec);
15586 break;
15587 case ALC880_MIC_EVENT:
15588 alc662_eeepc_mic_automute(codec);
15589 break;
15590 }
15591 }
15592
15593 static void alc663_mode3_inithook(struct hda_codec *codec)
15594 {
15595 alc663_two_hp_m1_speaker_automute(codec);
15596 alc662_eeepc_mic_automute(codec);
15597 }
15598 /* ***************** Mode4 ******************************/
15599 static void alc663_mode4_unsol_event(struct hda_codec *codec,
15600 unsigned int res)
15601 {
15602 switch (res >> 26) {
15603 case ALC880_HP_EVENT:
15604 alc663_21jd_two_speaker_automute(codec);
15605 break;
15606 case ALC880_MIC_EVENT:
15607 alc662_eeepc_mic_automute(codec);
15608 break;
15609 }
15610 }
15611
15612 static void alc663_mode4_inithook(struct hda_codec *codec)
15613 {
15614 alc663_21jd_two_speaker_automute(codec);
15615 alc662_eeepc_mic_automute(codec);
15616 }
15617 /* ***************** Mode5 ******************************/
15618 static void alc663_mode5_unsol_event(struct hda_codec *codec,
15619 unsigned int res)
15620 {
15621 switch (res >> 26) {
15622 case ALC880_HP_EVENT:
15623 alc663_15jd_two_speaker_automute(codec);
15624 break;
15625 case ALC880_MIC_EVENT:
15626 alc662_eeepc_mic_automute(codec);
15627 break;
15628 }
15629 }
15630
15631 static void alc663_mode5_inithook(struct hda_codec *codec)
15632 {
15633 alc663_15jd_two_speaker_automute(codec);
15634 alc662_eeepc_mic_automute(codec);
15635 }
15636 /* ***************** Mode6 ******************************/
15637 static void alc663_mode6_unsol_event(struct hda_codec *codec,
15638 unsigned int res)
15639 {
15640 switch (res >> 26) {
15641 case ALC880_HP_EVENT:
15642 alc663_two_hp_m2_speaker_automute(codec);
15643 break;
15644 case ALC880_MIC_EVENT:
15645 alc662_eeepc_mic_automute(codec);
15646 break;
15647 }
15648 }
15649
15650 static void alc663_mode6_inithook(struct hda_codec *codec)
15651 {
15652 alc663_two_hp_m2_speaker_automute(codec);
15653 alc662_eeepc_mic_automute(codec);
15654 }
15655
15656 static void alc663_g71v_hp_automute(struct hda_codec *codec)
15657 {
15658 unsigned int present;
15659 unsigned char bits;
15660
15661 present = snd_hda_codec_read(codec, 0x21, 0,
15662 AC_VERB_GET_PIN_SENSE, 0)
15663 & AC_PINSENSE_PRESENCE;
15664 bits = present ? HDA_AMP_MUTE : 0;
15665 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
15666 HDA_AMP_MUTE, bits);
15667 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
15668 HDA_AMP_MUTE, bits);
15669 }
15670
15671 static void alc663_g71v_front_automute(struct hda_codec *codec)
15672 {
15673 unsigned int present;
15674 unsigned char bits;
15675
15676 present = snd_hda_codec_read(codec, 0x15, 0,
15677 AC_VERB_GET_PIN_SENSE, 0)
15678 & AC_PINSENSE_PRESENCE;
15679 bits = present ? HDA_AMP_MUTE : 0;
15680 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
15681 HDA_AMP_MUTE, bits);
15682 }
15683
15684 static void alc663_g71v_unsol_event(struct hda_codec *codec,
15685 unsigned int res)
15686 {
15687 switch (res >> 26) {
15688 case ALC880_HP_EVENT:
15689 alc663_g71v_hp_automute(codec);
15690 break;
15691 case ALC880_FRONT_EVENT:
15692 alc663_g71v_front_automute(codec);
15693 break;
15694 case ALC880_MIC_EVENT:
15695 alc662_eeepc_mic_automute(codec);
15696 break;
15697 }
15698 }
15699
15700 static void alc663_g71v_inithook(struct hda_codec *codec)
15701 {
15702 alc663_g71v_front_automute(codec);
15703 alc663_g71v_hp_automute(codec);
15704 alc662_eeepc_mic_automute(codec);
15705 }
15706
15707 static void alc663_g50v_unsol_event(struct hda_codec *codec,
15708 unsigned int res)
15709 {
15710 switch (res >> 26) {
15711 case ALC880_HP_EVENT:
15712 alc663_m51va_speaker_automute(codec);
15713 break;
15714 case ALC880_MIC_EVENT:
15715 alc662_eeepc_mic_automute(codec);
15716 break;
15717 }
15718 }
15719
15720 static void alc663_g50v_inithook(struct hda_codec *codec)
15721 {
15722 alc663_m51va_speaker_automute(codec);
15723 alc662_eeepc_mic_automute(codec);
15724 }
15725
15726 /* bind hp and internal speaker mute (with plug check) */
15727 static int alc662_ecs_master_sw_put(struct snd_kcontrol *kcontrol,
15728 struct snd_ctl_elem_value *ucontrol)
15729 {
15730 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
15731 long *valp = ucontrol->value.integer.value;
15732 int change;
15733
15734 change = snd_hda_codec_amp_update(codec, 0x1b, 0, HDA_OUTPUT, 0,
15735 HDA_AMP_MUTE,
15736 valp[0] ? 0 : HDA_AMP_MUTE);
15737 change |= snd_hda_codec_amp_update(codec, 0x1b, 1, HDA_OUTPUT, 0,
15738 HDA_AMP_MUTE,
15739 valp[1] ? 0 : HDA_AMP_MUTE);
15740 if (change)
15741 alc262_hippo1_automute(codec);
15742 return change;
15743 }
15744
15745 static struct snd_kcontrol_new alc662_ecs_mixer[] = {
15746 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15747 {
15748 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15749 .name = "Master Playback Switch",
15750 .info = snd_hda_mixer_amp_switch_info,
15751 .get = snd_hda_mixer_amp_switch_get,
15752 .put = alc662_ecs_master_sw_put,
15753 .private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
15754 },
15755
15756 HDA_CODEC_VOLUME("e-Mic/LineIn Boost", 0x18, 0, HDA_INPUT),
15757 HDA_CODEC_VOLUME("e-Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT),
15758 HDA_CODEC_MUTE("e-Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT),
15759
15760 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
15761 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15762 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15763 { } /* end */
15764 };
15765
15766 #ifdef CONFIG_SND_HDA_POWER_SAVE
15767 #define alc662_loopbacks alc880_loopbacks
15768 #endif
15769
15770
15771 /* pcm configuration: identiacal with ALC880 */
15772 #define alc662_pcm_analog_playback alc880_pcm_analog_playback
15773 #define alc662_pcm_analog_capture alc880_pcm_analog_capture
15774 #define alc662_pcm_digital_playback alc880_pcm_digital_playback
15775 #define alc662_pcm_digital_capture alc880_pcm_digital_capture
15776
15777 /*
15778 * configuration and preset
15779 */
15780 static const char *alc662_models[ALC662_MODEL_LAST] = {
15781 [ALC662_3ST_2ch_DIG] = "3stack-dig",
15782 [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig",
15783 [ALC662_3ST_6ch] = "3stack-6ch",
15784 [ALC662_5ST_DIG] = "6stack-dig",
15785 [ALC662_LENOVO_101E] = "lenovo-101e",
15786 [ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
15787 [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
15788 [ALC662_ECS] = "ecs",
15789 [ALC663_ASUS_M51VA] = "m51va",
15790 [ALC663_ASUS_G71V] = "g71v",
15791 [ALC663_ASUS_H13] = "h13",
15792 [ALC663_ASUS_G50V] = "g50v",
15793 [ALC663_ASUS_MODE1] = "asus-mode1",
15794 [ALC662_ASUS_MODE2] = "asus-mode2",
15795 [ALC663_ASUS_MODE3] = "asus-mode3",
15796 [ALC663_ASUS_MODE4] = "asus-mode4",
15797 [ALC663_ASUS_MODE5] = "asus-mode5",
15798 [ALC663_ASUS_MODE6] = "asus-mode6",
15799 [ALC662_AUTO] = "auto",
15800 };
15801
15802 static struct snd_pci_quirk alc662_cfg_tbl[] = {
15803 SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA),
15804 SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS G50V", ALC663_ASUS_G50V),
15805 SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG),
15806 SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
15807 SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
15808 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1),
15809 SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1),
15810 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1),
15811 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1),
15812 SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1),
15813 SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1),
15814 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1),
15815 SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1),
15816 SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1),
15817 SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC663_ASUS_MODE1),
15818 SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2),
15819 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2),
15820 SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2),
15821 SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2),
15822 SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_ASUS_MODE2),
15823 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2),
15824 SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2),
15825 SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_ASUS_MODE2),
15826 SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2),
15827 SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2),
15828 SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2),
15829 SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2),
15830 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3),
15831 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3),
15832 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3),
15833 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3),
15834 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3),
15835 SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC663_ASUS_MODE4),
15836 SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5),
15837 SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6),
15838 SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6),
15839 SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6),
15840 SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K",
15841 ALC662_3ST_6ch_DIG),
15842 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
15843 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS),
15844 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS),
15845 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L",
15846 ALC662_3ST_6ch_DIG),
15847 SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG),
15848 SND_PCI_QUIRK(0x1849, 0x3662, "ASROCK K10N78FullHD-hSLI R3.0",
15849 ALC662_3ST_6ch_DIG),
15850 SND_PCI_QUIRK(0x1854, 0x2000, "ASUS H13-2000", ALC663_ASUS_H13),
15851 SND_PCI_QUIRK(0x1854, 0x2001, "ASUS H13-2001", ALC663_ASUS_H13),
15852 SND_PCI_QUIRK(0x1854, 0x2002, "ASUS H13-2002", ALC663_ASUS_H13),
15853 {}
15854 };
15855
15856 static struct alc_config_preset alc662_presets[] = {
15857 [ALC662_3ST_2ch_DIG] = {
15858 .mixers = { alc662_3ST_2ch_mixer, alc662_capture_mixer },
15859 .init_verbs = { alc662_init_verbs },
15860 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15861 .dac_nids = alc662_dac_nids,
15862 .dig_out_nid = ALC662_DIGOUT_NID,
15863 .dig_in_nid = ALC662_DIGIN_NID,
15864 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15865 .channel_mode = alc662_3ST_2ch_modes,
15866 .input_mux = &alc662_capture_source,
15867 },
15868 [ALC662_3ST_6ch_DIG] = {
15869 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer,
15870 alc662_capture_mixer },
15871 .init_verbs = { alc662_init_verbs },
15872 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15873 .dac_nids = alc662_dac_nids,
15874 .dig_out_nid = ALC662_DIGOUT_NID,
15875 .dig_in_nid = ALC662_DIGIN_NID,
15876 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
15877 .channel_mode = alc662_3ST_6ch_modes,
15878 .need_dac_fix = 1,
15879 .input_mux = &alc662_capture_source,
15880 },
15881 [ALC662_3ST_6ch] = {
15882 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer,
15883 alc662_capture_mixer },
15884 .init_verbs = { alc662_init_verbs },
15885 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15886 .dac_nids = alc662_dac_nids,
15887 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
15888 .channel_mode = alc662_3ST_6ch_modes,
15889 .need_dac_fix = 1,
15890 .input_mux = &alc662_capture_source,
15891 },
15892 [ALC662_5ST_DIG] = {
15893 .mixers = { alc662_base_mixer, alc662_chmode_mixer,
15894 alc662_capture_mixer },
15895 .init_verbs = { alc662_init_verbs },
15896 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15897 .dac_nids = alc662_dac_nids,
15898 .dig_out_nid = ALC662_DIGOUT_NID,
15899 .dig_in_nid = ALC662_DIGIN_NID,
15900 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
15901 .channel_mode = alc662_5stack_modes,
15902 .input_mux = &alc662_capture_source,
15903 },
15904 [ALC662_LENOVO_101E] = {
15905 .mixers = { alc662_lenovo_101e_mixer, alc662_capture_mixer },
15906 .init_verbs = { alc662_init_verbs, alc662_sue_init_verbs },
15907 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15908 .dac_nids = alc662_dac_nids,
15909 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15910 .channel_mode = alc662_3ST_2ch_modes,
15911 .input_mux = &alc662_lenovo_101e_capture_source,
15912 .unsol_event = alc662_lenovo_101e_unsol_event,
15913 .init_hook = alc662_lenovo_101e_all_automute,
15914 },
15915 [ALC662_ASUS_EEEPC_P701] = {
15916 .mixers = { alc662_eeepc_p701_mixer, alc662_capture_mixer },
15917 .init_verbs = { alc662_init_verbs,
15918 alc662_eeepc_sue_init_verbs },
15919 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15920 .dac_nids = alc662_dac_nids,
15921 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15922 .channel_mode = alc662_3ST_2ch_modes,
15923 .input_mux = &alc662_eeepc_capture_source,
15924 .unsol_event = alc662_eeepc_unsol_event,
15925 .init_hook = alc662_eeepc_inithook,
15926 },
15927 [ALC662_ASUS_EEEPC_EP20] = {
15928 .mixers = { alc662_eeepc_ep20_mixer, alc662_capture_mixer,
15929 alc662_chmode_mixer },
15930 .init_verbs = { alc662_init_verbs,
15931 alc662_eeepc_ep20_sue_init_verbs },
15932 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15933 .dac_nids = alc662_dac_nids,
15934 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
15935 .channel_mode = alc662_3ST_6ch_modes,
15936 .input_mux = &alc662_lenovo_101e_capture_source,
15937 .unsol_event = alc662_eeepc_ep20_unsol_event,
15938 .init_hook = alc662_eeepc_ep20_inithook,
15939 },
15940 [ALC662_ECS] = {
15941 .mixers = { alc662_ecs_mixer, alc662_capture_mixer },
15942 .init_verbs = { alc662_init_verbs,
15943 alc662_ecs_init_verbs },
15944 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15945 .dac_nids = alc662_dac_nids,
15946 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15947 .channel_mode = alc662_3ST_2ch_modes,
15948 .input_mux = &alc662_eeepc_capture_source,
15949 .unsol_event = alc662_eeepc_unsol_event,
15950 .init_hook = alc662_eeepc_inithook,
15951 },
15952 [ALC663_ASUS_M51VA] = {
15953 .mixers = { alc663_m51va_mixer, alc662_capture_mixer},
15954 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
15955 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15956 .dac_nids = alc662_dac_nids,
15957 .dig_out_nid = ALC662_DIGOUT_NID,
15958 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15959 .channel_mode = alc662_3ST_2ch_modes,
15960 .input_mux = &alc663_m51va_capture_source,
15961 .unsol_event = alc663_m51va_unsol_event,
15962 .init_hook = alc663_m51va_inithook,
15963 },
15964 [ALC663_ASUS_G71V] = {
15965 .mixers = { alc663_g71v_mixer, alc662_capture_mixer},
15966 .init_verbs = { alc662_init_verbs, alc663_g71v_init_verbs },
15967 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15968 .dac_nids = alc662_dac_nids,
15969 .dig_out_nid = ALC662_DIGOUT_NID,
15970 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15971 .channel_mode = alc662_3ST_2ch_modes,
15972 .input_mux = &alc662_eeepc_capture_source,
15973 .unsol_event = alc663_g71v_unsol_event,
15974 .init_hook = alc663_g71v_inithook,
15975 },
15976 [ALC663_ASUS_H13] = {
15977 .mixers = { alc663_m51va_mixer, alc662_capture_mixer},
15978 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
15979 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15980 .dac_nids = alc662_dac_nids,
15981 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
15982 .channel_mode = alc662_3ST_2ch_modes,
15983 .input_mux = &alc663_m51va_capture_source,
15984 .unsol_event = alc663_m51va_unsol_event,
15985 .init_hook = alc663_m51va_inithook,
15986 },
15987 [ALC663_ASUS_G50V] = {
15988 .mixers = { alc663_g50v_mixer, alc662_capture_mixer},
15989 .init_verbs = { alc662_init_verbs, alc663_g50v_init_verbs },
15990 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15991 .dac_nids = alc662_dac_nids,
15992 .dig_out_nid = ALC662_DIGOUT_NID,
15993 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
15994 .channel_mode = alc662_3ST_6ch_modes,
15995 .input_mux = &alc663_capture_source,
15996 .unsol_event = alc663_g50v_unsol_event,
15997 .init_hook = alc663_g50v_inithook,
15998 },
15999 [ALC663_ASUS_MODE1] = {
16000 .mixers = { alc663_m51va_mixer, alc662_auto_capture_mixer },
16001 .init_verbs = { alc662_init_verbs,
16002 alc663_21jd_amic_init_verbs },
16003 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16004 .hp_nid = 0x03,
16005 .dac_nids = alc662_dac_nids,
16006 .dig_out_nid = ALC662_DIGOUT_NID,
16007 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16008 .channel_mode = alc662_3ST_2ch_modes,
16009 .input_mux = &alc662_eeepc_capture_source,
16010 .unsol_event = alc663_mode1_unsol_event,
16011 .init_hook = alc663_mode1_inithook,
16012 },
16013 [ALC662_ASUS_MODE2] = {
16014 .mixers = { alc662_1bjd_mixer, alc662_auto_capture_mixer },
16015 .init_verbs = { alc662_init_verbs,
16016 alc662_1bjd_amic_init_verbs },
16017 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16018 .dac_nids = alc662_dac_nids,
16019 .dig_out_nid = ALC662_DIGOUT_NID,
16020 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16021 .channel_mode = alc662_3ST_2ch_modes,
16022 .input_mux = &alc662_eeepc_capture_source,
16023 .unsol_event = alc662_mode2_unsol_event,
16024 .init_hook = alc662_mode2_inithook,
16025 },
16026 [ALC663_ASUS_MODE3] = {
16027 .mixers = { alc663_two_hp_m1_mixer, alc662_auto_capture_mixer },
16028 .init_verbs = { alc662_init_verbs,
16029 alc663_two_hp_amic_m1_init_verbs },
16030 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16031 .hp_nid = 0x03,
16032 .dac_nids = alc662_dac_nids,
16033 .dig_out_nid = ALC662_DIGOUT_NID,
16034 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16035 .channel_mode = alc662_3ST_2ch_modes,
16036 .input_mux = &alc662_eeepc_capture_source,
16037 .unsol_event = alc663_mode3_unsol_event,
16038 .init_hook = alc663_mode3_inithook,
16039 },
16040 [ALC663_ASUS_MODE4] = {
16041 .mixers = { alc663_asus_21jd_clfe_mixer,
16042 alc662_auto_capture_mixer},
16043 .init_verbs = { alc662_init_verbs,
16044 alc663_21jd_amic_init_verbs},
16045 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16046 .hp_nid = 0x03,
16047 .dac_nids = alc662_dac_nids,
16048 .dig_out_nid = ALC662_DIGOUT_NID,
16049 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16050 .channel_mode = alc662_3ST_2ch_modes,
16051 .input_mux = &alc662_eeepc_capture_source,
16052 .unsol_event = alc663_mode4_unsol_event,
16053 .init_hook = alc663_mode4_inithook,
16054 },
16055 [ALC663_ASUS_MODE5] = {
16056 .mixers = { alc663_asus_15jd_clfe_mixer,
16057 alc662_auto_capture_mixer },
16058 .init_verbs = { alc662_init_verbs,
16059 alc663_15jd_amic_init_verbs },
16060 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16061 .hp_nid = 0x03,
16062 .dac_nids = alc662_dac_nids,
16063 .dig_out_nid = ALC662_DIGOUT_NID,
16064 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16065 .channel_mode = alc662_3ST_2ch_modes,
16066 .input_mux = &alc662_eeepc_capture_source,
16067 .unsol_event = alc663_mode5_unsol_event,
16068 .init_hook = alc663_mode5_inithook,
16069 },
16070 [ALC663_ASUS_MODE6] = {
16071 .mixers = { alc663_two_hp_m2_mixer, alc662_auto_capture_mixer },
16072 .init_verbs = { alc662_init_verbs,
16073 alc663_two_hp_amic_m2_init_verbs },
16074 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16075 .hp_nid = 0x03,
16076 .dac_nids = alc662_dac_nids,
16077 .dig_out_nid = ALC662_DIGOUT_NID,
16078 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16079 .channel_mode = alc662_3ST_2ch_modes,
16080 .input_mux = &alc662_eeepc_capture_source,
16081 .unsol_event = alc663_mode6_unsol_event,
16082 .init_hook = alc663_mode6_inithook,
16083 },
16084 };
16085
16086
16087 /*
16088 * BIOS auto configuration
16089 */
16090
16091 /* add playback controls from the parsed DAC table */
16092 static int alc662_auto_create_multi_out_ctls(struct alc_spec *spec,
16093 const struct auto_pin_cfg *cfg)
16094 {
16095 char name[32];
16096 static const char *chname[4] = {
16097 "Front", "Surround", NULL /*CLFE*/, "Side"
16098 };
16099 hda_nid_t nid;
16100 int i, err;
16101
16102 for (i = 0; i < cfg->line_outs; i++) {
16103 if (!spec->multiout.dac_nids[i])
16104 continue;
16105 nid = alc880_idx_to_dac(i);
16106 if (i == 2) {
16107 /* Center/LFE */
16108 err = add_control(spec, ALC_CTL_WIDGET_VOL,
16109 "Center Playback Volume",
16110 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
16111 HDA_OUTPUT));
16112 if (err < 0)
16113 return err;
16114 err = add_control(spec, ALC_CTL_WIDGET_VOL,
16115 "LFE Playback Volume",
16116 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
16117 HDA_OUTPUT));
16118 if (err < 0)
16119 return err;
16120 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
16121 "Center Playback Switch",
16122 HDA_COMPOSE_AMP_VAL(0x0e, 1, 0,
16123 HDA_INPUT));
16124 if (err < 0)
16125 return err;
16126 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
16127 "LFE Playback Switch",
16128 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
16129 HDA_INPUT));
16130 if (err < 0)
16131 return err;
16132 } else {
16133 sprintf(name, "%s Playback Volume", chname[i]);
16134 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
16135 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
16136 HDA_OUTPUT));
16137 if (err < 0)
16138 return err;
16139 sprintf(name, "%s Playback Switch", chname[i]);
16140 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
16141 HDA_COMPOSE_AMP_VAL(alc880_idx_to_mixer(i),
16142 3, 0, HDA_INPUT));
16143 if (err < 0)
16144 return err;
16145 }
16146 }
16147 return 0;
16148 }
16149
16150 /* add playback controls for speaker and HP outputs */
16151 static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
16152 const char *pfx)
16153 {
16154 hda_nid_t nid;
16155 int err;
16156 char name[32];
16157
16158 if (!pin)
16159 return 0;
16160
16161 if (pin == 0x17) {
16162 /* ALC663 has a mono output pin on 0x17 */
16163 sprintf(name, "%s Playback Switch", pfx);
16164 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
16165 HDA_COMPOSE_AMP_VAL(pin, 2, 0, HDA_OUTPUT));
16166 return err;
16167 }
16168
16169 if (alc880_is_fixed_pin(pin)) {
16170 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
16171 /* printk("DAC nid=%x\n",nid); */
16172 /* specify the DAC as the extra output */
16173 if (!spec->multiout.hp_nid)
16174 spec->multiout.hp_nid = nid;
16175 else
16176 spec->multiout.extra_out_nid[0] = nid;
16177 /* control HP volume/switch on the output mixer amp */
16178 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
16179 sprintf(name, "%s Playback Volume", pfx);
16180 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
16181 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
16182 if (err < 0)
16183 return err;
16184 sprintf(name, "%s Playback Switch", pfx);
16185 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
16186 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
16187 if (err < 0)
16188 return err;
16189 } else if (alc880_is_multi_pin(pin)) {
16190 /* set manual connection */
16191 /* we have only a switch on HP-out PIN */
16192 sprintf(name, "%s Playback Switch", pfx);
16193 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
16194 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
16195 if (err < 0)
16196 return err;
16197 }
16198 return 0;
16199 }
16200
16201 /* create playback/capture controls for input pins */
16202 static int alc662_auto_create_analog_input_ctls(struct alc_spec *spec,
16203 const struct auto_pin_cfg *cfg)
16204 {
16205 struct hda_input_mux *imux = &spec->private_imux;
16206 int i, err, idx;
16207
16208 for (i = 0; i < AUTO_PIN_LAST; i++) {
16209 if (alc880_is_input_pin(cfg->input_pins[i])) {
16210 idx = alc880_input_pin_idx(cfg->input_pins[i]);
16211 err = new_analog_input(spec, cfg->input_pins[i],
16212 auto_pin_cfg_labels[i],
16213 idx, 0x0b);
16214 if (err < 0)
16215 return err;
16216 imux->items[imux->num_items].label =
16217 auto_pin_cfg_labels[i];
16218 imux->items[imux->num_items].index =
16219 alc880_input_pin_idx(cfg->input_pins[i]);
16220 imux->num_items++;
16221 }
16222 }
16223 return 0;
16224 }
16225
16226 static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
16227 hda_nid_t nid, int pin_type,
16228 int dac_idx)
16229 {
16230 alc_set_pin_output(codec, nid, pin_type);
16231 /* need the manual connection? */
16232 if (alc880_is_multi_pin(nid)) {
16233 struct alc_spec *spec = codec->spec;
16234 int idx = alc880_multi_pin_idx(nid);
16235 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
16236 AC_VERB_SET_CONNECT_SEL,
16237 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
16238 }
16239 }
16240
16241 static void alc662_auto_init_multi_out(struct hda_codec *codec)
16242 {
16243 struct alc_spec *spec = codec->spec;
16244 int i;
16245
16246 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
16247 for (i = 0; i <= HDA_SIDE; i++) {
16248 hda_nid_t nid = spec->autocfg.line_out_pins[i];
16249 int pin_type = get_pin_type(spec->autocfg.line_out_type);
16250 if (nid)
16251 alc662_auto_set_output_and_unmute(codec, nid, pin_type,
16252 i);
16253 }
16254 }
16255
16256 static void alc662_auto_init_hp_out(struct hda_codec *codec)
16257 {
16258 struct alc_spec *spec = codec->spec;
16259 hda_nid_t pin;
16260
16261 pin = spec->autocfg.hp_pins[0];
16262 if (pin) /* connect to front */
16263 /* use dac 0 */
16264 alc662_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
16265 pin = spec->autocfg.speaker_pins[0];
16266 if (pin)
16267 alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
16268 }
16269
16270 #define alc662_is_input_pin(nid) alc880_is_input_pin(nid)
16271 #define ALC662_PIN_CD_NID ALC880_PIN_CD_NID
16272
16273 static void alc662_auto_init_analog_input(struct hda_codec *codec)
16274 {
16275 struct alc_spec *spec = codec->spec;
16276 int i;
16277
16278 for (i = 0; i < AUTO_PIN_LAST; i++) {
16279 hda_nid_t nid = spec->autocfg.input_pins[i];
16280 if (alc662_is_input_pin(nid)) {
16281 snd_hda_codec_write(codec, nid, 0,
16282 AC_VERB_SET_PIN_WIDGET_CONTROL,
16283 (i <= AUTO_PIN_FRONT_MIC ?
16284 PIN_VREF80 : PIN_IN));
16285 if (nid != ALC662_PIN_CD_NID)
16286 snd_hda_codec_write(codec, nid, 0,
16287 AC_VERB_SET_AMP_GAIN_MUTE,
16288 AMP_OUT_MUTE);
16289 }
16290 }
16291 }
16292
16293 #define alc662_auto_init_input_src alc882_auto_init_input_src
16294
16295 static int alc662_parse_auto_config(struct hda_codec *codec)
16296 {
16297 struct alc_spec *spec = codec->spec;
16298 int err;
16299 static hda_nid_t alc662_ignore[] = { 0x1d, 0 };
16300
16301 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
16302 alc662_ignore);
16303 if (err < 0)
16304 return err;
16305 if (!spec->autocfg.line_outs)
16306 return 0; /* can't find valid BIOS pin config */
16307
16308 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
16309 if (err < 0)
16310 return err;
16311 err = alc662_auto_create_multi_out_ctls(spec, &spec->autocfg);
16312 if (err < 0)
16313 return err;
16314 err = alc662_auto_create_extra_out(spec,
16315 spec->autocfg.speaker_pins[0],
16316 "Speaker");
16317 if (err < 0)
16318 return err;
16319 err = alc662_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
16320 "Headphone");
16321 if (err < 0)
16322 return err;
16323 err = alc662_auto_create_analog_input_ctls(spec, &spec->autocfg);
16324 if (err < 0)
16325 return err;
16326
16327 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
16328
16329 if (spec->autocfg.dig_out_pin)
16330 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
16331
16332 if (spec->kctls.list)
16333 add_mixer(spec, spec->kctls.list);
16334
16335 spec->num_mux_defs = 1;
16336 spec->input_mux = &spec->private_imux;
16337
16338 add_verb(spec, alc662_auto_init_verbs);
16339 if (codec->vendor_id == 0x10ec0663)
16340 add_verb(spec, alc663_auto_init_verbs);
16341
16342 err = alc_auto_add_mic_boost(codec);
16343 if (err < 0)
16344 return err;
16345
16346 add_mixer(spec, alc662_capture_mixer);
16347
16348 store_pin_configs(codec);
16349 return 1;
16350 }
16351
16352 /* additional initialization for auto-configuration model */
16353 static void alc662_auto_init(struct hda_codec *codec)
16354 {
16355 struct alc_spec *spec = codec->spec;
16356 alc662_auto_init_multi_out(codec);
16357 alc662_auto_init_hp_out(codec);
16358 alc662_auto_init_analog_input(codec);
16359 alc662_auto_init_input_src(codec);
16360 if (spec->unsol_event)
16361 alc_inithook(codec);
16362 }
16363
16364 static int patch_alc662(struct hda_codec *codec)
16365 {
16366 struct alc_spec *spec;
16367 int err, board_config;
16368
16369 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
16370 if (!spec)
16371 return -ENOMEM;
16372
16373 codec->spec = spec;
16374
16375 alc_fix_pll_init(codec, 0x20, 0x04, 15);
16376
16377 board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
16378 alc662_models,
16379 alc662_cfg_tbl);
16380 if (board_config < 0) {
16381 printk(KERN_INFO "hda_codec: Unknown model for ALC662, "
16382 "trying auto-probe from BIOS...\n");
16383 board_config = ALC662_AUTO;
16384 }
16385
16386 if (board_config == ALC662_AUTO) {
16387 /* automatic parse from the BIOS config */
16388 err = alc662_parse_auto_config(codec);
16389 if (err < 0) {
16390 alc_free(codec);
16391 return err;
16392 } else if (!err) {
16393 printk(KERN_INFO
16394 "hda_codec: Cannot set up configuration "
16395 "from BIOS. Using base mode...\n");
16396 board_config = ALC662_3ST_2ch_DIG;
16397 }
16398 }
16399
16400 if (board_config != ALC662_AUTO)
16401 setup_preset(spec, &alc662_presets[board_config]);
16402
16403 if (codec->vendor_id == 0x10ec0663) {
16404 spec->stream_name_analog = "ALC663 Analog";
16405 spec->stream_name_digital = "ALC663 Digital";
16406 } else if (codec->vendor_id == 0x10ec0272) {
16407 spec->stream_name_analog = "ALC272 Analog";
16408 spec->stream_name_digital = "ALC272 Digital";
16409 } else {
16410 spec->stream_name_analog = "ALC662 Analog";
16411 spec->stream_name_digital = "ALC662 Digital";
16412 }
16413
16414 spec->stream_analog_playback = &alc662_pcm_analog_playback;
16415 spec->stream_analog_capture = &alc662_pcm_analog_capture;
16416
16417 spec->stream_digital_playback = &alc662_pcm_digital_playback;
16418 spec->stream_digital_capture = &alc662_pcm_digital_capture;
16419
16420 spec->adc_nids = alc662_adc_nids;
16421 spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
16422 spec->capsrc_nids = alc662_capsrc_nids;
16423
16424 spec->vmaster_nid = 0x02;
16425
16426 codec->patch_ops = alc_patch_ops;
16427 if (board_config == ALC662_AUTO)
16428 spec->init_hook = alc662_auto_init;
16429 #ifdef CONFIG_SND_HDA_POWER_SAVE
16430 if (!spec->loopback.amplist)
16431 spec->loopback.amplist = alc662_loopbacks;
16432 #endif
16433
16434 return 0;
16435 }
16436
16437 /*
16438 * patch entries
16439 */
16440 struct hda_codec_preset snd_hda_preset_realtek[] = {
16441 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
16442 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
16443 { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
16444 { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
16445 { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
16446 { .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 },
16447 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
16448 .patch = patch_alc861 },
16449 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
16450 { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
16451 { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
16452 { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
16453 .patch = patch_alc883 },
16454 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
16455 .patch = patch_alc662 },
16456 { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
16457 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
16458 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
16459 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc883 },
16460 { .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A",
16461 .patch = patch_alc882 }, /* should be patch_alc883() in future */
16462 { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A",
16463 .patch = patch_alc882 }, /* should be patch_alc883() in future */
16464 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
16465 { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc883 },
16466 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc883 },
16467 { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200",
16468 .patch = patch_alc883 },
16469 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc883 },
16470 {} /* terminator */
16471 };