Merge git://git.kernel.org/pub/scm/linux/kernel/git/wim/linux-2.6-watchdog
[pandora-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 <sound/driver.h>
27 #include <linux/init.h>
28 #include <linux/delay.h>
29 #include <linux/slab.h>
30 #include <linux/pci.h>
31 #include <sound/core.h>
32 #include "hda_codec.h"
33 #include "hda_local.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 #ifdef CONFIG_SND_DEBUG
64         ALC880_TEST,
65 #endif
66         ALC880_AUTO,
67         ALC880_MODEL_LAST /* last tag */
68 };
69
70 /* ALC260 models */
71 enum {
72         ALC260_BASIC,
73         ALC260_HP,
74         ALC260_HP_3013,
75         ALC260_FUJITSU_S702X,
76         ALC260_ACER,
77         ALC260_WILL,
78         ALC260_REPLACER_672V,
79 #ifdef CONFIG_SND_DEBUG
80         ALC260_TEST,
81 #endif
82         ALC260_AUTO,
83         ALC260_MODEL_LAST /* last tag */
84 };
85
86 /* ALC262 models */
87 enum {
88         ALC262_BASIC,
89         ALC262_HIPPO,
90         ALC262_HIPPO_1,
91         ALC262_FUJITSU,
92         ALC262_HP_BPC,
93         ALC262_HP_BPC_D7000_WL,
94         ALC262_HP_BPC_D7000_WF,
95         ALC262_BENQ_ED8,
96         ALC262_SONY_ASSAMD,
97         ALC262_BENQ_T31,
98         ALC262_AUTO,
99         ALC262_MODEL_LAST /* last tag */
100 };
101
102 /* ALC268 models */
103 enum {
104         ALC268_3ST,
105         ALC268_TOSHIBA,
106         ALC268_ACER,
107         ALC268_AUTO,
108         ALC268_MODEL_LAST /* last tag */
109 };
110
111 /* ALC861 models */
112 enum {
113         ALC861_3ST,
114         ALC660_3ST,
115         ALC861_3ST_DIG,
116         ALC861_6ST_DIG,
117         ALC861_UNIWILL_M31,
118         ALC861_TOSHIBA,
119         ALC861_ASUS,
120         ALC861_ASUS_LAPTOP,
121         ALC861_AUTO,
122         ALC861_MODEL_LAST,
123 };
124
125 /* ALC861-VD models */
126 enum {
127         ALC660VD_3ST,
128         ALC660VD_3ST_DIG,
129         ALC861VD_3ST,
130         ALC861VD_3ST_DIG,
131         ALC861VD_6ST_DIG,
132         ALC861VD_LENOVO,
133         ALC861VD_DALLAS,
134         ALC861VD_HP,
135         ALC861VD_AUTO,
136         ALC861VD_MODEL_LAST,
137 };
138
139 /* ALC662 models */
140 enum {
141         ALC662_3ST_2ch_DIG,
142         ALC662_3ST_6ch_DIG,
143         ALC662_3ST_6ch,
144         ALC662_5ST_DIG,
145         ALC662_LENOVO_101E,
146         ALC662_ASUS_EEEPC_P701,
147         ALC662_AUTO,
148         ALC662_MODEL_LAST,
149 };
150
151 /* ALC882 models */
152 enum {
153         ALC882_3ST_DIG,
154         ALC882_6ST_DIG,
155         ALC882_ARIMA,
156         ALC882_W2JC,
157         ALC882_TARGA,
158         ALC882_ASUS_A7J,
159         ALC882_ASUS_A7M,
160         ALC885_MACPRO,
161         ALC885_MBP3,
162         ALC885_IMAC24,
163         ALC882_AUTO,
164         ALC882_MODEL_LAST,
165 };
166
167 /* ALC883 models */
168 enum {
169         ALC883_3ST_2ch_DIG,
170         ALC883_3ST_6ch_DIG,
171         ALC883_3ST_6ch,
172         ALC883_6ST_DIG,
173         ALC883_TARGA_DIG,
174         ALC883_TARGA_2ch_DIG,
175         ALC883_ACER,
176         ALC883_ACER_ASPIRE,
177         ALC883_MEDION,
178         ALC883_MEDION_MD2,      
179         ALC883_LAPTOP_EAPD,
180         ALC883_LENOVO_101E_2ch,
181         ALC883_LENOVO_NB0763,
182         ALC888_LENOVO_MS7195_DIG,
183         ALC883_HAIER_W66,               
184         ALC888_6ST_HP,
185         ALC888_3ST_HP,
186         ALC883_AUTO,
187         ALC883_MODEL_LAST,
188 };
189
190 /* for GPIO Poll */
191 #define GPIO_MASK       0x03
192
193 struct alc_spec {
194         /* codec parameterization */
195         struct snd_kcontrol_new *mixers[5];     /* mixer arrays */
196         unsigned int num_mixers;
197
198         const struct hda_verb *init_verbs[5];   /* initialization verbs
199                                                  * don't forget NULL
200                                                  * termination!
201                                                  */
202         unsigned int num_init_verbs;
203
204         char *stream_name_analog;       /* analog PCM stream */
205         struct hda_pcm_stream *stream_analog_playback;
206         struct hda_pcm_stream *stream_analog_capture;
207
208         char *stream_name_digital;      /* digital PCM stream */
209         struct hda_pcm_stream *stream_digital_playback;
210         struct hda_pcm_stream *stream_digital_capture;
211
212         /* playback */
213         struct hda_multi_out multiout;  /* playback set-up
214                                          * max_channels, dacs must be set
215                                          * dig_out_nid and hp_nid are optional
216                                          */
217
218         /* capture */
219         unsigned int num_adc_nids;
220         hda_nid_t *adc_nids;
221         hda_nid_t dig_in_nid;           /* digital-in NID; optional */
222
223         /* capture source */
224         unsigned int num_mux_defs;
225         const struct hda_input_mux *input_mux;
226         unsigned int cur_mux[3];
227
228         /* channel model */
229         const struct hda_channel_mode *channel_mode;
230         int num_channel_mode;
231         int need_dac_fix;
232
233         /* PCM information */
234         struct hda_pcm pcm_rec[3];      /* used in alc_build_pcms() */
235
236         /* dynamic controls, init_verbs and input_mux */
237         struct auto_pin_cfg autocfg;
238         unsigned int num_kctl_alloc, num_kctl_used;
239         struct snd_kcontrol_new *kctl_alloc;
240         struct hda_input_mux private_imux;
241         hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
242
243         /* hooks */
244         void (*init_hook)(struct hda_codec *codec);
245         void (*unsol_event)(struct hda_codec *codec, unsigned int res);
246
247         /* for pin sensing */
248         unsigned int sense_updated: 1;
249         unsigned int jack_present: 1;
250
251 #ifdef CONFIG_SND_HDA_POWER_SAVE
252         struct hda_loopback_check loopback;
253 #endif
254 };
255
256 /*
257  * configuration template - to be copied to the spec instance
258  */
259 struct alc_config_preset {
260         struct snd_kcontrol_new *mixers[5]; /* should be identical size
261                                              * with spec
262                                              */
263         const struct hda_verb *init_verbs[5];
264         unsigned int num_dacs;
265         hda_nid_t *dac_nids;
266         hda_nid_t dig_out_nid;          /* optional */
267         hda_nid_t hp_nid;               /* optional */
268         unsigned int num_adc_nids;
269         hda_nid_t *adc_nids;
270         hda_nid_t dig_in_nid;
271         unsigned int num_channel_mode;
272         const struct hda_channel_mode *channel_mode;
273         int need_dac_fix;
274         unsigned int num_mux_defs;
275         const struct hda_input_mux *input_mux;
276         void (*unsol_event)(struct hda_codec *, unsigned int);
277         void (*init_hook)(struct hda_codec *);
278 #ifdef CONFIG_SND_HDA_POWER_SAVE
279         struct hda_amp_list *loopbacks;
280 #endif
281 };
282
283
284 /*
285  * input MUX handling
286  */
287 static int alc_mux_enum_info(struct snd_kcontrol *kcontrol,
288                              struct snd_ctl_elem_info *uinfo)
289 {
290         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
291         struct alc_spec *spec = codec->spec;
292         unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id);
293         if (mux_idx >= spec->num_mux_defs)
294                 mux_idx = 0;
295         return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo);
296 }
297
298 static int alc_mux_enum_get(struct snd_kcontrol *kcontrol,
299                             struct snd_ctl_elem_value *ucontrol)
300 {
301         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
302         struct alc_spec *spec = codec->spec;
303         unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
304
305         ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
306         return 0;
307 }
308
309 static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
310                             struct snd_ctl_elem_value *ucontrol)
311 {
312         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
313         struct alc_spec *spec = codec->spec;
314         unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
315         unsigned int mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
316         return snd_hda_input_mux_put(codec, &spec->input_mux[mux_idx], ucontrol,
317                                      spec->adc_nids[adc_idx],
318                                      &spec->cur_mux[adc_idx]);
319 }
320
321
322 /*
323  * channel mode setting
324  */
325 static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
326                             struct snd_ctl_elem_info *uinfo)
327 {
328         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
329         struct alc_spec *spec = codec->spec;
330         return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
331                                     spec->num_channel_mode);
332 }
333
334 static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
335                            struct snd_ctl_elem_value *ucontrol)
336 {
337         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
338         struct alc_spec *spec = codec->spec;
339         return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
340                                    spec->num_channel_mode,
341                                    spec->multiout.max_channels);
342 }
343
344 static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
345                            struct snd_ctl_elem_value *ucontrol)
346 {
347         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
348         struct alc_spec *spec = codec->spec;
349         int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
350                                       spec->num_channel_mode,
351                                       &spec->multiout.max_channels);
352         if (err >= 0 && spec->need_dac_fix)
353                 spec->multiout.num_dacs = spec->multiout.max_channels / 2;
354         return err;
355 }
356
357 /*
358  * Control the mode of pin widget settings via the mixer.  "pc" is used
359  * instead of "%" to avoid consequences of accidently treating the % as 
360  * being part of a format specifier.  Maximum allowed length of a value is
361  * 63 characters plus NULL terminator.
362  *
363  * Note: some retasking pin complexes seem to ignore requests for input
364  * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
365  * are requested.  Therefore order this list so that this behaviour will not
366  * cause problems when mixer clients move through the enum sequentially.
367  * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
368  * March 2006.
369  */
370 static char *alc_pin_mode_names[] = {
371         "Mic 50pc bias", "Mic 80pc bias",
372         "Line in", "Line out", "Headphone out",
373 };
374 static unsigned char alc_pin_mode_values[] = {
375         PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
376 };
377 /* The control can present all 5 options, or it can limit the options based
378  * in the pin being assumed to be exclusively an input or an output pin.  In
379  * addition, "input" pins may or may not process the mic bias option
380  * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
381  * accept requests for bias as of chip versions up to March 2006) and/or
382  * wiring in the computer.
383  */
384 #define ALC_PIN_DIR_IN              0x00
385 #define ALC_PIN_DIR_OUT             0x01
386 #define ALC_PIN_DIR_INOUT           0x02
387 #define ALC_PIN_DIR_IN_NOMICBIAS    0x03
388 #define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
389
390 /* Info about the pin modes supported by the different pin direction modes. 
391  * For each direction the minimum and maximum values are given.
392  */
393 static signed char alc_pin_mode_dir_info[5][2] = {
394         { 0, 2 },    /* ALC_PIN_DIR_IN */
395         { 3, 4 },    /* ALC_PIN_DIR_OUT */
396         { 0, 4 },    /* ALC_PIN_DIR_INOUT */
397         { 2, 2 },    /* ALC_PIN_DIR_IN_NOMICBIAS */
398         { 2, 4 },    /* ALC_PIN_DIR_INOUT_NOMICBIAS */
399 };
400 #define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
401 #define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
402 #define alc_pin_mode_n_items(_dir) \
403         (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
404
405 static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
406                              struct snd_ctl_elem_info *uinfo)
407 {
408         unsigned int item_num = uinfo->value.enumerated.item;
409         unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
410
411         uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
412         uinfo->count = 1;
413         uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
414
415         if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
416                 item_num = alc_pin_mode_min(dir);
417         strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
418         return 0;
419 }
420
421 static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
422                             struct snd_ctl_elem_value *ucontrol)
423 {
424         unsigned int i;
425         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
426         hda_nid_t nid = kcontrol->private_value & 0xffff;
427         unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
428         long *valp = ucontrol->value.integer.value;
429         unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
430                                                  AC_VERB_GET_PIN_WIDGET_CONTROL,
431                                                  0x00);
432
433         /* Find enumerated value for current pinctl setting */
434         i = alc_pin_mode_min(dir);
435         while (alc_pin_mode_values[i] != pinctl && i <= alc_pin_mode_max(dir))
436                 i++;
437         *valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
438         return 0;
439 }
440
441 static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
442                             struct snd_ctl_elem_value *ucontrol)
443 {
444         signed int change;
445         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
446         hda_nid_t nid = kcontrol->private_value & 0xffff;
447         unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
448         long val = *ucontrol->value.integer.value;
449         unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
450                                                  AC_VERB_GET_PIN_WIDGET_CONTROL,
451                                                  0x00);
452
453         if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
454                 val = alc_pin_mode_min(dir);
455
456         change = pinctl != alc_pin_mode_values[val];
457         if (change) {
458                 /* Set pin mode to that requested */
459                 snd_hda_codec_write_cache(codec, nid, 0,
460                                           AC_VERB_SET_PIN_WIDGET_CONTROL,
461                                           alc_pin_mode_values[val]);
462
463                 /* Also enable the retasking pin's input/output as required 
464                  * for the requested pin mode.  Enum values of 2 or less are
465                  * input modes.
466                  *
467                  * Dynamically switching the input/output buffers probably
468                  * reduces noise slightly (particularly on input) so we'll
469                  * do it.  However, having both input and output buffers
470                  * enabled simultaneously doesn't seem to be problematic if
471                  * this turns out to be necessary in the future.
472                  */
473                 if (val <= 2) {
474                         snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
475                                                  HDA_AMP_MUTE, HDA_AMP_MUTE);
476                         snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
477                                                  HDA_AMP_MUTE, 0);
478                 } else {
479                         snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
480                                                  HDA_AMP_MUTE, HDA_AMP_MUTE);
481                         snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
482                                                  HDA_AMP_MUTE, 0);
483                 }
484         }
485         return change;
486 }
487
488 #define ALC_PIN_MODE(xname, nid, dir) \
489         { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
490           .info = alc_pin_mode_info, \
491           .get = alc_pin_mode_get, \
492           .put = alc_pin_mode_put, \
493           .private_value = nid | (dir<<16) }
494
495 /* A switch control for ALC260 GPIO pins.  Multiple GPIOs can be ganged
496  * together using a mask with more than one bit set.  This control is
497  * currently used only by the ALC260 test model.  At this stage they are not
498  * needed for any "production" models.
499  */
500 #ifdef CONFIG_SND_DEBUG
501 #define alc_gpio_data_info      snd_ctl_boolean_mono_info
502
503 static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
504                              struct snd_ctl_elem_value *ucontrol)
505 {
506         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
507         hda_nid_t nid = kcontrol->private_value & 0xffff;
508         unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
509         long *valp = ucontrol->value.integer.value;
510         unsigned int val = snd_hda_codec_read(codec, nid, 0,
511                                               AC_VERB_GET_GPIO_DATA, 0x00);
512
513         *valp = (val & mask) != 0;
514         return 0;
515 }
516 static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
517                              struct snd_ctl_elem_value *ucontrol)
518 {
519         signed int change;
520         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
521         hda_nid_t nid = kcontrol->private_value & 0xffff;
522         unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
523         long val = *ucontrol->value.integer.value;
524         unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
525                                                     AC_VERB_GET_GPIO_DATA,
526                                                     0x00);
527
528         /* Set/unset the masked GPIO bit(s) as needed */
529         change = (val == 0 ? 0 : mask) != (gpio_data & mask);
530         if (val == 0)
531                 gpio_data &= ~mask;
532         else
533                 gpio_data |= mask;
534         snd_hda_codec_write_cache(codec, nid, 0,
535                                   AC_VERB_SET_GPIO_DATA, gpio_data);
536
537         return change;
538 }
539 #define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
540         { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
541           .info = alc_gpio_data_info, \
542           .get = alc_gpio_data_get, \
543           .put = alc_gpio_data_put, \
544           .private_value = nid | (mask<<16) }
545 #endif   /* CONFIG_SND_DEBUG */
546
547 /* A switch control to allow the enabling of the digital IO pins on the
548  * ALC260.  This is incredibly simplistic; the intention of this control is
549  * to provide something in the test model allowing digital outputs to be
550  * identified if present.  If models are found which can utilise these
551  * outputs a more complete mixer control can be devised for those models if
552  * necessary.
553  */
554 #ifdef CONFIG_SND_DEBUG
555 #define alc_spdif_ctrl_info     snd_ctl_boolean_mono_info
556
557 static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
558                               struct snd_ctl_elem_value *ucontrol)
559 {
560         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
561         hda_nid_t nid = kcontrol->private_value & 0xffff;
562         unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
563         long *valp = ucontrol->value.integer.value;
564         unsigned int val = snd_hda_codec_read(codec, nid, 0,
565                                               AC_VERB_GET_DIGI_CONVERT, 0x00);
566
567         *valp = (val & mask) != 0;
568         return 0;
569 }
570 static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
571                               struct snd_ctl_elem_value *ucontrol)
572 {
573         signed int change;
574         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
575         hda_nid_t nid = kcontrol->private_value & 0xffff;
576         unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
577         long val = *ucontrol->value.integer.value;
578         unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
579                                                     AC_VERB_GET_DIGI_CONVERT,
580                                                     0x00);
581
582         /* Set/unset the masked control bit(s) as needed */
583         change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
584         if (val==0)
585                 ctrl_data &= ~mask;
586         else
587                 ctrl_data |= mask;
588         snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
589                                   ctrl_data);
590
591         return change;
592 }
593 #define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
594         { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
595           .info = alc_spdif_ctrl_info, \
596           .get = alc_spdif_ctrl_get, \
597           .put = alc_spdif_ctrl_put, \
598           .private_value = nid | (mask<<16) }
599 #endif   /* CONFIG_SND_DEBUG */
600
601 /*
602  * set up from the preset table
603  */
604 static void setup_preset(struct alc_spec *spec,
605                          const struct alc_config_preset *preset)
606 {
607         int i;
608
609         for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
610                 spec->mixers[spec->num_mixers++] = preset->mixers[i];
611         for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
612              i++)
613                 spec->init_verbs[spec->num_init_verbs++] =
614                         preset->init_verbs[i];
615         
616         spec->channel_mode = preset->channel_mode;
617         spec->num_channel_mode = preset->num_channel_mode;
618         spec->need_dac_fix = preset->need_dac_fix;
619
620         spec->multiout.max_channels = spec->channel_mode[0].channels;
621
622         spec->multiout.num_dacs = preset->num_dacs;
623         spec->multiout.dac_nids = preset->dac_nids;
624         spec->multiout.dig_out_nid = preset->dig_out_nid;
625         spec->multiout.hp_nid = preset->hp_nid;
626         
627         spec->num_mux_defs = preset->num_mux_defs;
628         if (!spec->num_mux_defs)
629                 spec->num_mux_defs = 1;
630         spec->input_mux = preset->input_mux;
631
632         spec->num_adc_nids = preset->num_adc_nids;
633         spec->adc_nids = preset->adc_nids;
634         spec->dig_in_nid = preset->dig_in_nid;
635
636         spec->unsol_event = preset->unsol_event;
637         spec->init_hook = preset->init_hook;
638 #ifdef CONFIG_SND_HDA_POWER_SAVE
639         spec->loopback.amplist = preset->loopbacks;
640 #endif
641 }
642
643 /* Enable GPIO mask and set output */
644 static struct hda_verb alc_gpio1_init_verbs[] = {
645         {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
646         {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
647         {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
648         { }
649 };
650
651 static struct hda_verb alc_gpio2_init_verbs[] = {
652         {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
653         {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
654         {0x01, AC_VERB_SET_GPIO_DATA, 0x02},
655         { }
656 };
657
658 static struct hda_verb alc_gpio3_init_verbs[] = {
659         {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
660         {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
661         {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
662         { }
663 };
664
665 static void alc_sku_automute(struct hda_codec *codec)
666 {
667         struct alc_spec *spec = codec->spec;
668         unsigned int mute;
669         unsigned int present;
670         unsigned int hp_nid = spec->autocfg.hp_pins[0];
671         unsigned int sp_nid = spec->autocfg.speaker_pins[0];
672
673         /* need to execute and sync at first */
674         snd_hda_codec_read(codec, hp_nid, 0, AC_VERB_SET_PIN_SENSE, 0);
675         present = snd_hda_codec_read(codec, hp_nid, 0,
676                                      AC_VERB_GET_PIN_SENSE, 0);
677         spec->jack_present = (present & 0x80000000) != 0;
678         if (spec->jack_present) {
679                 /* mute internal speaker */
680                 snd_hda_codec_amp_stereo(codec, sp_nid, HDA_OUTPUT, 0,
681                                          HDA_AMP_MUTE, HDA_AMP_MUTE);
682         } else {
683                 /* unmute internal speaker if necessary */
684                 mute = snd_hda_codec_amp_read(codec, hp_nid, 0, HDA_OUTPUT, 0);
685                 snd_hda_codec_amp_stereo(codec, sp_nid, HDA_OUTPUT, 0,
686                                          HDA_AMP_MUTE, mute);
687         }
688 }
689
690 /* unsolicited event for HP jack sensing */
691 static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
692 {
693         if (codec->vendor_id == 0x10ec0880)
694                 res >>= 28;
695         else
696                 res >>= 26;
697         if (res != ALC880_HP_EVENT)
698                 return;
699
700         alc_sku_automute(codec);
701 }
702
703 /* 32-bit subsystem ID for BIOS loading in HD Audio codec.
704  *      31 ~ 16 :       Manufacture ID
705  *      15 ~ 8  :       SKU ID
706  *      7  ~ 0  :       Assembly ID
707  *      port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
708  */
709 static void alc_subsystem_id(struct hda_codec *codec,
710                              unsigned int porta, unsigned int porte,
711                              unsigned int portd)
712 {
713         unsigned int ass, tmp, i;
714         unsigned nid;
715         struct alc_spec *spec = codec->spec;
716
717         ass = codec->subsystem_id & 0xffff;
718         if ((ass != codec->bus->pci->subsystem_device) && (ass & 1))
719                 goto do_sku;
720
721         /*      
722          * 31~30        : port conetcivity
723          * 29~21        : reserve
724          * 20           : PCBEEP input
725          * 19~16        : Check sum (15:1)
726          * 15~1         : Custom
727          * 0            : override
728         */
729         nid = 0x1d;
730         if (codec->vendor_id == 0x10ec0260)
731                 nid = 0x17;
732         ass = snd_hda_codec_read(codec, nid, 0,
733                                  AC_VERB_GET_CONFIG_DEFAULT, 0);
734         if (!(ass & 1) && !(ass & 0x100000))
735                 return;
736         if ((ass >> 30) != 1)   /* no physical connection */
737                 return;
738
739         /* check sum */
740         tmp = 0;
741         for (i = 1; i < 16; i++) {
742                 if ((ass >> i) && 1)
743                         tmp++;
744         }
745         if (((ass >> 16) & 0xf) != tmp)
746                 return;
747 do_sku:
748         /*
749          * 0 : override
750          * 1 :  Swap Jack
751          * 2 : 0 --> Desktop, 1 --> Laptop
752          * 3~5 : External Amplifier control
753          * 7~6 : Reserved
754         */
755         tmp = (ass & 0x38) >> 3;        /* external Amp control */
756         switch (tmp) {
757         case 1:
758                 snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
759                 break;
760         case 3:
761                 snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
762                 break;
763         case 7:
764                 snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
765                 break;
766         case 5: /* set EAPD output high */
767                 switch (codec->vendor_id) {
768                 case 0x10ec0260:
769                         snd_hda_codec_write(codec, 0x0f, 0,
770                                             AC_VERB_SET_EAPD_BTLENABLE, 2);
771                         snd_hda_codec_write(codec, 0x10, 0,
772                                             AC_VERB_SET_EAPD_BTLENABLE, 2);
773                         break;
774                 case 0x10ec0262:
775                 case 0x10ec0267:
776                 case 0x10ec0268:
777                 case 0x10ec0269:
778                 case 0x10ec0862:
779                 case 0x10ec0662:        
780                         snd_hda_codec_write(codec, 0x14, 0,
781                                             AC_VERB_SET_EAPD_BTLENABLE, 2);
782                         snd_hda_codec_write(codec, 0x15, 0,
783                                             AC_VERB_SET_EAPD_BTLENABLE, 2);
784                         break;
785                 }
786                 switch (codec->vendor_id) {
787                 case 0x10ec0260:
788                         snd_hda_codec_write(codec, 0x1a, 0,
789                                             AC_VERB_SET_COEF_INDEX, 7);
790                         tmp = snd_hda_codec_read(codec, 0x1a, 0,
791                                                  AC_VERB_GET_PROC_COEF, 0);
792                         snd_hda_codec_write(codec, 0x1a, 0,
793                                             AC_VERB_SET_COEF_INDEX, 7);
794                         snd_hda_codec_write(codec, 0x1a, 0,
795                                             AC_VERB_SET_PROC_COEF,
796                                             tmp | 0x2010);
797                         break;
798                 case 0x10ec0262:
799                 case 0x10ec0880:
800                 case 0x10ec0882:
801                 case 0x10ec0883:
802                 case 0x10ec0885:
803                 case 0x10ec0888:
804                         snd_hda_codec_write(codec, 0x20, 0,
805                                             AC_VERB_SET_COEF_INDEX, 7);
806                         tmp = snd_hda_codec_read(codec, 0x20, 0,
807                                                  AC_VERB_GET_PROC_COEF, 0);
808                         snd_hda_codec_write(codec, 0x20, 0,
809                                             AC_VERB_SET_COEF_INDEX, 7); 
810                         snd_hda_codec_write(codec, 0x20, 0,
811                                             AC_VERB_SET_PROC_COEF,
812                                             tmp | 0x2010);
813                         break;
814                 case 0x10ec0267:
815                 case 0x10ec0268:
816                         snd_hda_codec_write(codec, 0x20, 0,
817                                             AC_VERB_SET_COEF_INDEX, 7);
818                         tmp = snd_hda_codec_read(codec, 0x20, 0,
819                                                  AC_VERB_GET_PROC_COEF, 0);
820                         snd_hda_codec_write(codec, 0x20, 0,
821                                             AC_VERB_SET_COEF_INDEX, 7); 
822                         snd_hda_codec_write(codec, 0x20, 0,
823                                             AC_VERB_SET_PROC_COEF,
824                                             tmp | 0x3000);
825                         break;
826                 }
827         default:
828                 break;
829         }
830         
831         /* is laptop and enable the function "Mute internal speaker
832          * when the external headphone out jack is plugged"
833          */
834         if (!(ass & 0x4) || !(ass & 0x8000))
835                 return;
836         /*
837          * 10~8 : Jack location
838          * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
839          * 14~13: Resvered
840          * 15   : 1 --> enable the function "Mute internal speaker
841          *              when the external headphone out jack is plugged"
842          */
843         if (!spec->autocfg.speaker_pins[0]) {
844                 if (spec->multiout.dac_nids[0])
845                         spec->autocfg.speaker_pins[0] =
846                                 spec->multiout.dac_nids[0];
847                 else
848                         return;
849         }
850
851         if (!spec->autocfg.hp_pins[0]) {
852                 tmp = (ass >> 11) & 0x3;        /* HP to chassis */
853                 if (tmp == 0)
854                         spec->autocfg.hp_pins[0] = porta;
855                 else if (tmp == 1)
856                         spec->autocfg.hp_pins[0] = porte;
857                 else if (tmp == 2)
858                         spec->autocfg.hp_pins[0] = portd;
859                 else
860                         return;
861         }
862
863         snd_hda_codec_write(codec, spec->autocfg.hp_pins[0], 0,
864                             AC_VERB_SET_UNSOLICITED_ENABLE,
865                             AC_USRSP_EN | ALC880_HP_EVENT);
866         spec->unsol_event = alc_sku_unsol_event;
867         spec->init_hook = alc_sku_automute;     
868 }
869
870 /*
871  * Fix-up pin default configurations
872  */
873
874 struct alc_pincfg {
875         hda_nid_t nid;
876         u32 val;
877 };
878
879 static void alc_fix_pincfg(struct hda_codec *codec,
880                            const struct snd_pci_quirk *quirk,
881                            const struct alc_pincfg **pinfix)
882 {
883         const struct alc_pincfg *cfg;
884
885         quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
886         if (!quirk)
887                 return;
888
889         cfg = pinfix[quirk->value];
890         for (; cfg->nid; cfg++) {
891                 int i;
892                 u32 val = cfg->val;
893                 for (i = 0; i < 4; i++) {
894                         snd_hda_codec_write(codec, cfg->nid, 0,
895                                     AC_VERB_SET_CONFIG_DEFAULT_BYTES_0 + i,
896                                     val & 0xff);
897                         val >>= 8;
898                 }
899         }
900 }
901
902 /*
903  * ALC880 3-stack model
904  *
905  * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
906  * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
907  *                 F-Mic = 0x1b, HP = 0x19
908  */
909
910 static hda_nid_t alc880_dac_nids[4] = {
911         /* front, rear, clfe, rear_surr */
912         0x02, 0x05, 0x04, 0x03
913 };
914
915 static hda_nid_t alc880_adc_nids[3] = {
916         /* ADC0-2 */
917         0x07, 0x08, 0x09,
918 };
919
920 /* The datasheet says the node 0x07 is connected from inputs,
921  * but it shows zero connection in the real implementation on some devices.
922  * Note: this is a 915GAV bug, fixed on 915GLV
923  */
924 static hda_nid_t alc880_adc_nids_alt[2] = {
925         /* ADC1-2 */
926         0x08, 0x09,
927 };
928
929 #define ALC880_DIGOUT_NID       0x06
930 #define ALC880_DIGIN_NID        0x0a
931
932 static struct hda_input_mux alc880_capture_source = {
933         .num_items = 4,
934         .items = {
935                 { "Mic", 0x0 },
936                 { "Front Mic", 0x3 },
937                 { "Line", 0x2 },
938                 { "CD", 0x4 },
939         },
940 };
941
942 /* channel source setting (2/6 channel selection for 3-stack) */
943 /* 2ch mode */
944 static struct hda_verb alc880_threestack_ch2_init[] = {
945         /* set line-in to input, mute it */
946         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
947         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
948         /* set mic-in to input vref 80%, mute it */
949         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
950         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
951         { } /* end */
952 };
953
954 /* 6ch mode */
955 static struct hda_verb alc880_threestack_ch6_init[] = {
956         /* set line-in to output, unmute it */
957         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
958         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
959         /* set mic-in to output, unmute it */
960         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
961         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
962         { } /* end */
963 };
964
965 static struct hda_channel_mode alc880_threestack_modes[2] = {
966         { 2, alc880_threestack_ch2_init },
967         { 6, alc880_threestack_ch6_init },
968 };
969
970 static struct snd_kcontrol_new alc880_three_stack_mixer[] = {
971         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
972         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
973         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
974         HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
975         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
976         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
977         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
978         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
979         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
980         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
981         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
982         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
983         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
984         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
985         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
986         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
987         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
988         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
989         HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
990         {
991                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
992                 .name = "Channel Mode",
993                 .info = alc_ch_mode_info,
994                 .get = alc_ch_mode_get,
995                 .put = alc_ch_mode_put,
996         },
997         { } /* end */
998 };
999
1000 /* capture mixer elements */
1001 static struct snd_kcontrol_new alc880_capture_mixer[] = {
1002         HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
1003         HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
1004         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
1005         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
1006         HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
1007         HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
1008         {
1009                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1010                 /* The multiple "Capture Source" controls confuse alsamixer
1011                  * So call somewhat different..
1012                  * FIXME: the controls appear in the "playback" view!
1013                  */
1014                 /* .name = "Capture Source", */
1015                 .name = "Input Source",
1016                 .count = 3,
1017                 .info = alc_mux_enum_info,
1018                 .get = alc_mux_enum_get,
1019                 .put = alc_mux_enum_put,
1020         },
1021         { } /* end */
1022 };
1023
1024 /* capture mixer elements (in case NID 0x07 not available) */
1025 static struct snd_kcontrol_new alc880_capture_alt_mixer[] = {
1026         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
1027         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
1028         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
1029         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
1030         {
1031                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1032                 /* The multiple "Capture Source" controls confuse alsamixer
1033                  * So call somewhat different..
1034                  * FIXME: the controls appear in the "playback" view!
1035                  */
1036                 /* .name = "Capture Source", */
1037                 .name = "Input Source",
1038                 .count = 2,
1039                 .info = alc_mux_enum_info,
1040                 .get = alc_mux_enum_get,
1041                 .put = alc_mux_enum_put,
1042         },
1043         { } /* end */
1044 };
1045
1046
1047
1048 /*
1049  * ALC880 5-stack model
1050  *
1051  * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
1052  *      Side = 0x02 (0xd)
1053  * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
1054  *                 Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
1055  */
1056
1057 /* additional mixers to alc880_three_stack_mixer */
1058 static struct snd_kcontrol_new alc880_five_stack_mixer[] = {
1059         HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1060         HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
1061         { } /* end */
1062 };
1063
1064 /* channel source setting (6/8 channel selection for 5-stack) */
1065 /* 6ch mode */
1066 static struct hda_verb alc880_fivestack_ch6_init[] = {
1067         /* set line-in to input, mute it */
1068         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1069         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1070         { } /* end */
1071 };
1072
1073 /* 8ch mode */
1074 static struct hda_verb alc880_fivestack_ch8_init[] = {
1075         /* set line-in to output, unmute it */
1076         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1077         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1078         { } /* end */
1079 };
1080
1081 static struct hda_channel_mode alc880_fivestack_modes[2] = {
1082         { 6, alc880_fivestack_ch6_init },
1083         { 8, alc880_fivestack_ch8_init },
1084 };
1085
1086
1087 /*
1088  * ALC880 6-stack model
1089  *
1090  * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
1091  *      Side = 0x05 (0x0f)
1092  * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
1093  *   Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
1094  */
1095
1096 static hda_nid_t alc880_6st_dac_nids[4] = {
1097         /* front, rear, clfe, rear_surr */
1098         0x02, 0x03, 0x04, 0x05
1099 };
1100
1101 static struct hda_input_mux alc880_6stack_capture_source = {
1102         .num_items = 4,
1103         .items = {
1104                 { "Mic", 0x0 },
1105                 { "Front Mic", 0x1 },
1106                 { "Line", 0x2 },
1107                 { "CD", 0x4 },
1108         },
1109 };
1110
1111 /* fixed 8-channels */
1112 static struct hda_channel_mode alc880_sixstack_modes[1] = {
1113         { 8, NULL },
1114 };
1115
1116 static struct snd_kcontrol_new alc880_six_stack_mixer[] = {
1117         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1118         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1119         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1120         HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1121         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1122         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1123         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1124         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1125         HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1126         HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1127         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1128         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1129         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1130         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1131         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1132         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1133         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1134         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1135         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1136         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1137         {
1138                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1139                 .name = "Channel Mode",
1140                 .info = alc_ch_mode_info,
1141                 .get = alc_ch_mode_get,
1142                 .put = alc_ch_mode_put,
1143         },
1144         { } /* end */
1145 };
1146
1147
1148 /*
1149  * ALC880 W810 model
1150  *
1151  * W810 has rear IO for:
1152  * Front (DAC 02)
1153  * Surround (DAC 03)
1154  * Center/LFE (DAC 04)
1155  * Digital out (06)
1156  *
1157  * The system also has a pair of internal speakers, and a headphone jack.
1158  * These are both connected to Line2 on the codec, hence to DAC 02.
1159  * 
1160  * There is a variable resistor to control the speaker or headphone
1161  * volume. This is a hardware-only device without a software API.
1162  *
1163  * Plugging headphones in will disable the internal speakers. This is
1164  * implemented in hardware, not via the driver using jack sense. In
1165  * a similar fashion, plugging into the rear socket marked "front" will
1166  * disable both the speakers and headphones.
1167  *
1168  * For input, there's a microphone jack, and an "audio in" jack.
1169  * These may not do anything useful with this driver yet, because I
1170  * haven't setup any initialization verbs for these yet...
1171  */
1172
1173 static hda_nid_t alc880_w810_dac_nids[3] = {
1174         /* front, rear/surround, clfe */
1175         0x02, 0x03, 0x04
1176 };
1177
1178 /* fixed 6 channels */
1179 static struct hda_channel_mode alc880_w810_modes[1] = {
1180         { 6, NULL }
1181 };
1182
1183 /* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
1184 static struct snd_kcontrol_new alc880_w810_base_mixer[] = {
1185         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1186         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1187         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1188         HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1189         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1190         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1191         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1192         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1193         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1194         { } /* end */
1195 };
1196
1197
1198 /*
1199  * Z710V model
1200  *
1201  * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
1202  * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
1203  *                 Line = 0x1a
1204  */
1205
1206 static hda_nid_t alc880_z71v_dac_nids[1] = {
1207         0x02
1208 };
1209 #define ALC880_Z71V_HP_DAC      0x03
1210
1211 /* fixed 2 channels */
1212 static struct hda_channel_mode alc880_2_jack_modes[1] = {
1213         { 2, NULL }
1214 };
1215
1216 static struct snd_kcontrol_new alc880_z71v_mixer[] = {
1217         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1218         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1219         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1220         HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
1221         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1222         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1223         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1224         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1225         { } /* end */
1226 };
1227
1228
1229 /* FIXME! */
1230 /*
1231  * ALC880 F1734 model
1232  *
1233  * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
1234  * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
1235  */
1236
1237 static hda_nid_t alc880_f1734_dac_nids[1] = {
1238         0x03
1239 };
1240 #define ALC880_F1734_HP_DAC     0x02
1241
1242 static struct snd_kcontrol_new alc880_f1734_mixer[] = {
1243         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1244         HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1245         HDA_CODEC_VOLUME("Internal Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1246         HDA_BIND_MUTE("Internal Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1247         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1248         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1249         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1250         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1251         { } /* end */
1252 };
1253
1254
1255 /* FIXME! */
1256 /*
1257  * ALC880 ASUS model
1258  *
1259  * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1260  * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1261  *  Mic = 0x18, Line = 0x1a
1262  */
1263
1264 #define alc880_asus_dac_nids    alc880_w810_dac_nids    /* identical with w810 */
1265 #define alc880_asus_modes       alc880_threestack_modes /* 2/6 channel mode */
1266
1267 static struct snd_kcontrol_new alc880_asus_mixer[] = {
1268         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1269         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1270         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1271         HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1272         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1273         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1274         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1275         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1276         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1277         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1278         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1279         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1280         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1281         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1282         {
1283                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1284                 .name = "Channel Mode",
1285                 .info = alc_ch_mode_info,
1286                 .get = alc_ch_mode_get,
1287                 .put = alc_ch_mode_put,
1288         },
1289         { } /* end */
1290 };
1291
1292 /* FIXME! */
1293 /*
1294  * ALC880 ASUS W1V model
1295  *
1296  * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
1297  * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
1298  *  Mic = 0x18, Line = 0x1a, Line2 = 0x1b
1299  */
1300
1301 /* additional mixers to alc880_asus_mixer */
1302 static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
1303         HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
1304         HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
1305         { } /* end */
1306 };
1307
1308 /* additional mixers to alc880_asus_mixer */
1309 static struct snd_kcontrol_new alc880_pcbeep_mixer[] = {
1310         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1311         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1312         { } /* end */
1313 };
1314
1315 /* TCL S700 */
1316 static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
1317         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1318         HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1319         HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
1320         HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
1321         HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
1322         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
1323         HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
1324         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
1325         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
1326         {
1327                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1328                 /* The multiple "Capture Source" controls confuse alsamixer
1329                  * So call somewhat different..
1330                  * FIXME: the controls appear in the "playback" view!
1331                  */
1332                 /* .name = "Capture Source", */
1333                 .name = "Input Source",
1334                 .count = 1,
1335                 .info = alc_mux_enum_info,
1336                 .get = alc_mux_enum_get,
1337                 .put = alc_mux_enum_put,
1338         },
1339         { } /* end */
1340 };
1341
1342 /* Uniwill */
1343 static struct snd_kcontrol_new alc880_uniwill_mixer[] = {
1344         HDA_CODEC_VOLUME("HPhone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1345         HDA_BIND_MUTE("HPhone Playback Switch", 0x0c, 2, HDA_INPUT),
1346         HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1347         HDA_BIND_MUTE("iSpeaker Playback Switch", 0x0d, 2, HDA_INPUT),
1348         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1349         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1350         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1351         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1352         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1353         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1354         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1355         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1356         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1357         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1358         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1359         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1360         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1361         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1362         {
1363                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1364                 .name = "Channel Mode",
1365                 .info = alc_ch_mode_info,
1366                 .get = alc_ch_mode_get,
1367                 .put = alc_ch_mode_put,
1368         },
1369         { } /* end */
1370 };
1371
1372 static struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
1373         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1374         HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1375         HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1376         HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1377         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1378         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1379         HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1380         HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1381         HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1382         HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1383         { } /* end */
1384 };
1385
1386 static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
1387         HDA_CODEC_VOLUME("HPhone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1388         HDA_BIND_MUTE("HPhone Playback Switch", 0x0c, 2, HDA_INPUT),
1389         HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1390         HDA_BIND_MUTE("iSpeaker Playback Switch", 0x0d, 2, HDA_INPUT),
1391         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1392         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1393         { } /* end */
1394 };
1395
1396 /*
1397  * build control elements
1398  */
1399 static int alc_build_controls(struct hda_codec *codec)
1400 {
1401         struct alc_spec *spec = codec->spec;
1402         int err;
1403         int i;
1404
1405         for (i = 0; i < spec->num_mixers; i++) {
1406                 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
1407                 if (err < 0)
1408                         return err;
1409         }
1410
1411         if (spec->multiout.dig_out_nid) {
1412                 err = snd_hda_create_spdif_out_ctls(codec,
1413                                                     spec->multiout.dig_out_nid);
1414                 if (err < 0)
1415                         return err;
1416         }
1417         if (spec->dig_in_nid) {
1418                 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
1419                 if (err < 0)
1420                         return err;
1421         }
1422         return 0;
1423 }
1424
1425
1426 /*
1427  * initialize the codec volumes, etc
1428  */
1429
1430 /*
1431  * generic initialization of ADC, input mixers and output mixers
1432  */
1433 static struct hda_verb alc880_volume_init_verbs[] = {
1434         /*
1435          * Unmute ADC0-2 and set the default input to mic-in
1436          */
1437         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
1438         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1439         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
1440         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1441         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
1442         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1443
1444         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
1445          * mixer widget
1446          * Note: PASD motherboards uses the Line In 2 as the input for front
1447          * panel mic (mic 2)
1448          */
1449         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
1450         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1451         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1452         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
1453         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
1454         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1455         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
1456         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
1457
1458         /*
1459          * Set up output mixers (0x0c - 0x0f)
1460          */
1461         /* set vol=0 to output mixers */
1462         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1463         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1464         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1465         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1466         /* set up input amps for analog loopback */
1467         /* Amp Indices: DAC = 0, mixer = 1 */
1468         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1469         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1470         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1471         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1472         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1473         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1474         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1475         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1476
1477         { }
1478 };
1479
1480 /*
1481  * 3-stack pin configuration:
1482  * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
1483  */
1484 static struct hda_verb alc880_pin_3stack_init_verbs[] = {
1485         /*
1486          * preset connection lists of input pins
1487          * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1488          */
1489         {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
1490         {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1491         {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
1492
1493         /*
1494          * Set pin mode and muting
1495          */
1496         /* set front pin widgets 0x14 for output */
1497         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1498         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1499         /* Mic1 (rear panel) pin widget for input and vref at 80% */
1500         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1501         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1502         /* Mic2 (as headphone out) for HP output */
1503         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1504         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1505         /* Line In pin widget for input */
1506         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1507         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1508         /* Line2 (as front mic) pin widget for input and vref at 80% */
1509         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1510         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1511         /* CD pin widget for input */
1512         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1513
1514         { }
1515 };
1516
1517 /*
1518  * 5-stack pin configuration:
1519  * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
1520  * line-in/side = 0x1a, f-mic = 0x1b
1521  */
1522 static struct hda_verb alc880_pin_5stack_init_verbs[] = {
1523         /*
1524          * preset connection lists of input pins
1525          * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1526          */
1527         {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1528         {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
1529
1530         /*
1531          * Set pin mode and muting
1532          */
1533         /* set pin widgets 0x14-0x17 for output */
1534         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1535         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1536         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1537         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1538         /* unmute pins for output (no gain on this amp) */
1539         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1540         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1541         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1542         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1543
1544         /* Mic1 (rear panel) pin widget for input and vref at 80% */
1545         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1546         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1547         /* Mic2 (as headphone out) for HP output */
1548         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1549         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1550         /* Line In pin widget for input */
1551         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1552         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1553         /* Line2 (as front mic) pin widget for input and vref at 80% */
1554         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1555         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1556         /* CD pin widget for input */
1557         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1558
1559         { }
1560 };
1561
1562 /*
1563  * W810 pin configuration:
1564  * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
1565  */
1566 static struct hda_verb alc880_pin_w810_init_verbs[] = {
1567         /* hphone/speaker input selector: front DAC */
1568         {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
1569
1570         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1571         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1572         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1573         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1574         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1575         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1576
1577         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1578         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1579
1580         { }
1581 };
1582
1583 /*
1584  * Z71V pin configuration:
1585  * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
1586  */
1587 static struct hda_verb alc880_pin_z71v_init_verbs[] = {
1588         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1589         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1590         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1591         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1592
1593         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1594         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1595         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1596         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1597
1598         { }
1599 };
1600
1601 /*
1602  * 6-stack pin configuration:
1603  * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
1604  * f-mic = 0x19, line = 0x1a, HP = 0x1b
1605  */
1606 static struct hda_verb alc880_pin_6stack_init_verbs[] = {
1607         {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1608
1609         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1610         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1611         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1612         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1613         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1614         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1615         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1616         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1617
1618         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1619         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1620         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1621         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1622         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1623         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1624         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1625         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1626         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1627         
1628         { }
1629 };
1630
1631 /*
1632  * Uniwill pin configuration:
1633  * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
1634  * line = 0x1a
1635  */
1636 static struct hda_verb alc880_uniwill_init_verbs[] = {
1637         {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1638
1639         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1640         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1641         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1642         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1643         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1644         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1645         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1646         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1647         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1648         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1649         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1650         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1651         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1652         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1653
1654         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1655         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1656         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1657         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1658         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1659         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1660         /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
1661         /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
1662         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1663
1664         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
1665         {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
1666
1667         { }
1668 };
1669
1670 /*
1671 * Uniwill P53
1672 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x19, 
1673  */
1674 static struct hda_verb alc880_uniwill_p53_init_verbs[] = {
1675         {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1676
1677         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1678         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1679         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1680         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1681         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1682         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1683         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1684         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1685         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1686         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1687         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1688         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1689
1690         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1691         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1692         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1693         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1694         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1695         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1696
1697         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
1698         {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
1699
1700         { }
1701 };
1702
1703 static struct hda_verb alc880_beep_init_verbs[] = {
1704         { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
1705         { }
1706 };
1707
1708 /* toggle speaker-output according to the hp-jack state */
1709 static void alc880_uniwill_hp_automute(struct hda_codec *codec)
1710 {
1711         unsigned int present;
1712         unsigned char bits;
1713
1714         present = snd_hda_codec_read(codec, 0x14, 0,
1715                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1716         bits = present ? HDA_AMP_MUTE : 0;
1717         snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
1718                                  HDA_AMP_MUTE, bits);
1719         snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
1720                                  HDA_AMP_MUTE, bits);
1721 }
1722
1723 /* auto-toggle front mic */
1724 static void alc880_uniwill_mic_automute(struct hda_codec *codec)
1725 {
1726         unsigned int present;
1727         unsigned char bits;
1728
1729         present = snd_hda_codec_read(codec, 0x18, 0,
1730                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1731         bits = present ? HDA_AMP_MUTE : 0;
1732         snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
1733 }
1734
1735 static void alc880_uniwill_automute(struct hda_codec *codec)
1736 {
1737         alc880_uniwill_hp_automute(codec);
1738         alc880_uniwill_mic_automute(codec);
1739 }
1740
1741 static void alc880_uniwill_unsol_event(struct hda_codec *codec,
1742                                        unsigned int res)
1743 {
1744         /* Looks like the unsol event is incompatible with the standard
1745          * definition.  4bit tag is placed at 28 bit!
1746          */
1747         switch (res >> 28) {
1748         case ALC880_HP_EVENT:
1749                 alc880_uniwill_hp_automute(codec);
1750                 break;
1751         case ALC880_MIC_EVENT:
1752                 alc880_uniwill_mic_automute(codec);
1753                 break;
1754         }
1755 }
1756
1757 static void alc880_uniwill_p53_hp_automute(struct hda_codec *codec)
1758 {
1759         unsigned int present;
1760         unsigned char bits;
1761
1762         present = snd_hda_codec_read(codec, 0x14, 0,
1763                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1764         bits = present ? HDA_AMP_MUTE : 0;
1765         snd_hda_codec_amp_stereo(codec, 0x15, HDA_INPUT, 0, HDA_AMP_MUTE, bits);
1766 }
1767
1768 static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
1769 {
1770         unsigned int present;
1771         
1772         present = snd_hda_codec_read(codec, 0x21, 0,
1773                                      AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
1774         present &= HDA_AMP_VOLMASK;
1775         snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
1776                                  HDA_AMP_VOLMASK, present);
1777         snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
1778                                  HDA_AMP_VOLMASK, present);
1779 }
1780
1781 static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
1782                                            unsigned int res)
1783 {
1784         /* Looks like the unsol event is incompatible with the standard
1785          * definition.  4bit tag is placed at 28 bit!
1786          */
1787         if ((res >> 28) == ALC880_HP_EVENT)
1788                 alc880_uniwill_p53_hp_automute(codec);
1789         if ((res >> 28) == ALC880_DCVOL_EVENT)
1790                 alc880_uniwill_p53_dcvol_automute(codec);
1791 }
1792
1793 /* FIXME! */
1794 /*
1795  * F1734 pin configuration:
1796  * HP = 0x14, speaker-out = 0x15, mic = 0x18
1797  */
1798 static struct hda_verb alc880_pin_f1734_init_verbs[] = {
1799         {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
1800         {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
1801         {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
1802         {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
1803
1804         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1805         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1806         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1807         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1808
1809         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1810         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1811         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1812         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1813         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1814         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1815         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1816         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1817         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1818
1819         { }
1820 };
1821
1822 /* FIXME! */
1823 /*
1824  * ASUS pin configuration:
1825  * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
1826  */
1827 static struct hda_verb alc880_pin_asus_init_verbs[] = {
1828         {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
1829         {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
1830         {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
1831         {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
1832
1833         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1834         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1835         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1836         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1837         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1838         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1839         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1840         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1841
1842         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1843         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1844         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1845         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1846         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1847         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1848         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1849         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1850         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1851         
1852         { }
1853 };
1854
1855 /* Enable GPIO mask and set output */
1856 #define alc880_gpio1_init_verbs alc_gpio1_init_verbs
1857 #define alc880_gpio2_init_verbs alc_gpio2_init_verbs
1858
1859 /* Clevo m520g init */
1860 static struct hda_verb alc880_pin_clevo_init_verbs[] = {
1861         /* headphone output */
1862         {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
1863         /* line-out */
1864         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1865         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1866         /* Line-in */
1867         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1868         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1869         /* CD */
1870         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1871         {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1872         /* Mic1 (rear panel) */
1873         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1874         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1875         /* Mic2 (front panel) */
1876         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1877         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1878         /* headphone */
1879         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1880         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1881         /* change to EAPD mode */
1882         {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
1883         {0x20, AC_VERB_SET_PROC_COEF,  0x3060},
1884
1885         { }
1886 };
1887
1888 static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
1889         /* change to EAPD mode */
1890         {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
1891         {0x20, AC_VERB_SET_PROC_COEF,  0x3060},
1892
1893         /* Headphone output */
1894         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1895         /* Front output*/
1896         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1897         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1898
1899         /* Line In pin widget for input */
1900         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1901         /* CD pin widget for input */
1902         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1903         /* Mic1 (rear panel) pin widget for input and vref at 80% */
1904         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1905
1906         /* change to EAPD mode */
1907         {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
1908         {0x20, AC_VERB_SET_PROC_COEF,  0x3070},
1909
1910         { }
1911 };
1912
1913 /*
1914  * LG m1 express dual
1915  *
1916  * Pin assignment:
1917  *   Rear Line-In/Out (blue): 0x14
1918  *   Build-in Mic-In: 0x15
1919  *   Speaker-out: 0x17
1920  *   HP-Out (green): 0x1b
1921  *   Mic-In/Out (red): 0x19
1922  *   SPDIF-Out: 0x1e
1923  */
1924
1925 /* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
1926 static hda_nid_t alc880_lg_dac_nids[3] = {
1927         0x05, 0x02, 0x03
1928 };
1929
1930 /* seems analog CD is not working */
1931 static struct hda_input_mux alc880_lg_capture_source = {
1932         .num_items = 3,
1933         .items = {
1934                 { "Mic", 0x1 },
1935                 { "Line", 0x5 },
1936                 { "Internal Mic", 0x6 },
1937         },
1938 };
1939
1940 /* 2,4,6 channel modes */
1941 static struct hda_verb alc880_lg_ch2_init[] = {
1942         /* set line-in and mic-in to input */
1943         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1944         { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1945         { }
1946 };
1947
1948 static struct hda_verb alc880_lg_ch4_init[] = {
1949         /* set line-in to out and mic-in to input */
1950         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
1951         { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1952         { }
1953 };
1954
1955 static struct hda_verb alc880_lg_ch6_init[] = {
1956         /* set line-in and mic-in to output */
1957         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
1958         { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
1959         { }
1960 };
1961
1962 static struct hda_channel_mode alc880_lg_ch_modes[3] = {
1963         { 2, alc880_lg_ch2_init },
1964         { 4, alc880_lg_ch4_init },
1965         { 6, alc880_lg_ch6_init },
1966 };
1967
1968 static struct snd_kcontrol_new alc880_lg_mixer[] = {
1969         /* FIXME: it's not really "master" but front channels */
1970         HDA_CODEC_VOLUME("Master Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1971         HDA_BIND_MUTE("Master Playback Switch", 0x0f, 2, HDA_INPUT),
1972         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1973         HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
1974         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
1975         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
1976         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
1977         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
1978         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1979         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1980         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
1981         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
1982         HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
1983         HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
1984         {
1985                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1986                 .name = "Channel Mode",
1987                 .info = alc_ch_mode_info,
1988                 .get = alc_ch_mode_get,
1989                 .put = alc_ch_mode_put,
1990         },
1991         { } /* end */
1992 };
1993
1994 static struct hda_verb alc880_lg_init_verbs[] = {
1995         /* set capture source to mic-in */
1996         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1997         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1998         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1999         /* mute all amp mixer inputs */
2000         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
2001         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2002         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2003         /* line-in to input */
2004         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2005         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2006         /* built-in mic */
2007         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2008         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2009         /* speaker-out */
2010         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2011         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2012         /* mic-in to input */
2013         {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
2014         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2015         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2016         /* HP-out */
2017         {0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
2018         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2019         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2020         /* jack sense */
2021         {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
2022         { }
2023 };
2024
2025 /* toggle speaker-output according to the hp-jack state */
2026 static void alc880_lg_automute(struct hda_codec *codec)
2027 {
2028         unsigned int present;
2029         unsigned char bits;
2030
2031         present = snd_hda_codec_read(codec, 0x1b, 0,
2032                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2033         bits = present ? HDA_AMP_MUTE : 0;
2034         snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0,
2035                                  HDA_AMP_MUTE, bits);
2036 }
2037
2038 static void alc880_lg_unsol_event(struct hda_codec *codec, unsigned int res)
2039 {
2040         /* Looks like the unsol event is incompatible with the standard
2041          * definition.  4bit tag is placed at 28 bit!
2042          */
2043         if ((res >> 28) == 0x01)
2044                 alc880_lg_automute(codec);
2045 }
2046
2047 /*
2048  * LG LW20
2049  *
2050  * Pin assignment:
2051  *   Speaker-out: 0x14
2052  *   Mic-In: 0x18
2053  *   Built-in Mic-In: 0x19
2054  *   Line-In: 0x1b
2055  *   HP-Out: 0x1a
2056  *   SPDIF-Out: 0x1e
2057  */
2058
2059 static struct hda_input_mux alc880_lg_lw_capture_source = {
2060         .num_items = 3,
2061         .items = {
2062                 { "Mic", 0x0 },
2063                 { "Internal Mic", 0x1 },
2064                 { "Line In", 0x2 },
2065         },
2066 };
2067
2068 #define alc880_lg_lw_modes alc880_threestack_modes
2069
2070 static struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
2071         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2072         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2073         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2074         HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
2075         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2076         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2077         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2078         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2079         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2080         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2081         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2082         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2083         HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
2084         HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
2085         {
2086                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2087                 .name = "Channel Mode",
2088                 .info = alc_ch_mode_info,
2089                 .get = alc_ch_mode_get,
2090                 .put = alc_ch_mode_put,
2091         },
2092         { } /* end */
2093 };
2094
2095 static struct hda_verb alc880_lg_lw_init_verbs[] = {
2096         {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
2097         {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
2098         {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
2099
2100         /* set capture source to mic-in */
2101         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2102         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2103         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2104         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2105         /* speaker-out */
2106         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2107         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2108         /* HP-out */
2109         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2110         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2111         /* mic-in to input */
2112         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2113         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2114         /* built-in mic */
2115         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2116         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2117         /* jack sense */
2118         {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | 0x1},
2119         { }
2120 };
2121
2122 /* toggle speaker-output according to the hp-jack state */
2123 static void alc880_lg_lw_automute(struct hda_codec *codec)
2124 {
2125         unsigned int present;
2126         unsigned char bits;
2127
2128         present = snd_hda_codec_read(codec, 0x1b, 0,
2129                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2130         bits = present ? HDA_AMP_MUTE : 0;
2131         snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
2132                                  HDA_AMP_MUTE, bits);
2133 }
2134
2135 static void alc880_lg_lw_unsol_event(struct hda_codec *codec, unsigned int res)
2136 {
2137         /* Looks like the unsol event is incompatible with the standard
2138          * definition.  4bit tag is placed at 28 bit!
2139          */
2140         if ((res >> 28) == 0x01)
2141                 alc880_lg_lw_automute(codec);
2142 }
2143
2144 #ifdef CONFIG_SND_HDA_POWER_SAVE
2145 static struct hda_amp_list alc880_loopbacks[] = {
2146         { 0x0b, HDA_INPUT, 0 },
2147         { 0x0b, HDA_INPUT, 1 },
2148         { 0x0b, HDA_INPUT, 2 },
2149         { 0x0b, HDA_INPUT, 3 },
2150         { 0x0b, HDA_INPUT, 4 },
2151         { } /* end */
2152 };
2153
2154 static struct hda_amp_list alc880_lg_loopbacks[] = {
2155         { 0x0b, HDA_INPUT, 1 },
2156         { 0x0b, HDA_INPUT, 6 },
2157         { 0x0b, HDA_INPUT, 7 },
2158         { } /* end */
2159 };
2160 #endif
2161
2162 /*
2163  * Common callbacks
2164  */
2165
2166 static int alc_init(struct hda_codec *codec)
2167 {
2168         struct alc_spec *spec = codec->spec;
2169         unsigned int i;
2170
2171         for (i = 0; i < spec->num_init_verbs; i++)
2172                 snd_hda_sequence_write(codec, spec->init_verbs[i]);
2173
2174         if (spec->init_hook)
2175                 spec->init_hook(codec);
2176
2177         return 0;
2178 }
2179
2180 static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
2181 {
2182         struct alc_spec *spec = codec->spec;
2183
2184         if (spec->unsol_event)
2185                 spec->unsol_event(codec, res);
2186 }
2187
2188 #ifdef CONFIG_SND_HDA_POWER_SAVE
2189 static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
2190 {
2191         struct alc_spec *spec = codec->spec;
2192         return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
2193 }
2194 #endif
2195
2196 /*
2197  * Analog playback callbacks
2198  */
2199 static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
2200                                     struct hda_codec *codec,
2201                                     struct snd_pcm_substream *substream)
2202 {
2203         struct alc_spec *spec = codec->spec;
2204         return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream);
2205 }
2206
2207 static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
2208                                        struct hda_codec *codec,
2209                                        unsigned int stream_tag,
2210                                        unsigned int format,
2211                                        struct snd_pcm_substream *substream)
2212 {
2213         struct alc_spec *spec = codec->spec;
2214         return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
2215                                                 stream_tag, format, substream);
2216 }
2217
2218 static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
2219                                        struct hda_codec *codec,
2220                                        struct snd_pcm_substream *substream)
2221 {
2222         struct alc_spec *spec = codec->spec;
2223         return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
2224 }
2225
2226 /*
2227  * Digital out
2228  */
2229 static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
2230                                         struct hda_codec *codec,
2231                                         struct snd_pcm_substream *substream)
2232 {
2233         struct alc_spec *spec = codec->spec;
2234         return snd_hda_multi_out_dig_open(codec, &spec->multiout);
2235 }
2236
2237 static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
2238                                            struct hda_codec *codec,
2239                                            unsigned int stream_tag,
2240                                            unsigned int format,
2241                                            struct snd_pcm_substream *substream)
2242 {
2243         struct alc_spec *spec = codec->spec;
2244         return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
2245                                              stream_tag, format, substream);
2246 }
2247
2248 static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
2249                                          struct hda_codec *codec,
2250                                          struct snd_pcm_substream *substream)
2251 {
2252         struct alc_spec *spec = codec->spec;
2253         return snd_hda_multi_out_dig_close(codec, &spec->multiout);
2254 }
2255
2256 /*
2257  * Analog capture
2258  */
2259 static int alc880_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
2260                                       struct hda_codec *codec,
2261                                       unsigned int stream_tag,
2262                                       unsigned int format,
2263                                       struct snd_pcm_substream *substream)
2264 {
2265         struct alc_spec *spec = codec->spec;
2266
2267         snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
2268                                    stream_tag, 0, format);
2269         return 0;
2270 }
2271
2272 static int alc880_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
2273                                       struct hda_codec *codec,
2274                                       struct snd_pcm_substream *substream)
2275 {
2276         struct alc_spec *spec = codec->spec;
2277
2278         snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
2279                                    0, 0, 0);
2280         return 0;
2281 }
2282
2283
2284 /*
2285  */
2286 static struct hda_pcm_stream alc880_pcm_analog_playback = {
2287         .substreams = 1,
2288         .channels_min = 2,
2289         .channels_max = 8,
2290         /* NID is set in alc_build_pcms */
2291         .ops = {
2292                 .open = alc880_playback_pcm_open,
2293                 .prepare = alc880_playback_pcm_prepare,
2294                 .cleanup = alc880_playback_pcm_cleanup
2295         },
2296 };
2297
2298 static struct hda_pcm_stream alc880_pcm_analog_capture = {
2299         .substreams = 2,
2300         .channels_min = 2,
2301         .channels_max = 2,
2302         /* NID is set in alc_build_pcms */
2303         .ops = {
2304                 .prepare = alc880_capture_pcm_prepare,
2305                 .cleanup = alc880_capture_pcm_cleanup
2306         },
2307 };
2308
2309 static struct hda_pcm_stream alc880_pcm_digital_playback = {
2310         .substreams = 1,
2311         .channels_min = 2,
2312         .channels_max = 2,
2313         /* NID is set in alc_build_pcms */
2314         .ops = {
2315                 .open = alc880_dig_playback_pcm_open,
2316                 .close = alc880_dig_playback_pcm_close,
2317                 .prepare = alc880_dig_playback_pcm_prepare
2318         },
2319 };
2320
2321 static struct hda_pcm_stream alc880_pcm_digital_capture = {
2322         .substreams = 1,
2323         .channels_min = 2,
2324         .channels_max = 2,
2325         /* NID is set in alc_build_pcms */
2326 };
2327
2328 /* Used by alc_build_pcms to flag that a PCM has no playback stream */
2329 static struct hda_pcm_stream alc_pcm_null_playback = {
2330         .substreams = 0,
2331         .channels_min = 0,
2332         .channels_max = 0,
2333 };
2334
2335 static int alc_build_pcms(struct hda_codec *codec)
2336 {
2337         struct alc_spec *spec = codec->spec;
2338         struct hda_pcm *info = spec->pcm_rec;
2339         int i;
2340
2341         codec->num_pcms = 1;
2342         codec->pcm_info = info;
2343
2344         info->name = spec->stream_name_analog;
2345         if (spec->stream_analog_playback) {
2346                 snd_assert(spec->multiout.dac_nids, return -EINVAL);
2347                 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
2348                 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
2349         }
2350         if (spec->stream_analog_capture) {
2351                 snd_assert(spec->adc_nids, return -EINVAL);
2352                 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
2353                 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
2354         }
2355
2356         if (spec->channel_mode) {
2357                 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
2358                 for (i = 0; i < spec->num_channel_mode; i++) {
2359                         if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
2360                                 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
2361                         }
2362                 }
2363         }
2364
2365         /* SPDIF for stream index #1 */
2366         if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
2367                 codec->num_pcms = 2;
2368                 info = spec->pcm_rec + 1;
2369                 info->name = spec->stream_name_digital;
2370                 if (spec->multiout.dig_out_nid &&
2371                     spec->stream_digital_playback) {
2372                         info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
2373                         info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
2374                 }
2375                 if (spec->dig_in_nid &&
2376                     spec->stream_digital_capture) {
2377                         info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
2378                         info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
2379                 }
2380         }
2381
2382         /* If the use of more than one ADC is requested for the current
2383          * model, configure a second analog capture-only PCM.
2384          */
2385         /* Additional Analaog capture for index #2 */
2386         if (spec->num_adc_nids > 1 && spec->stream_analog_capture &&
2387             spec->adc_nids) {
2388                 codec->num_pcms = 3;
2389                 info = spec->pcm_rec + 2;
2390                 info->name = spec->stream_name_analog;
2391                 /* No playback stream for second PCM */
2392                 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = alc_pcm_null_playback;
2393                 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
2394                 if (spec->stream_analog_capture) {
2395                         info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
2396                         info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[1];
2397                 }
2398         }
2399
2400         return 0;
2401 }
2402
2403 static void alc_free(struct hda_codec *codec)
2404 {
2405         struct alc_spec *spec = codec->spec;
2406         unsigned int i;
2407
2408         if (!spec)
2409                 return;
2410
2411         if (spec->kctl_alloc) {
2412                 for (i = 0; i < spec->num_kctl_used; i++)
2413                         kfree(spec->kctl_alloc[i].name);
2414                 kfree(spec->kctl_alloc);
2415         }
2416         kfree(spec);
2417 }
2418
2419 /*
2420  */
2421 static struct hda_codec_ops alc_patch_ops = {
2422         .build_controls = alc_build_controls,
2423         .build_pcms = alc_build_pcms,
2424         .init = alc_init,
2425         .free = alc_free,
2426         .unsol_event = alc_unsol_event,
2427 #ifdef CONFIG_SND_HDA_POWER_SAVE
2428         .check_power_status = alc_check_power_status,
2429 #endif
2430 };
2431
2432
2433 /*
2434  * Test configuration for debugging
2435  *
2436  * Almost all inputs/outputs are enabled.  I/O pins can be configured via
2437  * enum controls.
2438  */
2439 #ifdef CONFIG_SND_DEBUG
2440 static hda_nid_t alc880_test_dac_nids[4] = {
2441         0x02, 0x03, 0x04, 0x05
2442 };
2443
2444 static struct hda_input_mux alc880_test_capture_source = {
2445         .num_items = 7,
2446         .items = {
2447                 { "In-1", 0x0 },
2448                 { "In-2", 0x1 },
2449                 { "In-3", 0x2 },
2450                 { "In-4", 0x3 },
2451                 { "CD", 0x4 },
2452                 { "Front", 0x5 },
2453                 { "Surround", 0x6 },
2454         },
2455 };
2456
2457 static struct hda_channel_mode alc880_test_modes[4] = {
2458         { 2, NULL },
2459         { 4, NULL },
2460         { 6, NULL },
2461         { 8, NULL },
2462 };
2463
2464 static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
2465                                  struct snd_ctl_elem_info *uinfo)
2466 {
2467         static char *texts[] = {
2468                 "N/A", "Line Out", "HP Out",
2469                 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
2470         };
2471         uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2472         uinfo->count = 1;
2473         uinfo->value.enumerated.items = 8;
2474         if (uinfo->value.enumerated.item >= 8)
2475                 uinfo->value.enumerated.item = 7;
2476         strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2477         return 0;
2478 }
2479
2480 static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
2481                                 struct snd_ctl_elem_value *ucontrol)
2482 {
2483         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2484         hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2485         unsigned int pin_ctl, item = 0;
2486
2487         pin_ctl = snd_hda_codec_read(codec, nid, 0,
2488                                      AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
2489         if (pin_ctl & AC_PINCTL_OUT_EN) {
2490                 if (pin_ctl & AC_PINCTL_HP_EN)
2491                         item = 2;
2492                 else
2493                         item = 1;
2494         } else if (pin_ctl & AC_PINCTL_IN_EN) {
2495                 switch (pin_ctl & AC_PINCTL_VREFEN) {
2496                 case AC_PINCTL_VREF_HIZ: item = 3; break;
2497                 case AC_PINCTL_VREF_50:  item = 4; break;
2498                 case AC_PINCTL_VREF_GRD: item = 5; break;
2499                 case AC_PINCTL_VREF_80:  item = 6; break;
2500                 case AC_PINCTL_VREF_100: item = 7; break;
2501                 }
2502         }
2503         ucontrol->value.enumerated.item[0] = item;
2504         return 0;
2505 }
2506
2507 static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
2508                                 struct snd_ctl_elem_value *ucontrol)
2509 {
2510         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2511         hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2512         static unsigned int ctls[] = {
2513                 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
2514                 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
2515                 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
2516                 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
2517                 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
2518                 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
2519         };
2520         unsigned int old_ctl, new_ctl;
2521
2522         old_ctl = snd_hda_codec_read(codec, nid, 0,
2523                                      AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
2524         new_ctl = ctls[ucontrol->value.enumerated.item[0]];
2525         if (old_ctl != new_ctl) {
2526                 int val;
2527                 snd_hda_codec_write_cache(codec, nid, 0,
2528                                           AC_VERB_SET_PIN_WIDGET_CONTROL,
2529                                           new_ctl);
2530                 val = ucontrol->value.enumerated.item[0] >= 3 ?
2531                         HDA_AMP_MUTE : 0;
2532                 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
2533                                          HDA_AMP_MUTE, val);
2534                 return 1;
2535         }
2536         return 0;
2537 }
2538
2539 static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
2540                                  struct snd_ctl_elem_info *uinfo)
2541 {
2542         static char *texts[] = {
2543                 "Front", "Surround", "CLFE", "Side"
2544         };
2545         uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2546         uinfo->count = 1;
2547         uinfo->value.enumerated.items = 4;
2548         if (uinfo->value.enumerated.item >= 4)
2549                 uinfo->value.enumerated.item = 3;
2550         strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2551         return 0;
2552 }
2553
2554 static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
2555                                 struct snd_ctl_elem_value *ucontrol)
2556 {
2557         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2558         hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2559         unsigned int sel;
2560
2561         sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
2562         ucontrol->value.enumerated.item[0] = sel & 3;
2563         return 0;
2564 }
2565
2566 static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
2567                                 struct snd_ctl_elem_value *ucontrol)
2568 {
2569         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2570         hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
2571         unsigned int sel;
2572
2573         sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
2574         if (ucontrol->value.enumerated.item[0] != sel) {
2575                 sel = ucontrol->value.enumerated.item[0] & 3;
2576                 snd_hda_codec_write_cache(codec, nid, 0,
2577                                           AC_VERB_SET_CONNECT_SEL, sel);
2578                 return 1;
2579         }
2580         return 0;
2581 }
2582
2583 #define PIN_CTL_TEST(xname,nid) {                       \
2584                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,    \
2585                         .name = xname,                 \
2586                         .info = alc_test_pin_ctl_info, \
2587                         .get = alc_test_pin_ctl_get,   \
2588                         .put = alc_test_pin_ctl_put,   \
2589                         .private_value = nid           \
2590                         }
2591
2592 #define PIN_SRC_TEST(xname,nid) {                       \
2593                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,    \
2594                         .name = xname,                 \
2595                         .info = alc_test_pin_src_info, \
2596                         .get = alc_test_pin_src_get,   \
2597                         .put = alc_test_pin_src_put,   \
2598                         .private_value = nid           \
2599                         }
2600
2601 static struct snd_kcontrol_new alc880_test_mixer[] = {
2602         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2603         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2604         HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
2605         HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2606         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2607         HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2608         HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
2609         HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2610         PIN_CTL_TEST("Front Pin Mode", 0x14),
2611         PIN_CTL_TEST("Surround Pin Mode", 0x15),
2612         PIN_CTL_TEST("CLFE Pin Mode", 0x16),
2613         PIN_CTL_TEST("Side Pin Mode", 0x17),
2614         PIN_CTL_TEST("In-1 Pin Mode", 0x18),
2615         PIN_CTL_TEST("In-2 Pin Mode", 0x19),
2616         PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
2617         PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
2618         PIN_SRC_TEST("In-1 Pin Source", 0x18),
2619         PIN_SRC_TEST("In-2 Pin Source", 0x19),
2620         PIN_SRC_TEST("In-3 Pin Source", 0x1a),
2621         PIN_SRC_TEST("In-4 Pin Source", 0x1b),
2622         HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
2623         HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
2624         HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
2625         HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
2626         HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
2627         HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
2628         HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
2629         HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
2630         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
2631         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
2632         {
2633                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2634                 .name = "Channel Mode",
2635                 .info = alc_ch_mode_info,
2636                 .get = alc_ch_mode_get,
2637                 .put = alc_ch_mode_put,
2638         },
2639         { } /* end */
2640 };
2641
2642 static struct hda_verb alc880_test_init_verbs[] = {
2643         /* Unmute inputs of 0x0c - 0x0f */
2644         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2645         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2646         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2647         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2648         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2649         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2650         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2651         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2652         /* Vol output for 0x0c-0x0f */
2653         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2654         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2655         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2656         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2657         /* Set output pins 0x14-0x17 */
2658         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2659         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2660         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2661         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2662         /* Unmute output pins 0x14-0x17 */
2663         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2664         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2665         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2666         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2667         /* Set input pins 0x18-0x1c */
2668         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2669         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2670         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2671         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2672         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2673         /* Mute input pins 0x18-0x1b */
2674         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2675         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2676         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2677         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2678         /* ADC set up */
2679         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2680         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
2681         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2682         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
2683         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2684         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
2685         /* Analog input/passthru */
2686         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2687         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2688         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2689         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2690         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2691         { }
2692 };
2693 #endif
2694
2695 /*
2696  */
2697
2698 static const char *alc880_models[ALC880_MODEL_LAST] = {
2699         [ALC880_3ST]            = "3stack",
2700         [ALC880_TCL_S700]       = "tcl",
2701         [ALC880_3ST_DIG]        = "3stack-digout",
2702         [ALC880_CLEVO]          = "clevo",
2703         [ALC880_5ST]            = "5stack",
2704         [ALC880_5ST_DIG]        = "5stack-digout",
2705         [ALC880_W810]           = "w810",
2706         [ALC880_Z71V]           = "z71v",
2707         [ALC880_6ST]            = "6stack",
2708         [ALC880_6ST_DIG]        = "6stack-digout",
2709         [ALC880_ASUS]           = "asus",
2710         [ALC880_ASUS_W1V]       = "asus-w1v",
2711         [ALC880_ASUS_DIG]       = "asus-dig",
2712         [ALC880_ASUS_DIG2]      = "asus-dig2",
2713         [ALC880_UNIWILL_DIG]    = "uniwill",
2714         [ALC880_UNIWILL_P53]    = "uniwill-p53",
2715         [ALC880_FUJITSU]        = "fujitsu",
2716         [ALC880_F1734]          = "F1734",
2717         [ALC880_LG]             = "lg",
2718         [ALC880_LG_LW]          = "lg-lw",
2719 #ifdef CONFIG_SND_DEBUG
2720         [ALC880_TEST]           = "test",
2721 #endif
2722         [ALC880_AUTO]           = "auto",
2723 };
2724
2725 static struct snd_pci_quirk alc880_cfg_tbl[] = {
2726         /* Broken BIOS configuration */
2727         SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG),
2728         SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
2729
2730         SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
2731         SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
2732         SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
2733         SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
2734         SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
2735         SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
2736         SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
2737         SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
2738         SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
2739
2740         SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
2741         SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST),
2742
2743         SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
2744         SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
2745         SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
2746         SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
2747         SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
2748         SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
2749         SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
2750         /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
2751         SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
2752         SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
2753         SND_PCI_QUIRK(0x1043, 0x814e, "ASUS", ALC880_ASUS),
2754         SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
2755         SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
2756         SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
2757         SND_PCI_QUIRK(0x1043, 0, "ASUS", ALC880_ASUS),
2758
2759         SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
2760         SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
2761         SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
2762         SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
2763         SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
2764         SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
2765         SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
2766         SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
2767         SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
2768         SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
2769         SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
2770         SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
2771         SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
2772         SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
2773         SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
2774         SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
2775         SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
2776         SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
2777
2778         SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
2779         SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
2780         SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
2781         SND_PCI_QUIRK(0x1584, 0x9054, "Uniwlll", ALC880_F1734),
2782
2783         SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
2784         SND_PCI_QUIRK(0x1734, 0x10ac, "FSC", ALC880_UNIWILL),
2785         SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
2786         SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
2787
2788         SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
2789         SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
2790         SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
2791         SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
2792
2793         SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
2794         SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
2795         SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
2796         SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
2797         SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
2798         SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
2799         SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
2800         SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
2801         SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
2802         SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
2803         SND_PCI_QUIRK(0x8086, 0, "Intel mobo", ALC880_3ST),
2804
2805         {}
2806 };
2807
2808 /*
2809  * ALC880 codec presets
2810  */
2811 static struct alc_config_preset alc880_presets[] = {
2812         [ALC880_3ST] = {
2813                 .mixers = { alc880_three_stack_mixer },
2814                 .init_verbs = { alc880_volume_init_verbs,
2815                                 alc880_pin_3stack_init_verbs },
2816                 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
2817                 .dac_nids = alc880_dac_nids,
2818                 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
2819                 .channel_mode = alc880_threestack_modes,
2820                 .need_dac_fix = 1,
2821                 .input_mux = &alc880_capture_source,
2822         },
2823         [ALC880_3ST_DIG] = {
2824                 .mixers = { alc880_three_stack_mixer },
2825                 .init_verbs = { alc880_volume_init_verbs,
2826                                 alc880_pin_3stack_init_verbs },
2827                 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
2828                 .dac_nids = alc880_dac_nids,
2829                 .dig_out_nid = ALC880_DIGOUT_NID,
2830                 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
2831                 .channel_mode = alc880_threestack_modes,
2832                 .need_dac_fix = 1,
2833                 .input_mux = &alc880_capture_source,
2834         },
2835         [ALC880_TCL_S700] = {
2836                 .mixers = { alc880_tcl_s700_mixer },
2837                 .init_verbs = { alc880_volume_init_verbs,
2838                                 alc880_pin_tcl_S700_init_verbs,
2839                                 alc880_gpio2_init_verbs },
2840                 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
2841                 .dac_nids = alc880_dac_nids,
2842                 .hp_nid = 0x03,
2843                 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
2844                 .channel_mode = alc880_2_jack_modes,
2845                 .input_mux = &alc880_capture_source,
2846         },
2847         [ALC880_5ST] = {
2848                 .mixers = { alc880_three_stack_mixer,
2849                             alc880_five_stack_mixer},
2850                 .init_verbs = { alc880_volume_init_verbs,
2851                                 alc880_pin_5stack_init_verbs },
2852                 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
2853                 .dac_nids = alc880_dac_nids,
2854                 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
2855                 .channel_mode = alc880_fivestack_modes,
2856                 .input_mux = &alc880_capture_source,
2857         },
2858         [ALC880_5ST_DIG] = {
2859                 .mixers = { alc880_three_stack_mixer,
2860                             alc880_five_stack_mixer },
2861                 .init_verbs = { alc880_volume_init_verbs,
2862                                 alc880_pin_5stack_init_verbs },
2863                 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
2864                 .dac_nids = alc880_dac_nids,
2865                 .dig_out_nid = ALC880_DIGOUT_NID,
2866                 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
2867                 .channel_mode = alc880_fivestack_modes,
2868                 .input_mux = &alc880_capture_source,
2869         },
2870         [ALC880_6ST] = {
2871                 .mixers = { alc880_six_stack_mixer },
2872                 .init_verbs = { alc880_volume_init_verbs,
2873                                 alc880_pin_6stack_init_verbs },
2874                 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
2875                 .dac_nids = alc880_6st_dac_nids,
2876                 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
2877                 .channel_mode = alc880_sixstack_modes,
2878                 .input_mux = &alc880_6stack_capture_source,
2879         },
2880         [ALC880_6ST_DIG] = {
2881                 .mixers = { alc880_six_stack_mixer },
2882                 .init_verbs = { alc880_volume_init_verbs,
2883                                 alc880_pin_6stack_init_verbs },
2884                 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
2885                 .dac_nids = alc880_6st_dac_nids,
2886                 .dig_out_nid = ALC880_DIGOUT_NID,
2887                 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
2888                 .channel_mode = alc880_sixstack_modes,
2889                 .input_mux = &alc880_6stack_capture_source,
2890         },
2891         [ALC880_W810] = {
2892                 .mixers = { alc880_w810_base_mixer },
2893                 .init_verbs = { alc880_volume_init_verbs,
2894                                 alc880_pin_w810_init_verbs,
2895                                 alc880_gpio2_init_verbs },
2896                 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
2897                 .dac_nids = alc880_w810_dac_nids,
2898                 .dig_out_nid = ALC880_DIGOUT_NID,
2899                 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
2900                 .channel_mode = alc880_w810_modes,
2901                 .input_mux = &alc880_capture_source,
2902         },
2903         [ALC880_Z71V] = {
2904                 .mixers = { alc880_z71v_mixer },
2905                 .init_verbs = { alc880_volume_init_verbs,
2906                                 alc880_pin_z71v_init_verbs },
2907                 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
2908                 .dac_nids = alc880_z71v_dac_nids,
2909                 .dig_out_nid = ALC880_DIGOUT_NID,
2910                 .hp_nid = 0x03,
2911                 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
2912                 .channel_mode = alc880_2_jack_modes,
2913                 .input_mux = &alc880_capture_source,
2914         },
2915         [ALC880_F1734] = {
2916                 .mixers = { alc880_f1734_mixer },
2917                 .init_verbs = { alc880_volume_init_verbs,
2918                                 alc880_pin_f1734_init_verbs },
2919                 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
2920                 .dac_nids = alc880_f1734_dac_nids,
2921                 .hp_nid = 0x02,
2922                 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
2923                 .channel_mode = alc880_2_jack_modes,
2924                 .input_mux = &alc880_capture_source,
2925         },
2926         [ALC880_ASUS] = {
2927                 .mixers = { alc880_asus_mixer },
2928                 .init_verbs = { alc880_volume_init_verbs,
2929                                 alc880_pin_asus_init_verbs,
2930                                 alc880_gpio1_init_verbs },
2931                 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2932                 .dac_nids = alc880_asus_dac_nids,
2933                 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
2934                 .channel_mode = alc880_asus_modes,
2935                 .need_dac_fix = 1,
2936                 .input_mux = &alc880_capture_source,
2937         },
2938         [ALC880_ASUS_DIG] = {
2939                 .mixers = { alc880_asus_mixer },
2940                 .init_verbs = { alc880_volume_init_verbs,
2941                                 alc880_pin_asus_init_verbs,
2942                                 alc880_gpio1_init_verbs },
2943                 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2944                 .dac_nids = alc880_asus_dac_nids,
2945                 .dig_out_nid = ALC880_DIGOUT_NID,
2946                 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
2947                 .channel_mode = alc880_asus_modes,
2948                 .need_dac_fix = 1,
2949                 .input_mux = &alc880_capture_source,
2950         },
2951         [ALC880_ASUS_DIG2] = {
2952                 .mixers = { alc880_asus_mixer },
2953                 .init_verbs = { alc880_volume_init_verbs,
2954                                 alc880_pin_asus_init_verbs,
2955                                 alc880_gpio2_init_verbs }, /* use GPIO2 */
2956                 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2957                 .dac_nids = alc880_asus_dac_nids,
2958                 .dig_out_nid = ALC880_DIGOUT_NID,
2959                 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
2960                 .channel_mode = alc880_asus_modes,
2961                 .need_dac_fix = 1,
2962                 .input_mux = &alc880_capture_source,
2963         },
2964         [ALC880_ASUS_W1V] = {
2965                 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
2966                 .init_verbs = { alc880_volume_init_verbs,
2967                                 alc880_pin_asus_init_verbs,
2968                                 alc880_gpio1_init_verbs },
2969                 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2970                 .dac_nids = alc880_asus_dac_nids,
2971                 .dig_out_nid = ALC880_DIGOUT_NID,
2972                 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
2973                 .channel_mode = alc880_asus_modes,
2974                 .need_dac_fix = 1,
2975                 .input_mux = &alc880_capture_source,
2976         },
2977         [ALC880_UNIWILL_DIG] = {
2978                 .mixers = { alc880_asus_mixer, alc880_pcbeep_mixer },
2979                 .init_verbs = { alc880_volume_init_verbs,
2980                                 alc880_pin_asus_init_verbs },
2981                 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2982                 .dac_nids = alc880_asus_dac_nids,
2983                 .dig_out_nid = ALC880_DIGOUT_NID,
2984                 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
2985                 .channel_mode = alc880_asus_modes,
2986                 .need_dac_fix = 1,
2987                 .input_mux = &alc880_capture_source,
2988         },
2989         [ALC880_UNIWILL] = {
2990                 .mixers = { alc880_uniwill_mixer },
2991                 .init_verbs = { alc880_volume_init_verbs,
2992                                 alc880_uniwill_init_verbs },
2993                 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2994                 .dac_nids = alc880_asus_dac_nids,
2995                 .dig_out_nid = ALC880_DIGOUT_NID,
2996                 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
2997                 .channel_mode = alc880_threestack_modes,
2998                 .need_dac_fix = 1,
2999                 .input_mux = &alc880_capture_source,
3000                 .unsol_event = alc880_uniwill_unsol_event,
3001                 .init_hook = alc880_uniwill_automute,
3002         },
3003         [ALC880_UNIWILL_P53] = {
3004                 .mixers = { alc880_uniwill_p53_mixer },
3005                 .init_verbs = { alc880_volume_init_verbs,
3006                                 alc880_uniwill_p53_init_verbs },
3007                 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
3008                 .dac_nids = alc880_asus_dac_nids,
3009                 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
3010                 .channel_mode = alc880_threestack_modes,
3011                 .input_mux = &alc880_capture_source,
3012                 .unsol_event = alc880_uniwill_p53_unsol_event,
3013                 .init_hook = alc880_uniwill_p53_hp_automute,
3014         },
3015         [ALC880_FUJITSU] = {
3016                 .mixers = { alc880_fujitsu_mixer,
3017                             alc880_pcbeep_mixer, },
3018                 .init_verbs = { alc880_volume_init_verbs,
3019                                 alc880_uniwill_p53_init_verbs,
3020                                 alc880_beep_init_verbs },
3021                 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3022                 .dac_nids = alc880_dac_nids,
3023                 .dig_out_nid = ALC880_DIGOUT_NID,
3024                 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3025                 .channel_mode = alc880_2_jack_modes,
3026                 .input_mux = &alc880_capture_source,
3027                 .unsol_event = alc880_uniwill_p53_unsol_event,
3028                 .init_hook = alc880_uniwill_p53_hp_automute,
3029         },
3030         [ALC880_CLEVO] = {
3031                 .mixers = { alc880_three_stack_mixer },
3032                 .init_verbs = { alc880_volume_init_verbs,
3033                                 alc880_pin_clevo_init_verbs },
3034                 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3035                 .dac_nids = alc880_dac_nids,
3036                 .hp_nid = 0x03,
3037                 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3038                 .channel_mode = alc880_threestack_modes,
3039                 .need_dac_fix = 1,
3040                 .input_mux = &alc880_capture_source,
3041         },
3042         [ALC880_LG] = {
3043                 .mixers = { alc880_lg_mixer },
3044                 .init_verbs = { alc880_volume_init_verbs,
3045                                 alc880_lg_init_verbs },
3046                 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
3047                 .dac_nids = alc880_lg_dac_nids,
3048                 .dig_out_nid = ALC880_DIGOUT_NID,
3049                 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
3050                 .channel_mode = alc880_lg_ch_modes,
3051                 .need_dac_fix = 1,
3052                 .input_mux = &alc880_lg_capture_source,
3053                 .unsol_event = alc880_lg_unsol_event,
3054                 .init_hook = alc880_lg_automute,
3055 #ifdef CONFIG_SND_HDA_POWER_SAVE
3056                 .loopbacks = alc880_lg_loopbacks,
3057 #endif
3058         },
3059         [ALC880_LG_LW] = {
3060                 .mixers = { alc880_lg_lw_mixer },
3061                 .init_verbs = { alc880_volume_init_verbs,
3062                                 alc880_lg_lw_init_verbs },
3063                 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3064                 .dac_nids = alc880_dac_nids,
3065                 .dig_out_nid = ALC880_DIGOUT_NID,
3066                 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
3067                 .channel_mode = alc880_lg_lw_modes,
3068                 .input_mux = &alc880_lg_lw_capture_source,
3069                 .unsol_event = alc880_lg_lw_unsol_event,
3070                 .init_hook = alc880_lg_lw_automute,
3071         },
3072 #ifdef CONFIG_SND_DEBUG
3073         [ALC880_TEST] = {
3074                 .mixers = { alc880_test_mixer },
3075                 .init_verbs = { alc880_test_init_verbs },
3076                 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
3077                 .dac_nids = alc880_test_dac_nids,
3078                 .dig_out_nid = ALC880_DIGOUT_NID,
3079                 .num_channel_mode = ARRAY_SIZE(alc880_test_modes),
3080                 .channel_mode = alc880_test_modes,
3081                 .input_mux = &alc880_test_capture_source,
3082         },
3083 #endif
3084 };
3085
3086 /*
3087  * Automatic parse of I/O pins from the BIOS configuration
3088  */
3089
3090 #define NUM_CONTROL_ALLOC       32
3091 #define NUM_VERB_ALLOC          32
3092
3093 enum {
3094         ALC_CTL_WIDGET_VOL,
3095         ALC_CTL_WIDGET_MUTE,
3096         ALC_CTL_BIND_MUTE,
3097 };
3098 static struct snd_kcontrol_new alc880_control_templates[] = {
3099         HDA_CODEC_VOLUME(NULL, 0, 0, 0),
3100         HDA_CODEC_MUTE(NULL, 0, 0, 0),
3101         HDA_BIND_MUTE(NULL, 0, 0, 0),
3102 };
3103
3104 /* add dynamic controls */
3105 static int add_control(struct alc_spec *spec, int type, const char *name,
3106                        unsigned long val)
3107 {
3108         struct snd_kcontrol_new *knew;
3109
3110         if (spec->num_kctl_used >= spec->num_kctl_alloc) {
3111                 int num = spec->num_kctl_alloc + NUM_CONTROL_ALLOC;
3112
3113                 /* array + terminator */
3114                 knew = kcalloc(num + 1, sizeof(*knew), GFP_KERNEL);
3115                 if (!knew)
3116                         return -ENOMEM;
3117                 if (spec->kctl_alloc) {
3118                         memcpy(knew, spec->kctl_alloc,
3119                                sizeof(*knew) * spec->num_kctl_alloc);
3120                         kfree(spec->kctl_alloc);
3121                 }
3122                 spec->kctl_alloc = knew;
3123                 spec->num_kctl_alloc = num;
3124         }
3125
3126         knew = &spec->kctl_alloc[spec->num_kctl_used];
3127         *knew = alc880_control_templates[type];
3128         knew->name = kstrdup(name, GFP_KERNEL);
3129         if (!knew->name)
3130                 return -ENOMEM;
3131         knew->private_value = val;
3132         spec->num_kctl_used++;
3133         return 0;
3134 }
3135
3136 #define alc880_is_fixed_pin(nid)        ((nid) >= 0x14 && (nid) <= 0x17)
3137 #define alc880_fixed_pin_idx(nid)       ((nid) - 0x14)
3138 #define alc880_is_multi_pin(nid)        ((nid) >= 0x18)
3139 #define alc880_multi_pin_idx(nid)       ((nid) - 0x18)
3140 #define alc880_is_input_pin(nid)        ((nid) >= 0x18)
3141 #define alc880_input_pin_idx(nid)       ((nid) - 0x18)
3142 #define alc880_idx_to_dac(nid)          ((nid) + 0x02)
3143 #define alc880_dac_to_idx(nid)          ((nid) - 0x02)
3144 #define alc880_idx_to_mixer(nid)        ((nid) + 0x0c)
3145 #define alc880_idx_to_selector(nid)     ((nid) + 0x10)
3146 #define ALC880_PIN_CD_NID               0x1c
3147
3148 /* fill in the dac_nids table from the parsed pin configuration */
3149 static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
3150                                      const struct auto_pin_cfg *cfg)
3151 {
3152         hda_nid_t nid;
3153         int assigned[4];
3154         int i, j;
3155
3156         memset(assigned, 0, sizeof(assigned));
3157         spec->multiout.dac_nids = spec->private_dac_nids;
3158
3159         /* check the pins hardwired to audio widget */
3160         for (i = 0; i < cfg->line_outs; i++) {
3161                 nid = cfg->line_out_pins[i];
3162                 if (alc880_is_fixed_pin(nid)) {
3163                         int idx = alc880_fixed_pin_idx(nid);
3164                         spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx);
3165                         assigned[idx] = 1;
3166                 }
3167         }
3168         /* left pins can be connect to any audio widget */
3169         for (i = 0; i < cfg->line_outs; i++) {
3170                 nid = cfg->line_out_pins[i];
3171                 if (alc880_is_fixed_pin(nid))
3172                         continue;
3173                 /* search for an empty channel */
3174                 for (j = 0; j < cfg->line_outs; j++) {
3175                         if (!assigned[j]) {
3176                                 spec->multiout.dac_nids[i] =
3177                                         alc880_idx_to_dac(j);
3178                                 assigned[j] = 1;
3179                                 break;
3180                         }
3181                 }
3182         }
3183         spec->multiout.num_dacs = cfg->line_outs;
3184         return 0;
3185 }
3186
3187 /* add playback controls from the parsed DAC table */
3188 static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
3189                                              const struct auto_pin_cfg *cfg)
3190 {
3191         char name[32];
3192         static const char *chname[4] = {
3193                 "Front", "Surround", NULL /*CLFE*/, "Side"
3194         };
3195         hda_nid_t nid;
3196         int i, err;
3197
3198         for (i = 0; i < cfg->line_outs; i++) {
3199                 if (!spec->multiout.dac_nids[i])
3200                         continue;
3201                 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
3202                 if (i == 2) {
3203                         /* Center/LFE */
3204                         err = add_control(spec, ALC_CTL_WIDGET_VOL,
3205                                           "Center Playback Volume",
3206                                           HDA_COMPOSE_AMP_VAL(nid, 1, 0,
3207                                                               HDA_OUTPUT));
3208                         if (err < 0)
3209                                 return err;
3210                         err = add_control(spec, ALC_CTL_WIDGET_VOL,
3211                                           "LFE Playback Volume",
3212                                           HDA_COMPOSE_AMP_VAL(nid, 2, 0,
3213                                                               HDA_OUTPUT));
3214                         if (err < 0)
3215                                 return err;
3216                         err = add_control(spec, ALC_CTL_BIND_MUTE,
3217                                           "Center Playback Switch",
3218                                           HDA_COMPOSE_AMP_VAL(nid, 1, 2,
3219                                                               HDA_INPUT));
3220                         if (err < 0)
3221                                 return err;
3222                         err = add_control(spec, ALC_CTL_BIND_MUTE,
3223                                           "LFE Playback Switch",
3224                                           HDA_COMPOSE_AMP_VAL(nid, 2, 2,
3225                                                               HDA_INPUT));
3226                         if (err < 0)
3227                                 return err;
3228                 } else {
3229                         sprintf(name, "%s Playback Volume", chname[i]);
3230                         err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3231                                           HDA_COMPOSE_AMP_VAL(nid, 3, 0,
3232                                                               HDA_OUTPUT));
3233                         if (err < 0)
3234                                 return err;
3235                         sprintf(name, "%s Playback Switch", chname[i]);
3236                         err = add_control(spec, ALC_CTL_BIND_MUTE, name,
3237                                           HDA_COMPOSE_AMP_VAL(nid, 3, 2,
3238                                                               HDA_INPUT));
3239                         if (err < 0)
3240                                 return err;
3241                 }
3242         }
3243         return 0;
3244 }
3245
3246 /* add playback controls for speaker and HP outputs */
3247 static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
3248                                         const char *pfx)
3249 {
3250         hda_nid_t nid;
3251         int err;
3252         char name[32];
3253
3254         if (!pin)
3255                 return 0;
3256
3257         if (alc880_is_fixed_pin(pin)) {
3258                 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
3259                 /* specify the DAC as the extra output */
3260                 if (!spec->multiout.hp_nid)
3261                         spec->multiout.hp_nid = nid;
3262                 else
3263                         spec->multiout.extra_out_nid[0] = nid;
3264                 /* control HP volume/switch on the output mixer amp */
3265                 nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
3266                 sprintf(name, "%s Playback Volume", pfx);
3267                 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3268                                   HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
3269                 if (err < 0)
3270                         return err;
3271                 sprintf(name, "%s Playback Switch", pfx);
3272                 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
3273                                   HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
3274                 if (err < 0)
3275                         return err;
3276         } else if (alc880_is_multi_pin(pin)) {
3277                 /* set manual connection */
3278                 /* we have only a switch on HP-out PIN */
3279                 sprintf(name, "%s Playback Switch", pfx);
3280                 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
3281                                   HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
3282                 if (err < 0)
3283                         return err;
3284         }
3285         return 0;
3286 }
3287
3288 /* create input playback/capture controls for the given pin */
3289 static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
3290                             const char *ctlname,
3291                             int idx, hda_nid_t mix_nid)
3292 {
3293         char name[32];
3294         int err;
3295
3296         sprintf(name, "%s Playback Volume", ctlname);
3297         err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
3298                           HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
3299         if (err < 0)
3300                 return err;
3301         sprintf(name, "%s Playback Switch", ctlname);
3302         err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
3303                           HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
3304         if (err < 0)
3305                 return err;
3306         return 0;
3307 }
3308
3309 /* create playback/capture controls for input pins */
3310 static int alc880_auto_create_analog_input_ctls(struct alc_spec *spec,
3311                                                 const struct auto_pin_cfg *cfg)
3312 {
3313         struct hda_input_mux *imux = &spec->private_imux;
3314         int i, err, idx;
3315
3316         for (i = 0; i < AUTO_PIN_LAST; i++) {
3317                 if (alc880_is_input_pin(cfg->input_pins[i])) {
3318                         idx = alc880_input_pin_idx(cfg->input_pins[i]);
3319                         err = new_analog_input(spec, cfg->input_pins[i],
3320                                                auto_pin_cfg_labels[i],
3321                                                idx, 0x0b);
3322                         if (err < 0)
3323                                 return err;
3324                         imux->items[imux->num_items].label =
3325                                 auto_pin_cfg_labels[i];
3326                         imux->items[imux->num_items].index =
3327                                 alc880_input_pin_idx(cfg->input_pins[i]);
3328                         imux->num_items++;
3329                 }
3330         }
3331         return 0;
3332 }
3333
3334 static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
3335                                               hda_nid_t nid, int pin_type,
3336                                               int dac_idx)
3337 {
3338         /* set as output */
3339         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3340                             pin_type);
3341         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
3342                             AMP_OUT_UNMUTE);
3343         /* need the manual connection? */
3344         if (alc880_is_multi_pin(nid)) {
3345                 struct alc_spec *spec = codec->spec;
3346                 int idx = alc880_multi_pin_idx(nid);
3347                 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
3348                                     AC_VERB_SET_CONNECT_SEL,
3349                                     alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
3350         }
3351 }
3352
3353 static int get_pin_type(int line_out_type)
3354 {
3355         if (line_out_type == AUTO_PIN_HP_OUT)
3356                 return PIN_HP;
3357         else
3358                 return PIN_OUT;
3359 }
3360
3361 static void alc880_auto_init_multi_out(struct hda_codec *codec)
3362 {
3363         struct alc_spec *spec = codec->spec;
3364         int i;
3365         
3366         alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
3367         for (i = 0; i < spec->autocfg.line_outs; i++) {
3368                 hda_nid_t nid = spec->autocfg.line_out_pins[i];
3369                 int pin_type = get_pin_type(spec->autocfg.line_out_type);
3370                 alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
3371         }
3372 }
3373
3374 static void alc880_auto_init_extra_out(struct hda_codec *codec)
3375 {
3376         struct alc_spec *spec = codec->spec;
3377         hda_nid_t pin;
3378
3379         pin = spec->autocfg.speaker_pins[0];
3380         if (pin) /* connect to front */
3381                 alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
3382         pin = spec->autocfg.hp_pins[0];
3383         if (pin) /* connect to front */
3384                 alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
3385 }
3386
3387 static void alc880_auto_init_analog_input(struct hda_codec *codec)
3388 {
3389         struct alc_spec *spec = codec->spec;
3390         int i;
3391
3392         for (i = 0; i < AUTO_PIN_LAST; i++) {
3393                 hda_nid_t nid = spec->autocfg.input_pins[i];
3394                 if (alc880_is_input_pin(nid)) {
3395                         snd_hda_codec_write(codec, nid, 0,
3396                                             AC_VERB_SET_PIN_WIDGET_CONTROL,
3397                                             i <= AUTO_PIN_FRONT_MIC ?
3398                                             PIN_VREF80 : PIN_IN);
3399                         if (nid != ALC880_PIN_CD_NID)
3400                                 snd_hda_codec_write(codec, nid, 0,
3401                                                     AC_VERB_SET_AMP_GAIN_MUTE,
3402                                                     AMP_OUT_MUTE);
3403                 }
3404         }
3405 }
3406
3407 /* parse the BIOS configuration and set up the alc_spec */
3408 /* return 1 if successful, 0 if the proper config is not found,
3409  * or a negative error code
3410  */
3411 static int alc880_parse_auto_config(struct hda_codec *codec)
3412 {
3413         struct alc_spec *spec = codec->spec;
3414         int err;
3415         static hda_nid_t alc880_ignore[] = { 0x1d, 0 };
3416
3417         err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
3418                                            alc880_ignore);
3419         if (err < 0)
3420                 return err;
3421         if (!spec->autocfg.line_outs)
3422                 return 0; /* can't find valid BIOS pin config */
3423
3424         err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
3425         if (err < 0)
3426                 return err;
3427         err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
3428         if (err < 0)
3429                 return err;
3430         err = alc880_auto_create_extra_out(spec,
3431                                            spec->autocfg.speaker_pins[0],
3432                                            "Speaker");
3433         if (err < 0)
3434                 return err;
3435         err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
3436                                            "Headphone");
3437         if (err < 0)
3438                 return err;
3439         err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
3440         if (err < 0)
3441                 return err;
3442
3443         spec->multiout.max_channels = spec->multiout.num_dacs * 2;
3444
3445         if (spec->autocfg.dig_out_pin)
3446                 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
3447         if (spec->autocfg.dig_in_pin)
3448                 spec->dig_in_nid = ALC880_DIGIN_NID;
3449
3450         if (spec->kctl_alloc)
3451                 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
3452
3453         spec->init_verbs[spec->num_init_verbs++] = alc880_volume_init_verbs;
3454
3455         spec->num_mux_defs = 1;
3456         spec->input_mux = &spec->private_imux;
3457
3458         return 1;
3459 }
3460
3461 /* additional initialization for auto-configuration model */
3462 static void alc880_auto_init(struct hda_codec *codec)
3463 {
3464         alc880_auto_init_multi_out(codec);
3465         alc880_auto_init_extra_out(codec);
3466         alc880_auto_init_analog_input(codec);
3467 }
3468
3469 /*
3470  * OK, here we have finally the patch for ALC880
3471  */
3472
3473 static int patch_alc880(struct hda_codec *codec)
3474 {
3475         struct alc_spec *spec;
3476         int board_config;
3477         int err;
3478
3479         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
3480         if (spec == NULL)
3481                 return -ENOMEM;
3482
3483         codec->spec = spec;
3484
3485         board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
3486                                                   alc880_models,
3487                                                   alc880_cfg_tbl);
3488         if (board_config < 0) {
3489                 printk(KERN_INFO "hda_codec: Unknown model for ALC880, "
3490                        "trying auto-probe from BIOS...\n");
3491                 board_config = ALC880_AUTO;
3492         }
3493
3494         if (board_config == ALC880_AUTO) {
3495                 /* automatic parse from the BIOS config */
3496                 err = alc880_parse_auto_config(codec);
3497                 if (err < 0) {
3498                         alc_free(codec);
3499                         return err;
3500                 } else if (!err) {
3501                         printk(KERN_INFO
3502                                "hda_codec: Cannot set up configuration "
3503                                "from BIOS.  Using 3-stack mode...\n");
3504                         board_config = ALC880_3ST;
3505                 }
3506         }
3507
3508         if (board_config != ALC880_AUTO)
3509                 setup_preset(spec, &alc880_presets[board_config]);
3510
3511         spec->stream_name_analog = "ALC880 Analog";
3512         spec->stream_analog_playback = &alc880_pcm_analog_playback;
3513         spec->stream_analog_capture = &alc880_pcm_analog_capture;
3514
3515         spec->stream_name_digital = "ALC880 Digital";
3516         spec->stream_digital_playback = &alc880_pcm_digital_playback;
3517         spec->stream_digital_capture = &alc880_pcm_digital_capture;
3518
3519         if (!spec->adc_nids && spec->input_mux) {
3520                 /* check whether NID 0x07 is valid */
3521                 unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
3522                 /* get type */
3523                 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
3524                 if (wcap != AC_WID_AUD_IN) {
3525                         spec->adc_nids = alc880_adc_nids_alt;
3526                         spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
3527                         spec->mixers[spec->num_mixers] =
3528                                 alc880_capture_alt_mixer;
3529                         spec->num_mixers++;
3530                 } else {
3531                         spec->adc_nids = alc880_adc_nids;
3532                         spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
3533                         spec->mixers[spec->num_mixers] = alc880_capture_mixer;
3534                         spec->num_mixers++;
3535                 }
3536         }
3537
3538         codec->patch_ops = alc_patch_ops;
3539         if (board_config == ALC880_AUTO)
3540                 spec->init_hook = alc880_auto_init;
3541 #ifdef CONFIG_SND_HDA_POWER_SAVE
3542         if (!spec->loopback.amplist)
3543                 spec->loopback.amplist = alc880_loopbacks;
3544 #endif
3545
3546         return 0;
3547 }
3548
3549
3550 /*
3551  * ALC260 support
3552  */
3553
3554 static hda_nid_t alc260_dac_nids[1] = {
3555         /* front */
3556         0x02,
3557 };
3558
3559 static hda_nid_t alc260_adc_nids[1] = {
3560         /* ADC0 */
3561         0x04,
3562 };
3563
3564 static hda_nid_t alc260_adc_nids_alt[1] = {
3565         /* ADC1 */
3566         0x05,
3567 };
3568
3569 static hda_nid_t alc260_hp_adc_nids[2] = {
3570         /* ADC1, 0 */
3571         0x05, 0x04
3572 };
3573
3574 /* NIDs used when simultaneous access to both ADCs makes sense.  Note that
3575  * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
3576  */
3577 static hda_nid_t alc260_dual_adc_nids[2] = {
3578         /* ADC0, ADC1 */
3579         0x04, 0x05
3580 };
3581
3582 #define ALC260_DIGOUT_NID       0x03
3583 #define ALC260_DIGIN_NID        0x06
3584
3585 static struct hda_input_mux alc260_capture_source = {
3586         .num_items = 4,
3587         .items = {
3588                 { "Mic", 0x0 },
3589                 { "Front Mic", 0x1 },
3590                 { "Line", 0x2 },
3591                 { "CD", 0x4 },
3592         },
3593 };
3594
3595 /* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
3596  * headphone jack and the internal CD lines since these are the only pins at
3597  * which audio can appear.  For flexibility, also allow the option of
3598  * recording the mixer output on the second ADC (ADC0 doesn't have a
3599  * connection to the mixer output).
3600  */
3601 static struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
3602         {
3603                 .num_items = 3,
3604                 .items = {
3605                         { "Mic/Line", 0x0 },
3606                         { "CD", 0x4 },
3607                         { "Headphone", 0x2 },
3608                 },
3609         },
3610         {
3611                 .num_items = 4,
3612                 .items = {
3613                         { "Mic/Line", 0x0 },
3614                         { "CD", 0x4 },
3615                         { "Headphone", 0x2 },
3616                         { "Mixer", 0x5 },
3617                 },
3618         },
3619
3620 };
3621
3622 /* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
3623  * the Fujitsu S702x, but jacks are marked differently.
3624  */
3625 static struct hda_input_mux alc260_acer_capture_sources[2] = {
3626         {
3627                 .num_items = 4,
3628                 .items = {
3629                         { "Mic", 0x0 },
3630                         { "Line", 0x2 },
3631                         { "CD", 0x4 },
3632                         { "Headphone", 0x5 },
3633                 },
3634         },
3635         {
3636                 .num_items = 5,
3637                 .items = {
3638                         { "Mic", 0x0 },
3639                         { "Line", 0x2 },
3640                         { "CD", 0x4 },
3641                         { "Headphone", 0x6 },
3642                         { "Mixer", 0x5 },
3643                 },
3644         },
3645 };
3646 /*
3647  * This is just place-holder, so there's something for alc_build_pcms to look
3648  * at when it calculates the maximum number of channels. ALC260 has no mixer
3649  * element which allows changing the channel mode, so the verb list is
3650  * never used.
3651  */
3652 static struct hda_channel_mode alc260_modes[1] = {
3653         { 2, NULL },
3654 };
3655
3656
3657 /* Mixer combinations
3658  *
3659  * basic: base_output + input + pc_beep + capture
3660  * HP: base_output + input + capture_alt
3661  * HP_3013: hp_3013 + input + capture
3662  * fujitsu: fujitsu + capture
3663  * acer: acer + capture
3664  */
3665
3666 static struct snd_kcontrol_new alc260_base_output_mixer[] = {
3667         HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3668         HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
3669         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
3670         HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
3671         HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
3672         HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
3673         { } /* end */
3674 };
3675
3676 static struct snd_kcontrol_new alc260_input_mixer[] = {
3677         HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
3678         HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
3679         HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
3680         HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
3681         HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
3682         HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
3683         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
3684         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
3685         { } /* end */
3686 };
3687
3688 static struct snd_kcontrol_new alc260_pc_beep_mixer[] = {
3689         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x07, 0x05, HDA_INPUT),
3690         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x07, 0x05, HDA_INPUT),
3691         { } /* end */
3692 };
3693
3694 static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
3695         HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
3696         HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
3697         HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
3698         HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
3699         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3700         HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
3701         HDA_CODEC_VOLUME_MONO("iSpeaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
3702         HDA_CODEC_MUTE_MONO("iSpeaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
3703         { } /* end */
3704 };
3705
3706 /* Fujitsu S702x series laptops.  ALC260 pin usage: Mic/Line jack = 0x12, 
3707  * HP jack = 0x14, CD audio =  0x16, internal speaker = 0x10.
3708  */
3709 static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
3710         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3711         HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
3712         ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
3713         HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
3714         HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
3715         HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
3716         HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
3717         ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
3718         HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
3719         HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
3720         HDA_CODEC_VOLUME("Internal Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
3721         HDA_BIND_MUTE("Internal Speaker Playback Switch", 0x09, 2, HDA_INPUT),
3722         { } /* end */
3723 };
3724
3725 /* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks.  Note that current
3726  * versions of the ALC260 don't act on requests to enable mic bias from NID
3727  * 0x0f (used to drive the headphone jack in these laptops).  The ALC260
3728  * datasheet doesn't mention this restriction.  At this stage it's not clear
3729  * whether this behaviour is intentional or is a hardware bug in chip
3730  * revisions available in early 2006.  Therefore for now allow the
3731  * "Headphone Jack Mode" control to span all choices, but if it turns out
3732  * that the lack of mic bias for this NID is intentional we could change the
3733  * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
3734  *
3735  * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
3736  * don't appear to make the mic bias available from the "line" jack, even
3737  * though the NID used for this jack (0x14) can supply it.  The theory is
3738  * that perhaps Acer have included blocking capacitors between the ALC260
3739  * and the output jack.  If this turns out to be the case for all such
3740  * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
3741  * to ALC_PIN_DIR_INOUT_NOMICBIAS.
3742  *
3743  * The C20x Tablet series have a mono internal speaker which is controlled
3744  * via the chip's Mono sum widget and pin complex, so include the necessary
3745  * controls for such models.  On models without a "mono speaker" the control
3746  * won't do anything.
3747  */
3748 static struct snd_kcontrol_new alc260_acer_mixer[] = {
3749         HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3750         HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
3751         ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
3752         HDA_CODEC_VOLUME_MONO("Mono Speaker Playback Volume", 0x0a, 1, 0x0,
3753                               HDA_OUTPUT),
3754         HDA_BIND_MUTE_MONO("Mono Speaker Playback Switch", 0x0a, 1, 2,
3755                            HDA_INPUT),
3756         HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
3757         HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
3758         HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
3759         HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
3760         ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
3761         HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
3762         HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
3763         ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
3764         HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
3765         HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
3766         { } /* end */
3767 };
3768
3769 /* Packard bell V7900  ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
3770  * Line In jack = 0x14, CD audio =  0x16, pc beep = 0x17.
3771  */
3772 static struct snd_kcontrol_new alc260_will_mixer[] = {
3773         HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3774         HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
3775         HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
3776         HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
3777         ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
3778         HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
3779         HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
3780         ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
3781         HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
3782         HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
3783         HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
3784         HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
3785         { } /* end */
3786 };
3787
3788 /* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
3789  * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
3790  */
3791 static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
3792         HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3793         HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
3794         HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
3795         HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
3796         ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
3797         HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
3798         HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
3799         HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
3800         HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
3801         ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
3802         { } /* end */
3803 };
3804
3805 /* capture mixer elements */
3806 static struct snd_kcontrol_new alc260_capture_mixer[] = {
3807         HDA_CODEC_VOLUME("Capture Volume", 0x04, 0x0, HDA_INPUT),
3808         HDA_CODEC_MUTE("Capture Switch", 0x04, 0x0, HDA_INPUT),
3809         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x05, 0x0, HDA_INPUT),
3810         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x05, 0x0, HDA_INPUT),
3811         {
3812                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3813                 /* The multiple "Capture Source" controls confuse alsamixer
3814                  * So call somewhat different..
3815                  * FIXME: the controls appear in the "playback" view!
3816                  */
3817                 /* .name = "Capture Source", */
3818                 .name = "Input Source",
3819                 .count = 2,
3820                 .info = alc_mux_enum_info,
3821                 .get = alc_mux_enum_get,
3822                 .put = alc_mux_enum_put,
3823         },
3824         { } /* end */
3825 };
3826
3827 static struct snd_kcontrol_new alc260_capture_alt_mixer[] = {
3828         HDA_CODEC_VOLUME("Capture Volume", 0x05, 0x0, HDA_INPUT),
3829         HDA_CODEC_MUTE("Capture Switch", 0x05, 0x0, HDA_INPUT),
3830         {
3831                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3832                 /* The multiple "Capture Source" controls confuse alsamixer
3833                  * So call somewhat different..
3834                  * FIXME: the controls appear in the "playback" view!
3835                  */
3836                 /* .name = "Capture Source", */
3837                 .name = "Input Source",
3838                 .count = 1,
3839                 .info = alc_mux_enum_info,
3840                 .get = alc_mux_enum_get,
3841                 .put = alc_mux_enum_put,
3842         },
3843         { } /* end */
3844 };
3845
3846 /*
3847  * initialization verbs
3848  */
3849 static struct hda_verb alc260_init_verbs[] = {
3850         /* Line In pin widget for input */
3851         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3852         /* CD pin widget for input */
3853         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3854         /* Mic1 (rear panel) pin widget for input and vref at 80% */
3855         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3856         /* Mic2 (front panel) pin widget for input and vref at 80% */
3857         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3858         /* LINE-2 is used for line-out in rear */
3859         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3860         /* select line-out */
3861         {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
3862         /* LINE-OUT pin */
3863         {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3864         /* enable HP */
3865         {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3866         /* enable Mono */
3867         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3868         /* mute capture amp left and right */
3869         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3870         /* set connection select to line in (default select for this ADC) */
3871         {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
3872         /* mute capture amp left and right */
3873         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3874         /* set connection select to line in (default select for this ADC) */
3875         {0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
3876         /* set vol=0 Line-Out mixer amp left and right */
3877         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3878         /* unmute pin widget amp left and right (no gain on this amp) */
3879         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3880         /* set vol=0 HP mixer amp left and right */
3881         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3882         /* unmute pin widget amp left and right (no gain on this amp) */
3883         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3884         /* set vol=0 Mono mixer amp left and right */
3885         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3886         /* unmute pin widget amp left and right (no gain on this amp) */
3887         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3888         /* unmute LINE-2 out pin */
3889         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3890         /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
3891          * Line In 2 = 0x03
3892          */
3893         /* mute analog inputs */
3894         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3895         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3896         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3897         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3898         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3899         /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
3900         /* mute Front out path */
3901         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3902         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3903         /* mute Headphone out path */
3904         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3905         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3906         /* mute Mono out path */
3907         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3908         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3909         { }
3910 };
3911
3912 #if 0 /* should be identical with alc260_init_verbs? */
3913 static struct hda_verb alc260_hp_init_verbs[] = {
3914         /* Headphone and output */
3915         {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
3916         /* mono output */
3917         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3918         /* Mic1 (rear panel) pin widget for input and vref at 80% */
3919         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
3920         /* Mic2 (front panel) pin widget for input and vref at 80% */
3921         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
3922         /* Line In pin widget for input */
3923         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
3924         /* Line-2 pin widget for output */
3925         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3926         /* CD pin widget for input */
3927         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
3928         /* unmute amp left and right */
3929         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
3930         /* set connection select to line in (default select for this ADC) */
3931         {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
3932         /* unmute Line-Out mixer amp left and right (volume = 0) */
3933         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
3934         /* mute pin widget amp left and right (no gain on this amp) */
3935         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
3936         /* unmute HP mixer amp left and right (volume = 0) */
3937         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
3938         /* mute pin widget amp left and right (no gain on this amp) */
3939         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
3940         /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
3941          * Line In 2 = 0x03
3942          */
3943         /* mute analog inputs */
3944         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3945         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3946         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3947         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3948         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3949         /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
3950         /* Unmute Front out path */
3951         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3952         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3953         /* Unmute Headphone out path */
3954         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3955         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3956         /* Unmute Mono out path */
3957         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3958         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3959         { }
3960 };
3961 #endif
3962
3963 static struct hda_verb alc260_hp_3013_init_verbs[] = {
3964         /* Line out and output */
3965         {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3966         /* mono output */
3967         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3968         /* Mic1 (rear panel) pin widget for input and vref at 80% */
3969         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
3970         /* Mic2 (front panel) pin widget for input and vref at 80% */
3971         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
3972         /* Line In pin widget for input */
3973         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
3974         /* Headphone pin widget for output */
3975         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
3976         /* CD pin widget for input */
3977         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
3978         /* unmute amp left and right */
3979         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
3980         /* set connection select to line in (default select for this ADC) */
3981         {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
3982         /* unmute Line-Out mixer amp left and right (volume = 0) */
3983         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
3984         /* mute pin widget amp left and right (no gain on this amp) */
3985         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
3986         /* unmute HP mixer amp left and right (volume = 0) */
3987         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
3988         /* mute pin widget amp left and right (no gain on this amp) */
3989         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
3990         /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
3991          * Line In 2 = 0x03
3992          */
3993         /* mute analog inputs */
3994         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3995         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3996         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3997         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3998         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3999         /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
4000         /* Unmute Front out path */
4001         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4002         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4003         /* Unmute Headphone out path */
4004         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4005         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4006         /* Unmute Mono out path */
4007         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
4008         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
4009         { }
4010 };
4011
4012 /* Initialisation sequence for ALC260 as configured in Fujitsu S702x
4013  * laptops.  ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
4014  * audio = 0x16, internal speaker = 0x10.
4015  */
4016 static struct hda_verb alc260_fujitsu_init_verbs[] = {
4017         /* Disable all GPIOs */
4018         {0x01, AC_VERB_SET_GPIO_MASK, 0},
4019         /* Internal speaker is connected to headphone pin */
4020         {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4021         /* Headphone/Line-out jack connects to Line1 pin; make it an output */
4022         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4023         /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
4024         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4025         /* Ensure all other unused pins are disabled and muted. */
4026         {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4027         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4028         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4029         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4030         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4031         {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4032         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4033         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4034
4035         /* Disable digital (SPDIF) pins */
4036         {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
4037         {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
4038
4039         /* Ensure Line1 pin widget takes its input from the OUT1 sum bus 
4040          * when acting as an output.
4041          */
4042         {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4043
4044         /* Start with output sum widgets muted and their output gains at min */
4045         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4046         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4047         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4048         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4049         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4050         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4051         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4052         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4053         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4054
4055         /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
4056         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4057         /* Unmute Line1 pin widget output buffer since it starts as an output.
4058          * If the pin mode is changed by the user the pin mode control will
4059          * take care of enabling the pin's input/output buffers as needed.
4060          * Therefore there's no need to enable the input buffer at this
4061          * stage.
4062          */
4063         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4064         /* Unmute input buffer of pin widget used for Line-in (no equiv 
4065          * mixer ctrl)
4066          */
4067         {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4068
4069         /* Mute capture amp left and right */
4070         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4071         /* Set ADC connection select to match default mixer setting - line 
4072          * in (on mic1 pin)
4073          */
4074         {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4075
4076         /* Do the same for the second ADC: mute capture input amp and
4077          * set ADC connection to line in (on mic1 pin)
4078          */
4079         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4080         {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4081
4082         /* Mute all inputs to mixer widget (even unconnected ones) */
4083         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
4084         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
4085         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
4086         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
4087         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
4088         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4089         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4090         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4091
4092         { }
4093 };
4094
4095 /* Initialisation sequence for ALC260 as configured in Acer TravelMate and
4096  * similar laptops (adapted from Fujitsu init verbs).
4097  */
4098 static struct hda_verb alc260_acer_init_verbs[] = {
4099         /* On TravelMate laptops, GPIO 0 enables the internal speaker and
4100          * the headphone jack.  Turn this on and rely on the standard mute
4101          * methods whenever the user wants to turn these outputs off.
4102          */
4103         {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
4104         {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
4105         {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
4106         /* Internal speaker/Headphone jack is connected to Line-out pin */
4107         {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4108         /* Internal microphone/Mic jack is connected to Mic1 pin */
4109         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
4110         /* Line In jack is connected to Line1 pin */
4111         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4112         /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
4113         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4114         /* Ensure all other unused pins are disabled and muted. */
4115         {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4116         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4117         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4118         {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4119         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
4120         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4121         /* Disable digital (SPDIF) pins */
4122         {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
4123         {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
4124
4125         /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum 
4126          * bus when acting as outputs.
4127          */
4128         {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
4129         {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4130
4131         /* Start with output sum widgets muted and their output gains at min */
4132         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4133         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4134         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4135         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4136         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4137         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4138         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4139         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4140         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4141
4142         /* Unmute Line-out pin widget amp left and right
4143          * (no equiv mixer ctrl)
4144          */
4145         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4146         /* Unmute mono pin widget amp output (no equiv mixer ctrl) */
4147         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4148         /* Unmute Mic1 and Line1 pin widget input buffers since they start as
4149          * inputs. If the pin mode is changed by the user the pin mode control
4150          * will take care of enabling the pin's input/output buffers as needed.
4151          * Therefore there's no need to enable the input buffer at this
4152          * stage.
4153          */
4154         {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4155         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4156
4157         /* Mute capture amp left and right */
4158         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4159         /* Set ADC connection select to match default mixer setting - mic
4160          * (on mic1 pin)
4161          */
4162         {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4163
4164         /* Do similar with the second ADC: mute capture input amp and
4165          * set ADC connection to mic to match ALSA's default state.
4166          */
4167         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4168         {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4169
4170         /* Mute all inputs to mixer widget (even unconnected ones) */
4171         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
4172         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
4173         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
4174         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
4175         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
4176         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4177         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4178         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4179
4180         { }
4181 };
4182
4183 static struct hda_verb alc260_will_verbs[] = {
4184         {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4185         {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
4186         {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
4187         {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
4188         {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
4189         {0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
4190         {}
4191 };
4192
4193 static struct hda_verb alc260_replacer_672v_verbs[] = {
4194         {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
4195         {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
4196         {0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
4197
4198         {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
4199         {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
4200         {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
4201
4202         {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4203         {}
4204 };
4205
4206 /* toggle speaker-output according to the hp-jack state */
4207 static void alc260_replacer_672v_automute(struct hda_codec *codec)
4208 {
4209         unsigned int present;
4210
4211         /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
4212         present = snd_hda_codec_read(codec, 0x0f, 0,
4213                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
4214         if (present) {
4215                 snd_hda_codec_write_cache(codec, 0x01, 0,
4216                                           AC_VERB_SET_GPIO_DATA, 1);
4217                 snd_hda_codec_write_cache(codec, 0x0f, 0,
4218                                           AC_VERB_SET_PIN_WIDGET_CONTROL,
4219                                           PIN_HP);
4220         } else {
4221                 snd_hda_codec_write_cache(codec, 0x01, 0,
4222                                           AC_VERB_SET_GPIO_DATA, 0);
4223                 snd_hda_codec_write_cache(codec, 0x0f, 0,
4224                                           AC_VERB_SET_PIN_WIDGET_CONTROL,
4225                                           PIN_OUT);
4226         }
4227 }
4228
4229 static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
4230                                        unsigned int res)
4231 {
4232         if ((res >> 26) == ALC880_HP_EVENT)
4233                 alc260_replacer_672v_automute(codec);
4234 }
4235
4236 /* Test configuration for debugging, modelled after the ALC880 test
4237  * configuration.
4238  */
4239 #ifdef CONFIG_SND_DEBUG
4240 static hda_nid_t alc260_test_dac_nids[1] = {
4241         0x02,
4242 };
4243 static hda_nid_t alc260_test_adc_nids[2] = {
4244         0x04, 0x05,
4245 };
4246 /* For testing the ALC260, each input MUX needs its own definition since
4247  * the signal assignments are different.  This assumes that the first ADC 
4248  * is NID 0x04.
4249  */
4250 static struct hda_input_mux alc260_test_capture_sources[2] = {
4251         {
4252                 .num_items = 7,
4253                 .items = {
4254                         { "MIC1 pin", 0x0 },
4255                         { "MIC2 pin", 0x1 },
4256                         { "LINE1 pin", 0x2 },
4257                         { "LINE2 pin", 0x3 },
4258                         { "CD pin", 0x4 },
4259                         { "LINE-OUT pin", 0x5 },
4260                         { "HP-OUT pin", 0x6 },
4261                 },
4262         },
4263         {
4264                 .num_items = 8,
4265                 .items = {
4266                         { "MIC1 pin", 0x0 },
4267                         { "MIC2 pin", 0x1 },
4268                         { "LINE1 pin", 0x2 },
4269                         { "LINE2 pin", 0x3 },
4270                         { "CD pin", 0x4 },
4271                         { "Mixer", 0x5 },
4272                         { "LINE-OUT pin", 0x6 },
4273                         { "HP-OUT pin", 0x7 },
4274                 },
4275         },
4276 };
4277 static struct snd_kcontrol_new alc260_test_mixer[] = {
4278         /* Output driver widgets */
4279         HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
4280         HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
4281         HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4282         HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
4283         HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
4284         HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
4285
4286         /* Modes for retasking pin widgets
4287          * Note: the ALC260 doesn't seem to act on requests to enable mic
4288          * bias from NIDs 0x0f and 0x10.  The ALC260 datasheet doesn't
4289          * mention this restriction.  At this stage it's not clear whether
4290          * this behaviour is intentional or is a hardware bug in chip
4291          * revisions available at least up until early 2006.  Therefore for
4292          * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
4293          * choices, but if it turns out that the lack of mic bias for these
4294          * NIDs is intentional we could change their modes from
4295          * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
4296          */
4297         ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
4298         ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
4299         ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
4300         ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
4301         ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
4302         ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
4303
4304         /* Loopback mixer controls */
4305         HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
4306         HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
4307         HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
4308         HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
4309         HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
4310         HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
4311         HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
4312         HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
4313         HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
4314         HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
4315         HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT),
4316         HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT),
4317         HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
4318         HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
4319         HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
4320         HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
4321
4322         /* Controls for GPIO pins, assuming they are configured as outputs */
4323         ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
4324         ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
4325         ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
4326         ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
4327
4328         /* Switches to allow the digital IO pins to be enabled.  The datasheet
4329          * is ambigious as to which NID is which; testing on laptops which
4330          * make this output available should provide clarification. 
4331          */
4332         ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
4333         ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
4334
4335         { } /* end */
4336 };
4337 static struct hda_verb alc260_test_init_verbs[] = {
4338         /* Enable all GPIOs as outputs with an initial value of 0 */
4339         {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
4340         {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
4341         {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
4342
4343         /* Enable retasking pins as output, initially without power amp */
4344         {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4345         {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4346         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4347         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4348         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4349         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4350
4351         /* Disable digital (SPDIF) pins initially, but users can enable
4352          * them via a mixer switch.  In the case of SPDIF-out, this initverb
4353          * payload also sets the generation to 0, output to be in "consumer"
4354          * PCM format, copyright asserted, no pre-emphasis and no validity
4355          * control.
4356          */
4357         {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
4358         {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
4359
4360         /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the 
4361          * OUT1 sum bus when acting as an output.
4362          */
4363         {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
4364         {0x0c, AC_VERB_SET_CONNECT_SEL, 0},
4365         {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4366         {0x0e, AC_VERB_SET_CONNECT_SEL, 0},
4367
4368         /* Start with output sum widgets muted and their output gains at min */
4369         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4370         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4371         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4372         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4373         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4374         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4375         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4376         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4377         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4378
4379         /* Unmute retasking pin widget output buffers since the default
4380          * state appears to be output.  As the pin mode is changed by the
4381          * user the pin mode control will take care of enabling the pin's
4382          * input/output buffers as needed.
4383          */
4384         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4385         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4386         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4387         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4388         {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4389         {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4390         /* Also unmute the mono-out pin widget */
4391         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4392
4393         /* Mute capture amp left and right */
4394         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4395         /* Set ADC connection select to match default mixer setting (mic1
4396          * pin)
4397          */
4398         {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4399
4400         /* Do the same for the second ADC: mute capture input amp and
4401          * set ADC connection to mic1 pin
4402          */
4403         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4404         {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4405
4406         /* Mute all inputs to mixer widget (even unconnected ones) */
4407         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
4408         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
4409         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
4410         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
4411         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
4412         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
4413         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
4414         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4415
4416         { }
4417 };
4418 #endif
4419
4420 static struct hda_pcm_stream alc260_pcm_analog_playback = {
4421         .substreams = 1,
4422         .channels_min = 2,
4423         .channels_max = 2,
4424 };
4425
4426 static struct hda_pcm_stream alc260_pcm_analog_capture = {
4427         .substreams = 1,
4428         .channels_min = 2,
4429         .channels_max = 2,
4430 };
4431
4432 #define alc260_pcm_digital_playback     alc880_pcm_digital_playback
4433 #define alc260_pcm_digital_capture      alc880_pcm_digital_capture
4434
4435 /*
4436  * for BIOS auto-configuration
4437  */
4438
4439 static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
4440                                         const char *pfx)
4441 {
4442         hda_nid_t nid_vol;
4443         unsigned long vol_val, sw_val;
4444         char name[32];
4445         int err;
4446
4447         if (nid >= 0x0f && nid < 0x11) {
4448                 nid_vol = nid - 0x7;
4449                 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
4450                 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
4451         } else if (nid == 0x11) {
4452                 nid_vol = nid - 0x7;
4453                 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
4454                 sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
4455         } else if (nid >= 0x12 && nid <= 0x15) {
4456                 nid_vol = 0x08;
4457                 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
4458                 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
4459         } else
4460                 return 0; /* N/A */
4461         
4462         snprintf(name, sizeof(name), "%s Playback Volume", pfx);
4463         err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val);
4464         if (err < 0)
4465                 return err;
4466         snprintf(name, sizeof(name), "%s Playback Switch", pfx);
4467         err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, sw_val);
4468         if (err < 0)
4469                 return err;
4470         return 1;
4471 }
4472
4473 /* add playback controls from the parsed DAC table */
4474 static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
4475                                              const struct auto_pin_cfg *cfg)
4476 {
4477         hda_nid_t nid;
4478         int err;
4479
4480         spec->multiout.num_dacs = 1;
4481         spec->multiout.dac_nids = spec->private_dac_nids;
4482         spec->multiout.dac_nids[0] = 0x02;
4483
4484         nid = cfg->line_out_pins[0];
4485         if (nid) {
4486                 err = alc260_add_playback_controls(spec, nid, "Front");
4487                 if (err < 0)
4488                         return err;
4489         }
4490
4491         nid = cfg->speaker_pins[0];
4492         if (nid) {
4493                 err = alc260_add_playback_controls(spec, nid, "Speaker");
4494                 if (err < 0)
4495                         return err;
4496         }
4497
4498         nid = cfg->hp_pins[0];
4499         if (nid) {
4500                 err = alc260_add_playback_controls(spec, nid, "Headphone");
4501                 if (err < 0)
4502                         return err;
4503         }
4504         return 0;
4505 }
4506
4507 /* create playback/capture controls for input pins */
4508 static int alc260_auto_create_analog_input_ctls(struct alc_spec *spec,
4509                                                 const struct auto_pin_cfg *cfg)
4510 {
4511         struct hda_input_mux *imux = &spec->private_imux;
4512         int i, err, idx;
4513
4514         for (i = 0; i < AUTO_PIN_LAST; i++) {
4515                 if (cfg->input_pins[i] >= 0x12) {
4516                         idx = cfg->input_pins[i] - 0x12;
4517                         err = new_analog_input(spec, cfg->input_pins[i],
4518                                                auto_pin_cfg_labels[i], idx,
4519                                                0x07);
4520                         if (err < 0)
4521                                 return err;
4522                         imux->items[imux->num_items].label =
4523                                 auto_pin_cfg_labels[i];
4524                         imux->items[imux->num_items].index = idx;
4525                         imux->num_items++;
4526                 }
4527                 if (cfg->input_pins[i] >= 0x0f && cfg->input_pins[i] <= 0x10){
4528                         idx = cfg->input_pins[i] - 0x09;
4529                         err = new_analog_input(spec, cfg->input_pins[i],
4530                                                auto_pin_cfg_labels[i], idx,
4531                                                0x07);
4532                         if (err < 0)
4533                                 return err;
4534                         imux->items[imux->num_items].label =
4535                                 auto_pin_cfg_labels[i];
4536                         imux->items[imux->num_items].index = idx;
4537                         imux->num_items++;
4538                 }
4539         }
4540         return 0;
4541 }
4542
4543 static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
4544                                               hda_nid_t nid, int pin_type,
4545                                               int sel_idx)
4546 {
4547         /* set as output */
4548         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4549                             pin_type);
4550         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
4551                             AMP_OUT_UNMUTE);
4552         /* need the manual connection? */
4553         if (nid >= 0x12) {
4554                 int idx = nid - 0x12;
4555                 snd_hda_codec_write(codec, idx + 0x0b, 0,
4556                                     AC_VERB_SET_CONNECT_SEL, sel_idx);
4557         }
4558 }
4559
4560 static void alc260_auto_init_multi_out(struct hda_codec *codec)
4561 {
4562         struct alc_spec *spec = codec->spec;
4563         hda_nid_t nid;
4564
4565         alc_subsystem_id(codec, 0x10, 0x15, 0x0f);
4566         nid = spec->autocfg.line_out_pins[0];
4567         if (nid) {
4568                 int pin_type = get_pin_type(spec->autocfg.line_out_type);
4569                 alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
4570         }
4571         
4572         nid = spec->autocfg.speaker_pins[0];
4573         if (nid)
4574                 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
4575
4576         nid = spec->autocfg.hp_pins[0];
4577         if (nid)
4578                 alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
4579 }
4580
4581 #define ALC260_PIN_CD_NID               0x16
4582 static void alc260_auto_init_analog_input(struct hda_codec *codec)
4583 {
4584         struct alc_spec *spec = codec->spec;
4585         int i;
4586
4587         for (i = 0; i < AUTO_PIN_LAST; i++) {
4588                 hda_nid_t nid = spec->autocfg.input_pins[i];
4589                 if (nid >= 0x12) {
4590                         snd_hda_codec_write(codec, nid, 0,
4591                                             AC_VERB_SET_PIN_WIDGET_CONTROL,
4592                                             i <= AUTO_PIN_FRONT_MIC ?
4593                                             PIN_VREF80 : PIN_IN);
4594                         if (nid != ALC260_PIN_CD_NID)
4595                                 snd_hda_codec_write(codec, nid, 0,
4596                                                     AC_VERB_SET_AMP_GAIN_MUTE,
4597                                                     AMP_OUT_MUTE);
4598                 }
4599         }
4600 }
4601
4602 /*
4603  * generic initialization of ADC, input mixers and output mixers
4604  */
4605 static struct hda_verb alc260_volume_init_verbs[] = {
4606         /*
4607          * Unmute ADC0-1 and set the default input to mic-in
4608          */
4609         {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
4610         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4611         {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
4612         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4613         
4614         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
4615          * mixer widget
4616          * Note: PASD motherboards uses the Line In 2 as the input for
4617          * front panel mic (mic 2)
4618          */
4619         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
4620         /* mute analog inputs */
4621         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4622         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4623         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4624         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4625         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4626
4627         /*
4628          * Set up output mixers (0x08 - 0x0a)
4629          */
4630         /* set vol=0 to output mixers */
4631         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4632         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4633         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4634         /* set up input amps for analog loopback */
4635         /* Amp Indices: DAC = 0, mixer = 1 */
4636         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4637         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4638         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4639         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4640         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4641         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4642         
4643         { }
4644 };
4645
4646 static int alc260_parse_auto_config(struct hda_codec *codec)
4647 {
4648         struct alc_spec *spec = codec->spec;
4649         unsigned int wcap;
4650         int err;
4651         static hda_nid_t alc260_ignore[] = { 0x17, 0 };
4652
4653         err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
4654                                            alc260_ignore);
4655         if (err < 0)
4656                 return err;
4657         err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
4658         if (err < 0)
4659                 return err;
4660         if (!spec->kctl_alloc)
4661                 return 0; /* can't find valid BIOS pin config */
4662         err = alc260_auto_create_analog_input_ctls(spec, &spec->autocfg);
4663         if (err < 0)
4664                 return err;
4665
4666         spec->multiout.max_channels = 2;
4667
4668         if (spec->autocfg.dig_out_pin)
4669                 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
4670         if (spec->kctl_alloc)
4671                 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
4672
4673         spec->init_verbs[spec->num_init_verbs++] = alc260_volume_init_verbs;
4674
4675         spec->num_mux_defs = 1;
4676         spec->input_mux = &spec->private_imux;
4677
4678         /* check whether NID 0x04 is valid */
4679         wcap = get_wcaps(codec, 0x04);
4680         wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; /* get type */
4681         if (wcap != AC_WID_AUD_IN) {
4682                 spec->adc_nids = alc260_adc_nids_alt;
4683                 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
4684                 spec->mixers[spec->num_mixers] = alc260_capture_alt_mixer;
4685         } else {
4686                 spec->adc_nids = alc260_adc_nids;
4687                 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
4688                 spec->mixers[spec->num_mixers] = alc260_capture_mixer;
4689         }
4690         spec->num_mixers++;
4691
4692         return 1;
4693 }
4694
4695 /* additional initialization for auto-configuration model */
4696 static void alc260_auto_init(struct hda_codec *codec)
4697 {
4698         alc260_auto_init_multi_out(codec);
4699         alc260_auto_init_analog_input(codec);
4700 }
4701
4702 #ifdef CONFIG_SND_HDA_POWER_SAVE
4703 static struct hda_amp_list alc260_loopbacks[] = {
4704         { 0x07, HDA_INPUT, 0 },
4705         { 0x07, HDA_INPUT, 1 },
4706         { 0x07, HDA_INPUT, 2 },
4707         { 0x07, HDA_INPUT, 3 },
4708         { 0x07, HDA_INPUT, 4 },
4709         { } /* end */
4710 };
4711 #endif
4712
4713 /*
4714  * ALC260 configurations
4715  */
4716 static const char *alc260_models[ALC260_MODEL_LAST] = {
4717         [ALC260_BASIC]          = "basic",
4718         [ALC260_HP]             = "hp",
4719         [ALC260_HP_3013]        = "hp-3013",
4720         [ALC260_FUJITSU_S702X]  = "fujitsu",
4721         [ALC260_ACER]           = "acer",
4722         [ALC260_WILL]           = "will",
4723         [ALC260_REPLACER_672V]  = "replacer",
4724 #ifdef CONFIG_SND_DEBUG
4725         [ALC260_TEST]           = "test",
4726 #endif
4727         [ALC260_AUTO]           = "auto",
4728 };
4729
4730 static struct snd_pci_quirk alc260_cfg_tbl[] = {
4731         SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
4732         SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
4733         SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
4734         SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_HP_3013),
4735         SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
4736         SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP),
4737         SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_3013),
4738         SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
4739         SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
4740         SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
4741         SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
4742         SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
4743         SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
4744         SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
4745         SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
4746         SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
4747         SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
4748         SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
4749         {}
4750 };
4751
4752 static struct alc_config_preset alc260_presets[] = {
4753         [ALC260_BASIC] = {
4754                 .mixers = { alc260_base_output_mixer,
4755                             alc260_input_mixer,
4756                             alc260_pc_beep_mixer,
4757                             alc260_capture_mixer },
4758                 .init_verbs = { alc260_init_verbs },
4759                 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
4760                 .dac_nids = alc260_dac_nids,
4761                 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
4762                 .adc_nids = alc260_adc_nids,
4763                 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4764                 .channel_mode = alc260_modes,
4765                 .input_mux = &alc260_capture_source,
4766         },
4767         [ALC260_HP] = {
4768                 .mixers = { alc260_base_output_mixer,
4769                             alc260_input_mixer,
4770                             alc260_capture_alt_mixer },
4771                 .init_verbs = { alc260_init_verbs },
4772                 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
4773                 .dac_nids = alc260_dac_nids,
4774                 .num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
4775                 .adc_nids = alc260_hp_adc_nids,
4776                 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4777                 .channel_mode = alc260_modes,
4778                 .input_mux = &alc260_capture_source,
4779         },
4780         [ALC260_HP_3013] = {
4781                 .mixers = { alc260_hp_3013_mixer,
4782                             alc260_input_mixer,
4783                             alc260_capture_alt_mixer },
4784                 .init_verbs = { alc260_hp_3013_init_verbs },
4785                 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
4786                 .dac_nids = alc260_dac_nids,
4787                 .num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids),
4788                 .adc_nids = alc260_hp_adc_nids,
4789                 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4790                 .channel_mode = alc260_modes,
4791                 .input_mux = &alc260_capture_source,
4792         },
4793         [ALC260_FUJITSU_S702X] = {
4794                 .mixers = { alc260_fujitsu_mixer,
4795                             alc260_capture_mixer },
4796                 .init_verbs = { alc260_fujitsu_init_verbs },
4797                 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
4798                 .dac_nids = alc260_dac_nids,
4799                 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
4800                 .adc_nids = alc260_dual_adc_nids,
4801                 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4802                 .channel_mode = alc260_modes,
4803                 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
4804                 .input_mux = alc260_fujitsu_capture_sources,
4805         },
4806         [ALC260_ACER] = {
4807                 .mixers = { alc260_acer_mixer,
4808                             alc260_capture_mixer },
4809                 .init_verbs = { alc260_acer_init_verbs },
4810                 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
4811                 .dac_nids = alc260_dac_nids,
4812                 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
4813                 .adc_nids = alc260_dual_adc_nids,
4814                 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4815                 .channel_mode = alc260_modes,
4816                 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
4817                 .input_mux = alc260_acer_capture_sources,
4818         },
4819         [ALC260_WILL] = {
4820                 .mixers = { alc260_will_mixer,
4821                             alc260_capture_mixer },
4822                 .init_verbs = { alc260_init_verbs, alc260_will_verbs },
4823                 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
4824                 .dac_nids = alc260_dac_nids,
4825                 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
4826                 .adc_nids = alc260_adc_nids,
4827                 .dig_out_nid = ALC260_DIGOUT_NID,
4828                 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4829                 .channel_mode = alc260_modes,
4830                 .input_mux = &alc260_capture_source,
4831         },
4832         [ALC260_REPLACER_672V] = {
4833                 .mixers = { alc260_replacer_672v_mixer,
4834                             alc260_capture_mixer },
4835                 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
4836                 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
4837                 .dac_nids = alc260_dac_nids,
4838                 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
4839                 .adc_nids = alc260_adc_nids,
4840                 .dig_out_nid = ALC260_DIGOUT_NID,
4841                 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4842                 .channel_mode = alc260_modes,
4843                 .input_mux = &alc260_capture_source,
4844                 .unsol_event = alc260_replacer_672v_unsol_event,
4845                 .init_hook = alc260_replacer_672v_automute,
4846         },
4847 #ifdef CONFIG_SND_DEBUG
4848         [ALC260_TEST] = {
4849                 .mixers = { alc260_test_mixer,
4850                             alc260_capture_mixer },
4851                 .init_verbs = { alc260_test_init_verbs },
4852                 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
4853                 .dac_nids = alc260_test_dac_nids,
4854                 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
4855                 .adc_nids = alc260_test_adc_nids,
4856                 .num_channel_mode = ARRAY_SIZE(alc260_modes),
4857                 .channel_mode = alc260_modes,
4858                 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
4859                 .input_mux = alc260_test_capture_sources,
4860         },
4861 #endif
4862 };
4863
4864 static int patch_alc260(struct hda_codec *codec)
4865 {
4866         struct alc_spec *spec;
4867         int err, board_config;
4868
4869         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
4870         if (spec == NULL)
4871                 return -ENOMEM;
4872
4873         codec->spec = spec;
4874
4875         board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
4876                                                   alc260_models,
4877                                                   alc260_cfg_tbl);
4878         if (board_config < 0) {
4879                 snd_printd(KERN_INFO "hda_codec: Unknown model for ALC260, "
4880                            "trying auto-probe from BIOS...\n");
4881                 board_config = ALC260_AUTO;
4882         }
4883
4884         if (board_config == ALC260_AUTO) {
4885                 /* automatic parse from the BIOS config */
4886                 err = alc260_parse_auto_config(codec);
4887                 if (err < 0) {
4888                         alc_free(codec);
4889                         return err;
4890                 } else if (!err) {
4891                         printk(KERN_INFO
4892                                "hda_codec: Cannot set up configuration "
4893                                "from BIOS.  Using base mode...\n");
4894                         board_config = ALC260_BASIC;
4895                 }
4896         }
4897
4898         if (board_config != ALC260_AUTO)
4899                 setup_preset(spec, &alc260_presets[board_config]);
4900
4901         spec->stream_name_analog = "ALC260 Analog";
4902         spec->stream_analog_playback = &alc260_pcm_analog_playback;
4903         spec->stream_analog_capture = &alc260_pcm_analog_capture;
4904
4905         spec->stream_name_digital = "ALC260 Digital";
4906         spec->stream_digital_playback = &alc260_pcm_digital_playback;
4907         spec->stream_digital_capture = &alc260_pcm_digital_capture;
4908
4909         codec->patch_ops = alc_patch_ops;
4910         if (board_config == ALC260_AUTO)
4911                 spec->init_hook = alc260_auto_init;
4912 #ifdef CONFIG_SND_HDA_POWER_SAVE
4913         if (!spec->loopback.amplist)
4914                 spec->loopback.amplist = alc260_loopbacks;
4915 #endif
4916
4917         return 0;
4918 }
4919
4920
4921 /*
4922  * ALC882 support
4923  *
4924  * ALC882 is almost identical with ALC880 but has cleaner and more flexible
4925  * configuration.  Each pin widget can choose any input DACs and a mixer.
4926  * Each ADC is connected from a mixer of all inputs.  This makes possible
4927  * 6-channel independent captures.
4928  *
4929  * In addition, an independent DAC for the multi-playback (not used in this
4930  * driver yet).
4931  */
4932 #define ALC882_DIGOUT_NID       0x06
4933 #define ALC882_DIGIN_NID        0x0a
4934
4935 static struct hda_channel_mode alc882_ch_modes[1] = {
4936         { 8, NULL }
4937 };
4938
4939 static hda_nid_t alc882_dac_nids[4] = {
4940         /* front, rear, clfe, rear_surr */
4941         0x02, 0x03, 0x04, 0x05
4942 };
4943
4944 /* identical with ALC880 */
4945 #define alc882_adc_nids         alc880_adc_nids
4946 #define alc882_adc_nids_alt     alc880_adc_nids_alt
4947
4948 /* input MUX */
4949 /* FIXME: should be a matrix-type input source selection */
4950
4951 static struct hda_input_mux alc882_capture_source = {
4952         .num_items = 4,
4953         .items = {
4954                 { "Mic", 0x0 },
4955                 { "Front Mic", 0x1 },
4956                 { "Line", 0x2 },
4957                 { "CD", 0x4 },
4958         },
4959 };
4960 #define alc882_mux_enum_info alc_mux_enum_info
4961 #define alc882_mux_enum_get alc_mux_enum_get
4962
4963 static int alc882_mux_enum_put(struct snd_kcontrol *kcontrol,
4964                                struct snd_ctl_elem_value *ucontrol)
4965 {
4966         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4967         struct alc_spec *spec = codec->spec;
4968         const struct hda_input_mux *imux = spec->input_mux;
4969         unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
4970         static hda_nid_t capture_mixers[3] = { 0x24, 0x23, 0x22 };
4971         hda_nid_t nid = capture_mixers[adc_idx];
4972         unsigned int *cur_val = &spec->cur_mux[adc_idx];
4973         unsigned int i, idx;
4974
4975         idx = ucontrol->value.enumerated.item[0];
4976         if (idx >= imux->num_items)
4977                 idx = imux->num_items - 1;
4978         if (*cur_val == idx)
4979                 return 0;
4980         for (i = 0; i < imux->num_items; i++) {
4981                 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
4982                 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
4983                                          imux->items[i].index,
4984                                          HDA_AMP_MUTE, v);
4985         }
4986         *cur_val = idx;
4987         return 1;
4988 }
4989
4990 /*
4991  * 2ch mode
4992  */
4993 static struct hda_verb alc882_3ST_ch2_init[] = {
4994         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
4995         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
4996         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
4997         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
4998         { } /* end */
4999 };
5000
5001 /*
5002  * 6ch mode
5003  */
5004 static struct hda_verb alc882_3ST_ch6_init[] = {
5005         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5006         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
5007         { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
5008         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5009         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
5010         { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
5011         { } /* end */
5012 };
5013
5014 static struct hda_channel_mode alc882_3ST_6ch_modes[2] = {
5015         { 2, alc882_3ST_ch2_init },
5016         { 6, alc882_3ST_ch6_init },
5017 };
5018
5019 /*
5020  * 6ch mode
5021  */
5022 static struct hda_verb alc882_sixstack_ch6_init[] = {
5023         { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
5024         { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5025         { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5026         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5027         { } /* end */
5028 };
5029
5030 /*
5031  * 8ch mode
5032  */
5033 static struct hda_verb alc882_sixstack_ch8_init[] = {
5034         { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5035         { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5036         { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5037         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5038         { } /* end */
5039 };
5040
5041 static struct hda_channel_mode alc882_sixstack_modes[2] = {
5042         { 6, alc882_sixstack_ch6_init },
5043         { 8, alc882_sixstack_ch8_init },
5044 };
5045
5046 /*
5047  * macbook pro ALC885 can switch LineIn to LineOut without loosing Mic
5048  */
5049
5050 /*
5051  * 2ch mode
5052  */
5053 static struct hda_verb alc885_mbp_ch2_init[] = {
5054         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
5055         { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5056         { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5057         { } /* end */
5058 };
5059
5060 /*
5061  * 6ch mode
5062  */
5063 static struct hda_verb alc885_mbp_ch6_init[] = {
5064         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
5065         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5066         { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
5067         { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5068         { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5069         { } /* end */
5070 };
5071
5072 static struct hda_channel_mode alc885_mbp_6ch_modes[2] = {
5073         { 2, alc885_mbp_ch2_init },
5074         { 6, alc885_mbp_ch6_init },
5075 };
5076
5077
5078 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
5079  *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
5080  */
5081 static struct snd_kcontrol_new alc882_base_mixer[] = {
5082         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5083         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5084         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
5085         HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
5086         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
5087         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
5088         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
5089         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
5090         HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
5091         HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
5092         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5093         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5094         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5095         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5096         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5097         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5098         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5099         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5100         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5101         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
5102         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5103         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5104         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5105         { } /* end */
5106 };
5107
5108 static struct snd_kcontrol_new alc885_mbp3_mixer[] = {
5109         HDA_CODEC_VOLUME("Master Volume", 0x0c, 0x00, HDA_OUTPUT),
5110         HDA_BIND_MUTE   ("Master Switch", 0x0c, 0x02, HDA_INPUT),
5111         HDA_CODEC_MUTE  ("Speaker Switch", 0x14, 0x00, HDA_OUTPUT),
5112         HDA_CODEC_VOLUME("Line Out Volume", 0x0d,0x00, HDA_OUTPUT),
5113         HDA_CODEC_VOLUME("Line In Playback Volume", 0x0b, 0x02, HDA_INPUT),
5114         HDA_CODEC_MUTE  ("Line In Playback Switch", 0x0b, 0x02, HDA_INPUT),
5115         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
5116         HDA_CODEC_MUTE  ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
5117         HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0x00, HDA_INPUT),
5118         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT),
5119         { } /* end */
5120 };
5121 static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
5122         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5123         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5124         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5125         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5126         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5127         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5128         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5129         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5130         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5131         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5132         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5133         { } /* end */
5134 };
5135
5136 static struct snd_kcontrol_new alc882_targa_mixer[] = {
5137         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5138         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5139         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5140         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5141         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5142         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5143         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5144         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5145         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5146         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5147         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5148         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5149         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
5150         { } /* end */
5151 };
5152
5153 /* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
5154  *                 Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
5155  */
5156 static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
5157         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5158         HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
5159         HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5160         HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
5161         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5162         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5163         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5164         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5165         HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
5166         HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
5167         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5168         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5169         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5170         { } /* end */
5171 };
5172
5173 static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
5174         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5175         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5176         HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5177         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5178         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5179         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5180         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5181         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5182         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5183         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5184         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5185         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5186         { } /* end */
5187 };
5188
5189 static struct snd_kcontrol_new alc882_chmode_mixer[] = {
5190         {
5191                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5192                 .name = "Channel Mode",
5193                 .info = alc_ch_mode_info,
5194                 .get = alc_ch_mode_get,
5195                 .put = alc_ch_mode_put,
5196         },
5197         { } /* end */
5198 };
5199
5200 static struct hda_verb alc882_init_verbs[] = {
5201         /* Front mixer: unmute input/output amp left and right (volume = 0) */
5202         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5203         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5204         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5205         /* Rear mixer */
5206         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5207         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5208         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5209         /* CLFE mixer */
5210         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5211         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5212         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5213         /* Side mixer */
5214         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5215         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5216         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5217
5218         /* Front Pin: output 0 (0x0c) */
5219         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5220         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5221         {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
5222         /* Rear Pin: output 1 (0x0d) */
5223         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5224         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5225         {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
5226         /* CLFE Pin: output 2 (0x0e) */
5227         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5228         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5229         {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
5230         /* Side Pin: output 3 (0x0f) */
5231         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5232         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5233         {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
5234         /* Mic (rear) pin: input vref at 80% */
5235         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5236         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5237         /* Front Mic pin: input vref at 80% */
5238         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5239         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5240         /* Line In pin: input */
5241         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5242         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5243         /* Line-2 In: Headphone output (output 0 - 0x0c) */
5244         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5245         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5246         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
5247         /* CD pin widget for input */
5248         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5249
5250         /* FIXME: use matrix-type input source selection */
5251         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5252         /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5253         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5254         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5255         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5256         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5257         /* Input mixer2 */
5258         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5259         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5260         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5261         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5262         /* Input mixer3 */
5263         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5264         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5265         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5266         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5267         /* ADC1: mute amp left and right */
5268         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5269         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5270         /* ADC2: mute amp left and right */
5271         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5272         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5273         /* ADC3: mute amp left and right */
5274         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5275         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5276
5277         { }
5278 };
5279
5280 static struct hda_verb alc882_eapd_verbs[] = {
5281         /* change to EAPD mode */
5282         {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
5283         {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
5284         { }
5285 };
5286
5287 /* Mac Pro test */
5288 static struct snd_kcontrol_new alc882_macpro_mixer[] = {
5289         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5290         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
5291         HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
5292         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
5293         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
5294         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x02, HDA_INPUT),
5295         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x02, HDA_INPUT),
5296         { } /* end */
5297 };
5298
5299 static struct hda_verb alc882_macpro_init_verbs[] = {
5300         /* Front mixer: unmute input/output amp left and right (volume = 0) */
5301         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5302         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5303         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5304         /* Front Pin: output 0 (0x0c) */
5305         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5306         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5307         {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
5308         /* Front Mic pin: input vref at 80% */
5309         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5310         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5311         /* Speaker:  output */
5312         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5313         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5314         {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
5315         /* Headphone output (output 0 - 0x0c) */
5316         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5317         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5318         {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
5319
5320         /* FIXME: use matrix-type input source selection */
5321         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5322         /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5323         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5324         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5325         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5326         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5327         /* Input mixer2 */
5328         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5329         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5330         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5331         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5332         /* Input mixer3 */
5333         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5334         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5335         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5336         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5337         /* ADC1: mute amp left and right */
5338         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5339         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5340         /* ADC2: mute amp left and right */
5341         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5342         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5343         /* ADC3: mute amp left and right */
5344         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5345         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5346
5347         { }
5348 };
5349
5350 /* Macbook Pro rev3 */
5351 static struct hda_verb alc885_mbp3_init_verbs[] = {
5352         /* Front mixer: unmute input/output amp left and right (volume = 0) */
5353         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5354         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5355         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5356         /* Rear mixer */
5357         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5358         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5359         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5360         /* Front Pin: output 0 (0x0c) */
5361         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5362         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5363         {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
5364         /* HP Pin: output 0 (0x0d) */
5365         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
5366         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5367         {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
5368         {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
5369         /* Mic (rear) pin: input vref at 80% */
5370         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5371         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5372         /* Front Mic pin: input vref at 80% */
5373         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5374         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5375         /* Line In pin: use output 1 when in LineOut mode */
5376         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5377         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5378         {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
5379
5380         /* FIXME: use matrix-type input source selection */
5381         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5382         /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5383         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5384         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5385         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5386         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5387         /* Input mixer2 */
5388         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5389         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5390         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5391         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5392         /* Input mixer3 */
5393         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5394         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5395         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5396         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5397         /* ADC1: mute amp left and right */
5398         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5399         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5400         /* ADC2: mute amp left and right */
5401         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5402         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5403         /* ADC3: mute amp left and right */
5404         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5405         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5406
5407         { }
5408 };
5409
5410 /* iMac 24 mixer. */
5411 static struct snd_kcontrol_new alc885_imac24_mixer[] = {
5412         HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
5413         HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
5414         { } /* end */
5415 };
5416
5417 /* iMac 24 init verbs. */
5418 static struct hda_verb alc885_imac24_init_verbs[] = {
5419         /* Internal speakers: output 0 (0x0c) */
5420         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5421         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5422         {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
5423         /* Internal speakers: output 0 (0x0c) */
5424         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5425         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5426         {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
5427         /* Headphone: output 0 (0x0c) */
5428         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5429         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
5430         {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
5431         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
5432         /* Front Mic: input vref at 80% */
5433         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5434         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5435         { }
5436 };
5437
5438 /* Toggle speaker-output according to the hp-jack state */
5439 static void alc885_imac24_automute(struct hda_codec *codec)
5440 {
5441         unsigned int present;
5442
5443         present = snd_hda_codec_read(codec, 0x14, 0,
5444                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
5445         snd_hda_codec_amp_stereo(codec, 0x18, HDA_OUTPUT, 0,
5446                                  HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
5447         snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
5448                                  HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
5449 }
5450
5451 /* Processes unsolicited events. */
5452 static void alc885_imac24_unsol_event(struct hda_codec *codec,
5453                                       unsigned int res)
5454 {
5455         /* Headphone insertion or removal. */
5456         if ((res >> 26) == ALC880_HP_EVENT)
5457                 alc885_imac24_automute(codec);
5458 }
5459
5460 static void alc885_mbp3_automute(struct hda_codec *codec)
5461 {
5462         unsigned int present;
5463
5464         present = snd_hda_codec_read(codec, 0x15, 0,
5465                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
5466         snd_hda_codec_amp_stereo(codec, 0x14,  HDA_OUTPUT, 0,
5467                                  HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
5468         snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
5469                                  HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
5470
5471 }
5472 static void alc885_mbp3_unsol_event(struct hda_codec *codec,
5473                                     unsigned int res)
5474 {
5475         /* Headphone insertion or removal. */
5476         if ((res >> 26) == ALC880_HP_EVENT)
5477                 alc885_mbp3_automute(codec);
5478 }
5479
5480
5481 static struct hda_verb alc882_targa_verbs[] = {
5482         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5483         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5484
5485         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5486         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5487         
5488         {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
5489         {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
5490         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5491
5492         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
5493         {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
5494         {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
5495         {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
5496         { } /* end */
5497 };
5498
5499 /* toggle speaker-output according to the hp-jack state */
5500 static void alc882_targa_automute(struct hda_codec *codec)
5501 {
5502         unsigned int present;
5503  
5504         present = snd_hda_codec_read(codec, 0x14, 0,
5505                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
5506         snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
5507                                  HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
5508         snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
5509                                   present ? 1 : 3);
5510 }
5511
5512 static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
5513 {
5514         /* Looks like the unsol event is incompatible with the standard
5515          * definition.  4bit tag is placed at 26 bit!
5516          */
5517         if (((res >> 26) == ALC880_HP_EVENT)) {
5518                 alc882_targa_automute(codec);
5519         }
5520 }
5521
5522 static struct hda_verb alc882_asus_a7j_verbs[] = {
5523         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5524         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5525
5526         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5527         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5528         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5529         
5530         {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
5531         {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5532         {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
5533
5534         {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
5535         {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
5536         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5537         { } /* end */
5538 };
5539
5540 static struct hda_verb alc882_asus_a7m_verbs[] = {
5541         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5542         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5543
5544         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5545         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5546         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5547         
5548         {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
5549         {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5550         {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
5551
5552         {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
5553         {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
5554         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5555         { } /* end */
5556 };
5557
5558 static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
5559 {
5560         unsigned int gpiostate, gpiomask, gpiodir;
5561
5562         gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
5563                                        AC_VERB_GET_GPIO_DATA, 0);
5564
5565         if (!muted)
5566                 gpiostate |= (1 << pin);
5567         else
5568                 gpiostate &= ~(1 << pin);
5569
5570         gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
5571                                       AC_VERB_GET_GPIO_MASK, 0);
5572         gpiomask |= (1 << pin);
5573
5574         gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
5575                                      AC_VERB_GET_GPIO_DIRECTION, 0);
5576         gpiodir |= (1 << pin);
5577
5578
5579         snd_hda_codec_write(codec, codec->afg, 0,
5580                             AC_VERB_SET_GPIO_MASK, gpiomask);
5581         snd_hda_codec_write(codec, codec->afg, 0,
5582                             AC_VERB_SET_GPIO_DIRECTION, gpiodir);
5583
5584         msleep(1);
5585
5586         snd_hda_codec_write(codec, codec->afg, 0,
5587                             AC_VERB_SET_GPIO_DATA, gpiostate);
5588 }
5589
5590 /* set up GPIO at initialization */
5591 static void alc885_macpro_init_hook(struct hda_codec *codec)
5592 {
5593         alc882_gpio_mute(codec, 0, 0);
5594         alc882_gpio_mute(codec, 1, 0);
5595 }
5596
5597 /* set up GPIO and update auto-muting at initialization */
5598 static void alc885_imac24_init_hook(struct hda_codec *codec)
5599 {
5600         alc885_macpro_init_hook(codec);
5601         alc885_imac24_automute(codec);
5602 }
5603
5604 /*
5605  * generic initialization of ADC, input mixers and output mixers
5606  */
5607 static struct hda_verb alc882_auto_init_verbs[] = {
5608         /*
5609          * Unmute ADC0-2 and set the default input to mic-in
5610          */
5611         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
5612         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5613         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
5614         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5615         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
5616         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5617
5618         /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
5619          * mixer widget
5620          * Note: PASD motherboards uses the Line In 2 as the input for
5621          * front panel mic (mic 2)
5622          */
5623         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
5624         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5625         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5626         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5627         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5628         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5629
5630         /*
5631          * Set up output mixers (0x0c - 0x0f)
5632          */
5633         /* set vol=0 to output mixers */
5634         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5635         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5636         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5637         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5638         /* set up input amps for analog loopback */
5639         /* Amp Indices: DAC = 0, mixer = 1 */
5640         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5641         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5642         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5643         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5644         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5645         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5646         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5647         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5648         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5649         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5650
5651         /* FIXME: use matrix-type input source selection */
5652         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
5653         /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
5654         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5655         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
5656         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
5657         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
5658         /* Input mixer2 */
5659         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5660         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
5661         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
5662         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
5663         /* Input mixer3 */
5664         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
5665         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
5666         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
5667         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
5668
5669         { }
5670 };
5671
5672 /* capture mixer elements */
5673 static struct snd_kcontrol_new alc882_capture_alt_mixer[] = {
5674         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
5675         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5676         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
5677         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
5678         {
5679                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5680                 /* The multiple "Capture Source" controls confuse alsamixer
5681                  * So call somewhat different..
5682                  * FIXME: the controls appear in the "playback" view!
5683                  */
5684                 /* .name = "Capture Source", */
5685                 .name = "Input Source",
5686                 .count = 2,
5687                 .info = alc882_mux_enum_info,
5688                 .get = alc882_mux_enum_get,
5689                 .put = alc882_mux_enum_put,
5690         },
5691         { } /* end */
5692 };
5693
5694 static struct snd_kcontrol_new alc882_capture_mixer[] = {
5695         HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
5696         HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
5697         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
5698         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
5699         HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
5700         HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
5701         {
5702                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5703                 /* The multiple "Capture Source" controls confuse alsamixer
5704                  * So call somewhat different..
5705                  * FIXME: the controls appear in the "playback" view!
5706                  */
5707                 /* .name = "Capture Source", */
5708                 .name = "Input Source",
5709                 .count = 3,
5710                 .info = alc882_mux_enum_info,
5711                 .get = alc882_mux_enum_get,
5712                 .put = alc882_mux_enum_put,
5713         },
5714         { } /* end */
5715 };
5716
5717 #ifdef CONFIG_SND_HDA_POWER_SAVE
5718 #define alc882_loopbacks        alc880_loopbacks
5719 #endif
5720
5721 /* pcm configuration: identiacal with ALC880 */
5722 #define alc882_pcm_analog_playback      alc880_pcm_analog_playback
5723 #define alc882_pcm_analog_capture       alc880_pcm_analog_capture
5724 #define alc882_pcm_digital_playback     alc880_pcm_digital_playback
5725 #define alc882_pcm_digital_capture      alc880_pcm_digital_capture
5726
5727 /*
5728  * configuration and preset
5729  */
5730 static const char *alc882_models[ALC882_MODEL_LAST] = {
5731         [ALC882_3ST_DIG]        = "3stack-dig",
5732         [ALC882_6ST_DIG]        = "6stack-dig",
5733         [ALC882_ARIMA]          = "arima",
5734         [ALC882_W2JC]           = "w2jc",
5735         [ALC882_TARGA]          = "targa",
5736         [ALC882_ASUS_A7J]       = "asus-a7j",
5737         [ALC882_ASUS_A7M]       = "asus-a7m",
5738         [ALC885_MACPRO]         = "macpro",
5739         [ALC885_MBP3]           = "mbp3",
5740         [ALC885_IMAC24]         = "imac24",
5741         [ALC882_AUTO]           = "auto",
5742 };
5743
5744 static struct snd_pci_quirk alc882_cfg_tbl[] = {
5745         SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
5746         SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
5747         SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
5748         SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8  */
5749         SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA),
5750         SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
5751         SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
5752         SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
5753         SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
5754         SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
5755         SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
5756         {}
5757 };
5758
5759 static struct alc_config_preset alc882_presets[] = {
5760         [ALC882_3ST_DIG] = {
5761                 .mixers = { alc882_base_mixer },
5762                 .init_verbs = { alc882_init_verbs },
5763                 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5764                 .dac_nids = alc882_dac_nids,
5765                 .dig_out_nid = ALC882_DIGOUT_NID,
5766                 .dig_in_nid = ALC882_DIGIN_NID,
5767                 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
5768                 .channel_mode = alc882_ch_modes,
5769                 .need_dac_fix = 1,
5770                 .input_mux = &alc882_capture_source,
5771         },
5772         [ALC882_6ST_DIG] = {
5773                 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
5774                 .init_verbs = { alc882_init_verbs },
5775                 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5776                 .dac_nids = alc882_dac_nids,
5777                 .dig_out_nid = ALC882_DIGOUT_NID,
5778                 .dig_in_nid = ALC882_DIGIN_NID,
5779                 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
5780                 .channel_mode = alc882_sixstack_modes,
5781                 .input_mux = &alc882_capture_source,
5782         },
5783         [ALC882_ARIMA] = {
5784                 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
5785                 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs },
5786                 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5787                 .dac_nids = alc882_dac_nids,
5788                 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
5789                 .channel_mode = alc882_sixstack_modes,
5790                 .input_mux = &alc882_capture_source,
5791         },
5792         [ALC882_W2JC] = {
5793                 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
5794                 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
5795                                 alc880_gpio1_init_verbs },
5796                 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5797                 .dac_nids = alc882_dac_nids,
5798                 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
5799                 .channel_mode = alc880_threestack_modes,
5800                 .need_dac_fix = 1,
5801                 .input_mux = &alc882_capture_source,
5802                 .dig_out_nid = ALC882_DIGOUT_NID,
5803         },
5804         [ALC885_MBP3] = {
5805                 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
5806                 .init_verbs = { alc885_mbp3_init_verbs,
5807                                 alc880_gpio1_init_verbs },
5808                 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5809                 .dac_nids = alc882_dac_nids,
5810                 .channel_mode = alc885_mbp_6ch_modes,
5811                 .num_channel_mode = ARRAY_SIZE(alc885_mbp_6ch_modes),
5812                 .input_mux = &alc882_capture_source,
5813                 .dig_out_nid = ALC882_DIGOUT_NID,
5814                 .dig_in_nid = ALC882_DIGIN_NID,
5815                 .unsol_event = alc885_mbp3_unsol_event,
5816                 .init_hook = alc885_mbp3_automute,
5817         },
5818         [ALC885_MACPRO] = {
5819                 .mixers = { alc882_macpro_mixer },
5820                 .init_verbs = { alc882_macpro_init_verbs },
5821                 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5822                 .dac_nids = alc882_dac_nids,
5823                 .dig_out_nid = ALC882_DIGOUT_NID,
5824                 .dig_in_nid = ALC882_DIGIN_NID,
5825                 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
5826                 .channel_mode = alc882_ch_modes,
5827                 .input_mux = &alc882_capture_source,
5828                 .init_hook = alc885_macpro_init_hook,
5829         },
5830         [ALC885_IMAC24] = {
5831                 .mixers = { alc885_imac24_mixer },
5832                 .init_verbs = { alc885_imac24_init_verbs },
5833                 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5834                 .dac_nids = alc882_dac_nids,
5835                 .dig_out_nid = ALC882_DIGOUT_NID,
5836                 .dig_in_nid = ALC882_DIGIN_NID,
5837                 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
5838                 .channel_mode = alc882_ch_modes,
5839                 .input_mux = &alc882_capture_source,
5840                 .unsol_event = alc885_imac24_unsol_event,
5841                 .init_hook = alc885_imac24_init_hook,
5842         },
5843         [ALC882_TARGA] = {
5844                 .mixers = { alc882_targa_mixer, alc882_chmode_mixer,
5845                             alc882_capture_mixer },
5846                 .init_verbs = { alc882_init_verbs, alc882_targa_verbs},
5847                 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5848                 .dac_nids = alc882_dac_nids,
5849                 .dig_out_nid = ALC882_DIGOUT_NID,
5850                 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
5851                 .adc_nids = alc882_adc_nids,
5852                 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
5853                 .channel_mode = alc882_3ST_6ch_modes,
5854                 .need_dac_fix = 1,
5855                 .input_mux = &alc882_capture_source,
5856                 .unsol_event = alc882_targa_unsol_event,
5857                 .init_hook = alc882_targa_automute,
5858         },
5859         [ALC882_ASUS_A7J] = {
5860                 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer,
5861                             alc882_capture_mixer },
5862                 .init_verbs = { alc882_init_verbs, alc882_asus_a7j_verbs},
5863                 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5864                 .dac_nids = alc882_dac_nids,
5865                 .dig_out_nid = ALC882_DIGOUT_NID,
5866                 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
5867                 .adc_nids = alc882_adc_nids,
5868                 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
5869                 .channel_mode = alc882_3ST_6ch_modes,
5870                 .need_dac_fix = 1,
5871                 .input_mux = &alc882_capture_source,
5872         },      
5873         [ALC882_ASUS_A7M] = {
5874                 .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
5875                 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
5876                                 alc880_gpio1_init_verbs,
5877                                 alc882_asus_a7m_verbs },
5878                 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
5879                 .dac_nids = alc882_dac_nids,
5880                 .dig_out_nid = ALC882_DIGOUT_NID,
5881                 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
5882                 .channel_mode = alc880_threestack_modes,
5883                 .need_dac_fix = 1,
5884                 .input_mux = &alc882_capture_source,
5885         },      
5886 };
5887
5888
5889 /*
5890  * Pin config fixes
5891  */
5892 enum { 
5893         PINFIX_ABIT_AW9D_MAX
5894 };
5895
5896 static struct alc_pincfg alc882_abit_aw9d_pinfix[] = {
5897         { 0x15, 0x01080104 }, /* side */
5898         { 0x16, 0x01011012 }, /* rear */
5899         { 0x17, 0x01016011 }, /* clfe */
5900         { }
5901 };
5902
5903 static const struct alc_pincfg *alc882_pin_fixes[] = {
5904         [PINFIX_ABIT_AW9D_MAX] = alc882_abit_aw9d_pinfix,
5905 };
5906
5907 static struct snd_pci_quirk alc882_pinfix_tbl[] = {
5908         SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
5909         {}
5910 };
5911
5912 /*
5913  * BIOS auto configuration
5914  */
5915 static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
5916                                               hda_nid_t nid, int pin_type,
5917                                               int dac_idx)
5918 {
5919         /* set as output */
5920         struct alc_spec *spec = codec->spec;
5921         int idx;
5922
5923         if (spec->multiout.dac_nids[dac_idx] == 0x25)
5924                 idx = 4;
5925         else
5926                 idx = spec->multiout.dac_nids[dac_idx] - 2;
5927
5928         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5929                             pin_type);
5930         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
5931                             AMP_OUT_UNMUTE);
5932         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
5933
5934 }
5935
5936 static void alc882_auto_init_multi_out(struct hda_codec *codec)
5937 {
5938         struct alc_spec *spec = codec->spec;
5939         int i;
5940
5941         alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
5942         for (i = 0; i <= HDA_SIDE; i++) {
5943                 hda_nid_t nid = spec->autocfg.line_out_pins[i];
5944                 int pin_type = get_pin_type(spec->autocfg.line_out_type);
5945                 if (nid)
5946                         alc882_auto_set_output_and_unmute(codec, nid, pin_type,
5947                                                           i);
5948         }
5949 }
5950
5951 static void alc882_auto_init_hp_out(struct hda_codec *codec)
5952 {
5953         struct alc_spec *spec = codec->spec;
5954         hda_nid_t pin;
5955
5956         pin = spec->autocfg.hp_pins[0];
5957         if (pin) /* connect to front */
5958                 /* use dac 0 */
5959                 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
5960 }
5961
5962 #define alc882_is_input_pin(nid)        alc880_is_input_pin(nid)
5963 #define ALC882_PIN_CD_NID               ALC880_PIN_CD_NID
5964
5965 static void alc882_auto_init_analog_input(struct hda_codec *codec)
5966 {
5967         struct alc_spec *spec = codec->spec;
5968         int i;
5969
5970         for (i = 0; i < AUTO_PIN_LAST; i++) {
5971                 hda_nid_t nid = spec->autocfg.input_pins[i];
5972                 if (alc882_is_input_pin(nid)) {
5973                         snd_hda_codec_write(codec, nid, 0,
5974                                             AC_VERB_SET_PIN_WIDGET_CONTROL,
5975                                             i <= AUTO_PIN_FRONT_MIC ?
5976                                             PIN_VREF80 : PIN_IN);
5977                         if (nid != ALC882_PIN_CD_NID)
5978                                 snd_hda_codec_write(codec, nid, 0,
5979                                                     AC_VERB_SET_AMP_GAIN_MUTE,
5980                                                     AMP_OUT_MUTE);
5981                 }
5982         }
5983 }
5984
5985 /* add mic boosts if needed */
5986 static int alc_auto_add_mic_boost(struct hda_codec *codec)
5987 {
5988         struct alc_spec *spec = codec->spec;
5989         int err;
5990         hda_nid_t nid;
5991
5992         nid = spec->autocfg.input_pins[AUTO_PIN_MIC];
5993         if (nid) {
5994                 err = add_control(spec, ALC_CTL_WIDGET_VOL,
5995                                   "Mic Boost",
5996                                   HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
5997                 if (err < 0)
5998                         return err;
5999         }
6000         nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC];
6001         if (nid) {
6002                 err = add_control(spec, ALC_CTL_WIDGET_VOL,
6003                                   "Front Mic Boost",
6004                                   HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
6005                 if (err < 0)
6006                         return err;
6007         }
6008         return 0;
6009 }
6010
6011 /* almost identical with ALC880 parser... */
6012 static int alc882_parse_auto_config(struct hda_codec *codec)
6013 {
6014         struct alc_spec *spec = codec->spec;
6015         int err = alc880_parse_auto_config(codec);
6016
6017         if (err < 0)
6018                 return err;
6019         else if (!err)
6020                 return 0; /* no config found */
6021
6022         err = alc_auto_add_mic_boost(codec);
6023         if (err < 0)
6024                 return err;
6025
6026         /* hack - override the init verbs */
6027         spec->init_verbs[0] = alc882_auto_init_verbs;
6028
6029         return 1; /* config found */
6030 }
6031
6032 /* additional initialization for auto-configuration model */
6033 static void alc882_auto_init(struct hda_codec *codec)
6034 {
6035         alc882_auto_init_multi_out(codec);
6036         alc882_auto_init_hp_out(codec);
6037         alc882_auto_init_analog_input(codec);
6038 }
6039
6040 static int patch_alc882(struct hda_codec *codec)
6041 {
6042         struct alc_spec *spec;
6043         int err, board_config;
6044
6045         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
6046         if (spec == NULL)
6047                 return -ENOMEM;
6048
6049         codec->spec = spec;
6050
6051         board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
6052                                                   alc882_models,
6053                                                   alc882_cfg_tbl);
6054
6055         if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
6056                 /* Pick up systems that don't supply PCI SSID */
6057                 switch (codec->subsystem_id) {
6058                 case 0x106b0c00: /* Mac Pro */
6059                         board_config = ALC885_MACPRO;
6060                         break;
6061                 case 0x106b1000: /* iMac 24 */
6062                         board_config = ALC885_IMAC24;
6063                         break;
6064                 case 0x106b2c00: /* Macbook Pro rev3 */
6065                         board_config = ALC885_MBP3;
6066                         break;
6067                 default:
6068                         printk(KERN_INFO "hda_codec: Unknown model for ALC882, "
6069                                          "trying auto-probe from BIOS...\n");
6070                         board_config = ALC882_AUTO;
6071                 }
6072         }
6073
6074         alc_fix_pincfg(codec, alc882_pinfix_tbl, alc882_pin_fixes);
6075
6076         if (board_config == ALC882_AUTO) {
6077                 /* automatic parse from the BIOS config */
6078                 err = alc882_parse_auto_config(codec);
6079                 if (err < 0) {
6080                         alc_free(codec);
6081                         return err;
6082                 } else if (!err) {
6083                         printk(KERN_INFO
6084                                "hda_codec: Cannot set up configuration "
6085                                "from BIOS.  Using base mode...\n");
6086                         board_config = ALC882_3ST_DIG;
6087                 }
6088         }
6089
6090         if (board_config != ALC882_AUTO)
6091                 setup_preset(spec, &alc882_presets[board_config]);
6092
6093         spec->stream_name_analog = "ALC882 Analog";
6094         spec->stream_analog_playback = &alc882_pcm_analog_playback;
6095         spec->stream_analog_capture = &alc882_pcm_analog_capture;
6096
6097         spec->stream_name_digital = "ALC882 Digital";
6098         spec->stream_digital_playback = &alc882_pcm_digital_playback;
6099         spec->stream_digital_capture = &alc882_pcm_digital_capture;
6100
6101         if (!spec->adc_nids && spec->input_mux) {
6102                 /* check whether NID 0x07 is valid */
6103                 unsigned int wcap = get_wcaps(codec, 0x07);
6104                 /* get type */
6105                 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
6106                 if (wcap != AC_WID_AUD_IN) {
6107                         spec->adc_nids = alc882_adc_nids_alt;
6108                         spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids_alt);
6109                         spec->mixers[spec->num_mixers] =
6110                                 alc882_capture_alt_mixer;
6111                         spec->num_mixers++;
6112                 } else {
6113                         spec->adc_nids = alc882_adc_nids;
6114                         spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids);
6115                         spec->mixers[spec->num_mixers] = alc882_capture_mixer;
6116                         spec->num_mixers++;
6117                 }
6118         }
6119
6120         codec->patch_ops = alc_patch_ops;
6121         if (board_config == ALC882_AUTO)
6122                 spec->init_hook = alc882_auto_init;
6123 #ifdef CONFIG_SND_HDA_POWER_SAVE
6124         if (!spec->loopback.amplist)
6125                 spec->loopback.amplist = alc882_loopbacks;
6126 #endif
6127
6128         return 0;
6129 }
6130
6131 /*
6132  * ALC883 support
6133  *
6134  * ALC883 is almost identical with ALC880 but has cleaner and more flexible
6135  * configuration.  Each pin widget can choose any input DACs and a mixer.
6136  * Each ADC is connected from a mixer of all inputs.  This makes possible
6137  * 6-channel independent captures.
6138  *
6139  * In addition, an independent DAC for the multi-playback (not used in this
6140  * driver yet).
6141  */
6142 #define ALC883_DIGOUT_NID       0x06
6143 #define ALC883_DIGIN_NID        0x0a
6144
6145 static hda_nid_t alc883_dac_nids[4] = {
6146         /* front, rear, clfe, rear_surr */
6147         0x02, 0x04, 0x03, 0x05
6148 };
6149
6150 static hda_nid_t alc883_adc_nids[2] = {
6151         /* ADC1-2 */
6152         0x08, 0x09,
6153 };
6154
6155 /* input MUX */
6156 /* FIXME: should be a matrix-type input source selection */
6157
6158 static struct hda_input_mux alc883_capture_source = {
6159         .num_items = 4,
6160         .items = {
6161                 { "Mic", 0x0 },
6162                 { "Front Mic", 0x1 },
6163                 { "Line", 0x2 },
6164                 { "CD", 0x4 },
6165         },
6166 };
6167
6168 static struct hda_input_mux alc883_lenovo_101e_capture_source = {
6169         .num_items = 2,
6170         .items = {
6171                 { "Mic", 0x1 },
6172                 { "Line", 0x2 },
6173         },
6174 };
6175
6176 static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
6177         .num_items = 4,
6178         .items = {
6179                 { "Mic", 0x0 },
6180                 { "iMic", 0x1 },
6181                 { "Line", 0x2 },
6182                 { "CD", 0x4 },
6183         },
6184 };
6185
6186 #define alc883_mux_enum_info alc_mux_enum_info
6187 #define alc883_mux_enum_get alc_mux_enum_get
6188
6189 static int alc883_mux_enum_put(struct snd_kcontrol *kcontrol,
6190                                struct snd_ctl_elem_value *ucontrol)
6191 {
6192         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
6193         struct alc_spec *spec = codec->spec;
6194         const struct hda_input_mux *imux = spec->input_mux;
6195         unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
6196         static hda_nid_t capture_mixers[3] = { 0x24, 0x23, 0x22 };
6197         hda_nid_t nid = capture_mixers[adc_idx];
6198         unsigned int *cur_val = &spec->cur_mux[adc_idx];
6199         unsigned int i, idx;
6200
6201         idx = ucontrol->value.enumerated.item[0];
6202         if (idx >= imux->num_items)
6203                 idx = imux->num_items - 1;
6204         if (*cur_val == idx)
6205                 return 0;
6206         for (i = 0; i < imux->num_items; i++) {
6207                 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
6208                 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
6209                                          imux->items[i].index,
6210                                          HDA_AMP_MUTE, v);
6211         }
6212         *cur_val = idx;
6213         return 1;
6214 }
6215
6216 /*
6217  * 2ch mode
6218  */
6219 static struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
6220         { 2, NULL }
6221 };
6222
6223 /*
6224  * 2ch mode
6225  */
6226 static struct hda_verb alc883_3ST_ch2_init[] = {
6227         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6228         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6229         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6230         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6231         { } /* end */
6232 };
6233
6234 /*
6235  * 4ch mode
6236  */
6237 static struct hda_verb alc883_3ST_ch4_init[] = {
6238         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6239         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6240         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6241         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6242         { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6243         { } /* end */
6244 };
6245
6246 /*
6247  * 6ch mode
6248  */
6249 static struct hda_verb alc883_3ST_ch6_init[] = {
6250         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6251         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6252         { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
6253         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6254         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6255         { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6256         { } /* end */
6257 };
6258
6259 static struct hda_channel_mode alc883_3ST_6ch_modes[3] = {
6260         { 2, alc883_3ST_ch2_init },
6261         { 4, alc883_3ST_ch4_init },
6262         { 6, alc883_3ST_ch6_init },
6263 };
6264
6265 /*
6266  * 6ch mode
6267  */
6268 static struct hda_verb alc883_sixstack_ch6_init[] = {
6269         { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
6270         { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6271         { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6272         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6273         { } /* end */
6274 };
6275
6276 /*
6277  * 8ch mode
6278  */
6279 static struct hda_verb alc883_sixstack_ch8_init[] = {
6280         { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6281         { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6282         { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6283         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6284         { } /* end */
6285 };
6286
6287 static struct hda_channel_mode alc883_sixstack_modes[2] = {
6288         { 6, alc883_sixstack_ch6_init },
6289         { 8, alc883_sixstack_ch8_init },
6290 };
6291
6292 static struct hda_verb alc883_medion_eapd_verbs[] = {
6293         /* eanable EAPD on medion laptop */
6294         {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
6295         {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
6296         { }
6297 };
6298
6299 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
6300  *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
6301  */
6302
6303 static struct snd_kcontrol_new alc883_base_mixer[] = {
6304         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6305         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6306         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6307         HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
6308         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6309         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6310         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
6311         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
6312         HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
6313         HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
6314         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6315         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6316         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6317         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6318         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6319         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6320         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6321         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6322         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6323         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6324         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6325         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6326         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6327         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6328         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6329         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6330         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6331         {
6332                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6333                 /* .name = "Capture Source", */
6334                 .name = "Input Source",
6335                 .count = 2,
6336                 .info = alc883_mux_enum_info,
6337                 .get = alc883_mux_enum_get,
6338                 .put = alc883_mux_enum_put,
6339         },
6340         { } /* end */
6341 };
6342
6343 static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
6344         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6345         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6346         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6347         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6348         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6349         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6350         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6351         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6352         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6353         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6354         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6355         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6356         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6357         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6358         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6359         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6360         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6361         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6362         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6363         {
6364                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6365                 /* .name = "Capture Source", */
6366                 .name = "Input Source",
6367                 .count = 2,
6368                 .info = alc883_mux_enum_info,
6369                 .get = alc883_mux_enum_get,
6370                 .put = alc883_mux_enum_put,
6371         },
6372         { } /* end */
6373 };
6374
6375 static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
6376         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6377         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6378         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6379         HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
6380         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6381         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6382         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
6383         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
6384         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6385         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6386         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6387         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6388         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6389         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6390         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6391         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6392         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6393         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6394         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6395         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6396         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6397         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6398         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6399         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6400         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6401         {
6402                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6403                 /* .name = "Capture Source", */
6404                 .name = "Input Source",
6405                 .count = 2,
6406                 .info = alc883_mux_enum_info,
6407                 .get = alc883_mux_enum_get,
6408                 .put = alc883_mux_enum_put,
6409         },
6410         { } /* end */
6411 };
6412
6413 static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
6414         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6415         HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6416         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6417         HDA_CODEC_MUTE("Surround Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6418         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6419         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6420         HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x16, 1, 0x0, HDA_OUTPUT),
6421         HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
6422         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6423         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6424         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6425         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6426         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6427         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6428         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6429         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6430         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6431         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6432         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6433         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6434         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6435         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6436         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6437
6438         {
6439                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6440                 /* .name = "Capture Source", */
6441                 .name = "Input Source",
6442                 .count = 1,
6443                 .info = alc883_mux_enum_info,
6444                 .get = alc883_mux_enum_get,
6445                 .put = alc883_mux_enum_put,
6446         },
6447         { } /* end */
6448 };
6449
6450 static struct snd_kcontrol_new alc883_tagra_mixer[] = {
6451         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6452         HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6453         HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6454         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6455         HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
6456         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
6457         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
6458         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
6459         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
6460         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6461         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6462         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6463         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6464         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6465         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6466         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6467         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6468         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6469         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6470         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6471         {
6472                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6473                 /* .name = "Capture Source", */
6474                 .name = "Input Source",
6475                 .count = 2,
6476                 .info = alc883_mux_enum_info,
6477                 .get = alc883_mux_enum_get,
6478                 .put = alc883_mux_enum_put,
6479         },
6480         { } /* end */
6481 };
6482
6483 static struct snd_kcontrol_new alc883_tagra_2ch_mixer[] = {
6484         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6485         HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6486         HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6487         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6488         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6489         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6490         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6491         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6492         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6493         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6494         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6495         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6496         {
6497                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6498                 /* .name = "Capture Source", */
6499                 .name = "Input Source",
6500                 .count = 2,
6501                 .info = alc883_mux_enum_info,
6502                 .get = alc883_mux_enum_get,
6503                 .put = alc883_mux_enum_put,
6504         },
6505         { } /* end */
6506 };
6507
6508 static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
6509         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6510         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6511         HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
6512         HDA_BIND_MUTE("iSpeaker Playback Switch", 0x0d, 2, HDA_INPUT),
6513         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6514         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6515         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6516         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6517         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6518         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6519         {
6520                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6521                 /* .name = "Capture Source", */
6522                 .name = "Input Source",
6523                 .count = 1,
6524                 .info = alc883_mux_enum_info,
6525                 .get = alc883_mux_enum_get,
6526                 .put = alc883_mux_enum_put,
6527         },
6528         { } /* end */
6529 };
6530
6531 static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
6532         HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6533         HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
6534         HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6535         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6536         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6537         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6538         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6539         HDA_CODEC_VOLUME("iMic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6540         HDA_CODEC_MUTE("iMic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6541         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6542         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6543         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6544         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6545         {
6546                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6547                 /* .name = "Capture Source", */
6548                 .name = "Input Source",
6549                 .count = 2,
6550                 .info = alc883_mux_enum_info,
6551                 .get = alc883_mux_enum_get,
6552                 .put = alc883_mux_enum_put,
6553         },
6554         { } /* end */
6555 };
6556
6557 static struct snd_kcontrol_new alc883_medion_md2_mixer[] = {
6558         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6559         HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6560         HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6561         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6562         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6563         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6564         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6565         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6566         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6567         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6568         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6569         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6570         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6571         {
6572                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6573                 /* .name = "Capture Source", */
6574                 .name = "Input Source",
6575                 .count = 2,
6576                 .info = alc883_mux_enum_info,
6577                 .get = alc883_mux_enum_get,
6578                 .put = alc883_mux_enum_put,
6579         },
6580         { } /* end */
6581 };      
6582
6583 static struct snd_kcontrol_new alc888_6st_hp_mixer[] = {
6584         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6585         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6586         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
6587         HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
6588         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
6589         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
6590         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
6591         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
6592         HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
6593         HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
6594         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6595         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6596         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6597         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6598         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6599         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6600         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6601         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6602         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6603         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6604         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6605         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6606         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6607         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6608         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6609         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6610         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6611         {
6612                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6613                 /* .name = "Capture Source", */
6614                 .name = "Input Source",
6615                 .count = 2,
6616                 .info = alc883_mux_enum_info,
6617                 .get = alc883_mux_enum_get,
6618                 .put = alc883_mux_enum_put,
6619         },
6620         { } /* end */
6621 };
6622
6623 static struct snd_kcontrol_new alc888_3st_hp_mixer[] = {
6624         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6625         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6626         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
6627         HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
6628         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
6629         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
6630         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
6631         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
6632         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
6633         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
6634         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
6635         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6636         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6637         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6638         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6639         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6640         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
6641         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
6642         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6643         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
6644         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
6645         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6646         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6647         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6648         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6649         {
6650                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6651                 /* .name = "Capture Source", */
6652                 .name = "Input Source",
6653                 .count = 2,
6654                 .info = alc883_mux_enum_info,
6655                 .get = alc883_mux_enum_get,
6656                 .put = alc883_mux_enum_put,
6657         },
6658         { } /* end */
6659 };
6660
6661 static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
6662         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
6663         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
6664         HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
6665         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6666         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6667         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
6668         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
6669         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6670         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6671         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6672         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6673         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6674         {
6675                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6676                 /* .name = "Capture Source", */
6677                 .name = "Input Source",
6678                 .count = 2,
6679                 .info = alc883_mux_enum_info,
6680                 .get = alc883_mux_enum_get,
6681                 .put = alc883_mux_enum_put,
6682         },
6683         { } /* end */
6684 };
6685
6686 static struct snd_kcontrol_new alc883_chmode_mixer[] = {
6687         {
6688                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6689                 .name = "Channel Mode",
6690                 .info = alc_ch_mode_info,
6691                 .get = alc_ch_mode_get,
6692                 .put = alc_ch_mode_put,
6693         },
6694         { } /* end */
6695 };
6696
6697 static struct hda_verb alc883_init_verbs[] = {
6698         /* ADC1: mute amp left and right */
6699         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6700         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6701         /* ADC2: mute amp left and right */
6702         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6703         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6704         /* Front mixer: unmute input/output amp left and right (volume = 0) */
6705         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6706         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6707         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6708         /* Rear mixer */
6709         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6710         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6711         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6712         /* CLFE mixer */
6713         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6714         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6715         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6716         /* Side mixer */
6717         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6718         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6719         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6720
6721         /* mute analog input loopbacks */
6722         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6723         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6724         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6725         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6726         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6727
6728         /* Front Pin: output 0 (0x0c) */
6729         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6730         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6731         {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
6732         /* Rear Pin: output 1 (0x0d) */
6733         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6734         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6735         {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
6736         /* CLFE Pin: output 2 (0x0e) */
6737         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6738         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6739         {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
6740         /* Side Pin: output 3 (0x0f) */
6741         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6742         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6743         {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
6744         /* Mic (rear) pin: input vref at 80% */
6745         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6746         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6747         /* Front Mic pin: input vref at 80% */
6748         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6749         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6750         /* Line In pin: input */
6751         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6752         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
6753         /* Line-2 In: Headphone output (output 0 - 0x0c) */
6754         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6755         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6756         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
6757         /* CD pin widget for input */
6758         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6759
6760         /* FIXME: use matrix-type input source selection */
6761         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6762         /* Input mixer2 */
6763         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6764         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6765         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
6766         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
6767         /* Input mixer3 */
6768         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6769         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6770         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
6771         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
6772         { }
6773 };
6774
6775 static struct hda_verb alc883_tagra_verbs[] = {
6776         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6777         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6778
6779         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6780         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6781         
6782         {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
6783         {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
6784         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
6785
6786         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6787         {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
6788         {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
6789         {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
6790
6791         { } /* end */
6792 };
6793
6794 static struct hda_verb alc883_lenovo_101e_verbs[] = {
6795         {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6796         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
6797         {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
6798         { } /* end */
6799 };
6800
6801 static struct hda_verb alc883_lenovo_nb0763_verbs[] = {
6802         {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6803         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6804         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6805         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6806         { } /* end */
6807 };
6808
6809 static struct hda_verb alc888_lenovo_ms7195_verbs[] = {
6810         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6811         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6812         {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
6813         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
6814         {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT    | AC_USRSP_EN},
6815         { } /* end */
6816 };
6817
6818 static struct hda_verb alc883_haier_w66_verbs[] = {
6819         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6820         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6821
6822         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6823
6824         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
6825         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6826         {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6827         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6828         { } /* end */
6829 };
6830
6831 static struct hda_verb alc888_6st_hp_verbs[] = {
6832         {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},  /* Front: output 0 (0x0c) */
6833         {0x15, AC_VERB_SET_CONNECT_SEL, 0x02},  /* Rear : output 2 (0x0e) */
6834         {0x16, AC_VERB_SET_CONNECT_SEL, 0x01},  /* CLFE : output 1 (0x0d) */
6835         {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},  /* Side : output 3 (0x0f) */
6836         { }
6837 };
6838
6839 static struct hda_verb alc888_3st_hp_verbs[] = {
6840         {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},  /* Front: output 0 (0x0c) */
6841         {0x18, AC_VERB_SET_CONNECT_SEL, 0x01},  /* Rear : output 1 (0x0d) */
6842         {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},  /* CLFE : output 2 (0x0e) */
6843         { }
6844 };
6845
6846 static struct hda_verb alc888_3st_hp_2ch_init[] = {
6847         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6848         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6849         { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6850         { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6851         { }
6852 };
6853
6854 static struct hda_verb alc888_3st_hp_6ch_init[] = {
6855         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6856         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6857         { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6858         { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6859         { }
6860 };
6861
6862 static struct hda_channel_mode alc888_3st_hp_modes[2] = {
6863         { 2, alc888_3st_hp_2ch_init },
6864         { 6, alc888_3st_hp_6ch_init },
6865 };
6866
6867 /* toggle front-jack and RCA according to the hp-jack state */
6868 static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec)
6869 {
6870         unsigned int present;
6871  
6872         present = snd_hda_codec_read(codec, 0x1b, 0,
6873                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6874         snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
6875                                  HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6876         snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
6877                                  HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6878 }
6879
6880 /* toggle RCA according to the front-jack state */
6881 static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec)
6882 {
6883         unsigned int present;
6884  
6885         present = snd_hda_codec_read(codec, 0x14, 0,
6886                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6887         snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
6888                                  HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6889 }
6890
6891 static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec,
6892                                              unsigned int res)
6893 {
6894         if ((res >> 26) == ALC880_HP_EVENT)
6895                 alc888_lenovo_ms7195_front_automute(codec);
6896         if ((res >> 26) == ALC880_FRONT_EVENT)
6897                 alc888_lenovo_ms7195_rca_automute(codec);
6898 }
6899
6900 static struct hda_verb alc883_medion_md2_verbs[] = {
6901         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6902         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6903
6904         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6905
6906         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6907         { } /* end */
6908 };
6909
6910 /* toggle speaker-output according to the hp-jack state */
6911 static void alc883_medion_md2_automute(struct hda_codec *codec)
6912 {
6913         unsigned int present;
6914  
6915         present = snd_hda_codec_read(codec, 0x14, 0,
6916                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6917         snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
6918                                  HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
6919 }
6920
6921 static void alc883_medion_md2_unsol_event(struct hda_codec *codec,
6922                                           unsigned int res)
6923 {
6924         if ((res >> 26) == ALC880_HP_EVENT)
6925                 alc883_medion_md2_automute(codec);
6926 }
6927
6928 /* toggle speaker-output according to the hp-jack state */
6929 static void alc883_tagra_automute(struct hda_codec *codec)
6930 {
6931         unsigned int present;
6932         unsigned char bits;
6933
6934         present = snd_hda_codec_read(codec, 0x14, 0,
6935                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6936         bits = present ? HDA_AMP_MUTE : 0;
6937         snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
6938                                  HDA_AMP_MUTE, bits);
6939         snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
6940                                   present ? 1 : 3);
6941 }
6942
6943 static void alc883_tagra_unsol_event(struct hda_codec *codec, unsigned int res)
6944 {
6945         if ((res >> 26) == ALC880_HP_EVENT)
6946                 alc883_tagra_automute(codec);
6947 }
6948
6949 static void alc883_haier_w66_automute(struct hda_codec *codec)
6950 {
6951         unsigned int present;
6952         unsigned char bits;
6953
6954         present = snd_hda_codec_read(codec, 0x1b, 0,
6955                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6956         bits = present ? 0x80 : 0;
6957         snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
6958                                  0x80, bits);
6959 }
6960
6961 static void alc883_haier_w66_unsol_event(struct hda_codec *codec,
6962                                          unsigned int res)
6963 {
6964         if ((res >> 26) == ALC880_HP_EVENT)
6965                 alc883_haier_w66_automute(codec);
6966 }
6967
6968 static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
6969 {
6970         unsigned int present;
6971         unsigned char bits;
6972
6973         present = snd_hda_codec_read(codec, 0x14, 0,
6974                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6975         bits = present ? HDA_AMP_MUTE : 0;
6976         snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
6977                                  HDA_AMP_MUTE, bits);
6978 }
6979
6980 static void alc883_lenovo_101e_all_automute(struct hda_codec *codec)
6981 {
6982         unsigned int present;
6983         unsigned char bits;
6984
6985         present = snd_hda_codec_read(codec, 0x1b, 0,
6986                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
6987         bits = present ? HDA_AMP_MUTE : 0;
6988         snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
6989                                  HDA_AMP_MUTE, bits);
6990         snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
6991                                  HDA_AMP_MUTE, bits);
6992 }
6993
6994 static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec,
6995                                            unsigned int res)
6996 {
6997         if ((res >> 26) == ALC880_HP_EVENT)
6998                 alc883_lenovo_101e_all_automute(codec);
6999         if ((res >> 26) == ALC880_FRONT_EVENT)
7000                 alc883_lenovo_101e_ispeaker_automute(codec);
7001 }
7002
7003 /* toggle speaker-output according to the hp-jack state */
7004 static void alc883_acer_aspire_automute(struct hda_codec *codec)
7005 {
7006         unsigned int present;
7007  
7008         present = snd_hda_codec_read(codec, 0x14, 0,
7009                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7010         snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
7011                                  HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7012         snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
7013                                  HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7014 }
7015
7016 static void alc883_acer_aspire_unsol_event(struct hda_codec *codec,
7017                                            unsigned int res)
7018 {
7019         if ((res >> 26) == ALC880_HP_EVENT)
7020                 alc883_acer_aspire_automute(codec);
7021 }
7022
7023 static struct hda_verb alc883_acer_eapd_verbs[] = {
7024         /* HP Pin: output 0 (0x0c) */
7025         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7026         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7027         {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7028         /* Front Pin: output 0 (0x0c) */
7029         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7030         {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7031         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7032         {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
7033         /* eanable EAPD on medion laptop */
7034         {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
7035         {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
7036         /* enable unsolicited event */
7037         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7038         { }
7039 };
7040
7041 /*
7042  * generic initialization of ADC, input mixers and output mixers
7043  */
7044 static struct hda_verb alc883_auto_init_verbs[] = {
7045         /*
7046          * Unmute ADC0-2 and set the default input to mic-in
7047          */
7048         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7049         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7050         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7051         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7052
7053         /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
7054          * mixer widget
7055          * Note: PASD motherboards uses the Line In 2 as the input for
7056          * front panel mic (mic 2)
7057          */
7058         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
7059         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7060         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7061         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7062         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7063         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7064
7065         /*
7066          * Set up output mixers (0x0c - 0x0f)
7067          */
7068         /* set vol=0 to output mixers */
7069         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7070         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7071         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7072         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7073         /* set up input amps for analog loopback */
7074         /* Amp Indices: DAC = 0, mixer = 1 */
7075         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7076         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7077         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7078         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7079         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7080         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7081         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7082         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7083         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7084         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7085
7086         /* FIXME: use matrix-type input source selection */
7087         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7088         /* Input mixer1 */
7089         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7090         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7091         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7092         /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
7093         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
7094         /* Input mixer2 */
7095         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7096         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7097         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7098         /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
7099         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
7100
7101         { }
7102 };
7103
7104 /* capture mixer elements */
7105 static struct snd_kcontrol_new alc883_capture_mixer[] = {
7106         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7107         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7108         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7109         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7110         {
7111                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7112                 /* The multiple "Capture Source" controls confuse alsamixer
7113                  * So call somewhat different..
7114                  * FIXME: the controls appear in the "playback" view!
7115                  */
7116                 /* .name = "Capture Source", */
7117                 .name = "Input Source",
7118                 .count = 2,
7119                 .info = alc882_mux_enum_info,
7120                 .get = alc882_mux_enum_get,
7121                 .put = alc882_mux_enum_put,
7122         },
7123         { } /* end */
7124 };
7125
7126 #ifdef CONFIG_SND_HDA_POWER_SAVE
7127 #define alc883_loopbacks        alc880_loopbacks
7128 #endif
7129
7130 /* pcm configuration: identiacal with ALC880 */
7131 #define alc883_pcm_analog_playback      alc880_pcm_analog_playback
7132 #define alc883_pcm_analog_capture       alc880_pcm_analog_capture
7133 #define alc883_pcm_digital_playback     alc880_pcm_digital_playback
7134 #define alc883_pcm_digital_capture      alc880_pcm_digital_capture
7135
7136 /*
7137  * configuration and preset
7138  */
7139 static const char *alc883_models[ALC883_MODEL_LAST] = {
7140         [ALC883_3ST_2ch_DIG]    = "3stack-dig",
7141         [ALC883_3ST_6ch_DIG]    = "3stack-6ch-dig",
7142         [ALC883_3ST_6ch]        = "3stack-6ch",
7143         [ALC883_6ST_DIG]        = "6stack-dig",
7144         [ALC883_TARGA_DIG]      = "targa-dig",
7145         [ALC883_TARGA_2ch_DIG]  = "targa-2ch-dig",
7146         [ALC883_ACER]           = "acer",
7147         [ALC883_ACER_ASPIRE]    = "acer-aspire",
7148         [ALC883_MEDION]         = "medion",
7149         [ALC883_MEDION_MD2]     = "medion-md2",
7150         [ALC883_LAPTOP_EAPD]    = "laptop-eapd",
7151         [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
7152         [ALC883_LENOVO_NB0763]  = "lenovo-nb0763",
7153         [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
7154         [ALC883_HAIER_W66]      = "haier-w66",
7155         [ALC888_6ST_HP]         = "6stack-hp",
7156         [ALC888_3ST_HP]         = "3stack-hp",
7157         [ALC883_AUTO]           = "auto",
7158 };
7159
7160 static struct snd_pci_quirk alc883_cfg_tbl[] = {
7161         SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC883_3ST_6ch_DIG),
7162         SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
7163         SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
7164         SND_PCI_QUIRK(0x1558, 0, "Clevo laptop", ALC883_LAPTOP_EAPD),
7165         SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC883_6ST_DIG),
7166         SND_PCI_QUIRK(0x1458, 0xa002, "MSI", ALC883_6ST_DIG),
7167         SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
7168         SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
7169         SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
7170         SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
7171         SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
7172         SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
7173         SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
7174         SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
7175         SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
7176         SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
7177         SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
7178         SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
7179         SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
7180         SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
7181         SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
7182         SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
7183         SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
7184         SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
7185         SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
7186         SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
7187         SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
7188         SND_PCI_QUIRK(0x1025, 0, "Acer laptop", ALC883_ACER),
7189         SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
7190         SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
7191         SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
7192         SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch),
7193         SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
7194         SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
7195         SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
7196         SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC888_6ST_HP),
7197         SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
7198         SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
7199         SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2),
7200         SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
7201         SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
7202         SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
7203         SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
7204         {}
7205 };
7206
7207 static struct alc_config_preset alc883_presets[] = {
7208         [ALC883_3ST_2ch_DIG] = {
7209                 .mixers = { alc883_3ST_2ch_mixer },
7210                 .init_verbs = { alc883_init_verbs },
7211                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7212                 .dac_nids = alc883_dac_nids,
7213                 .dig_out_nid = ALC883_DIGOUT_NID,
7214                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7215                 .adc_nids = alc883_adc_nids,
7216                 .dig_in_nid = ALC883_DIGIN_NID,
7217                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7218                 .channel_mode = alc883_3ST_2ch_modes,
7219                 .input_mux = &alc883_capture_source,
7220         },
7221         [ALC883_3ST_6ch_DIG] = {
7222                 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
7223                 .init_verbs = { alc883_init_verbs },
7224                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7225                 .dac_nids = alc883_dac_nids,
7226                 .dig_out_nid = ALC883_DIGOUT_NID,
7227                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7228                 .adc_nids = alc883_adc_nids,
7229                 .dig_in_nid = ALC883_DIGIN_NID,
7230                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
7231                 .channel_mode = alc883_3ST_6ch_modes,
7232                 .need_dac_fix = 1,
7233                 .input_mux = &alc883_capture_source,
7234         },
7235         [ALC883_3ST_6ch] = {
7236                 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
7237                 .init_verbs = { alc883_init_verbs },
7238                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7239                 .dac_nids = alc883_dac_nids,
7240                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7241                 .adc_nids = alc883_adc_nids,
7242                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
7243                 .channel_mode = alc883_3ST_6ch_modes,
7244                 .need_dac_fix = 1,
7245                 .input_mux = &alc883_capture_source,
7246         },
7247         [ALC883_6ST_DIG] = {
7248                 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
7249                 .init_verbs = { alc883_init_verbs },
7250                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7251                 .dac_nids = alc883_dac_nids,
7252                 .dig_out_nid = ALC883_DIGOUT_NID,
7253                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7254                 .adc_nids = alc883_adc_nids,
7255                 .dig_in_nid = ALC883_DIGIN_NID,
7256                 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
7257                 .channel_mode = alc883_sixstack_modes,
7258                 .input_mux = &alc883_capture_source,
7259         },
7260         [ALC883_TARGA_DIG] = {
7261                 .mixers = { alc883_tagra_mixer, alc883_chmode_mixer },
7262                 .init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
7263                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7264                 .dac_nids = alc883_dac_nids,
7265                 .dig_out_nid = ALC883_DIGOUT_NID,
7266                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7267                 .adc_nids = alc883_adc_nids,
7268                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
7269                 .channel_mode = alc883_3ST_6ch_modes,
7270                 .need_dac_fix = 1,
7271                 .input_mux = &alc883_capture_source,
7272                 .unsol_event = alc883_tagra_unsol_event,
7273                 .init_hook = alc883_tagra_automute,
7274         },
7275         [ALC883_TARGA_2ch_DIG] = {
7276                 .mixers = { alc883_tagra_2ch_mixer},
7277                 .init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
7278                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7279                 .dac_nids = alc883_dac_nids,
7280                 .dig_out_nid = ALC883_DIGOUT_NID,
7281                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7282                 .adc_nids = alc883_adc_nids,
7283                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7284                 .channel_mode = alc883_3ST_2ch_modes,
7285                 .input_mux = &alc883_capture_source,
7286                 .unsol_event = alc883_tagra_unsol_event,
7287                 .init_hook = alc883_tagra_automute,
7288         },
7289         [ALC883_ACER] = {
7290                 .mixers = { alc883_base_mixer },
7291                 /* On TravelMate laptops, GPIO 0 enables the internal speaker
7292                  * and the headphone jack.  Turn this on and rely on the
7293                  * standard mute methods whenever the user wants to turn
7294                  * these outputs off.
7295                  */
7296                 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
7297                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7298                 .dac_nids = alc883_dac_nids,
7299                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7300                 .adc_nids = alc883_adc_nids,
7301                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7302                 .channel_mode = alc883_3ST_2ch_modes,
7303                 .input_mux = &alc883_capture_source,
7304         },
7305         [ALC883_ACER_ASPIRE] = {
7306                 .mixers = { alc883_acer_aspire_mixer },
7307                 .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
7308                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7309                 .dac_nids = alc883_dac_nids,
7310                 .dig_out_nid = ALC883_DIGOUT_NID,
7311                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7312                 .adc_nids = alc883_adc_nids,
7313                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7314                 .channel_mode = alc883_3ST_2ch_modes,
7315                 .input_mux = &alc883_capture_source,
7316                 .unsol_event = alc883_acer_aspire_unsol_event,
7317                 .init_hook = alc883_acer_aspire_automute,
7318         },
7319         [ALC883_MEDION] = {
7320                 .mixers = { alc883_fivestack_mixer,
7321                             alc883_chmode_mixer },
7322                 .init_verbs = { alc883_init_verbs,
7323                                 alc883_medion_eapd_verbs },
7324                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7325                 .dac_nids = alc883_dac_nids,
7326                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7327                 .adc_nids = alc883_adc_nids,
7328                 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
7329                 .channel_mode = alc883_sixstack_modes,
7330                 .input_mux = &alc883_capture_source,
7331         },
7332         [ALC883_MEDION_MD2] = {
7333                 .mixers = { alc883_medion_md2_mixer},
7334                 .init_verbs = { alc883_init_verbs, alc883_medion_md2_verbs},
7335                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7336                 .dac_nids = alc883_dac_nids,
7337                 .dig_out_nid = ALC883_DIGOUT_NID,
7338                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7339                 .adc_nids = alc883_adc_nids,
7340                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7341                 .channel_mode = alc883_3ST_2ch_modes,
7342                 .input_mux = &alc883_capture_source,
7343                 .unsol_event = alc883_medion_md2_unsol_event,
7344                 .init_hook = alc883_medion_md2_automute,
7345         },      
7346         [ALC883_LAPTOP_EAPD] = {
7347                 .mixers = { alc883_base_mixer },
7348                 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
7349                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7350                 .dac_nids = alc883_dac_nids,
7351                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7352                 .adc_nids = alc883_adc_nids,
7353                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7354                 .channel_mode = alc883_3ST_2ch_modes,
7355                 .input_mux = &alc883_capture_source,
7356         },
7357         [ALC883_LENOVO_101E_2ch] = {
7358                 .mixers = { alc883_lenovo_101e_2ch_mixer},
7359                 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
7360                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7361                 .dac_nids = alc883_dac_nids,
7362                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7363                 .adc_nids = alc883_adc_nids,
7364                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7365                 .channel_mode = alc883_3ST_2ch_modes,
7366                 .input_mux = &alc883_lenovo_101e_capture_source,
7367                 .unsol_event = alc883_lenovo_101e_unsol_event,
7368                 .init_hook = alc883_lenovo_101e_all_automute,
7369         },
7370         [ALC883_LENOVO_NB0763] = {
7371                 .mixers = { alc883_lenovo_nb0763_mixer },
7372                 .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
7373                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7374                 .dac_nids = alc883_dac_nids,
7375                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7376                 .adc_nids = alc883_adc_nids,
7377                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7378                 .channel_mode = alc883_3ST_2ch_modes,
7379                 .need_dac_fix = 1,
7380                 .input_mux = &alc883_lenovo_nb0763_capture_source,
7381                 .unsol_event = alc883_medion_md2_unsol_event,
7382                 .init_hook = alc883_medion_md2_automute,
7383         },
7384         [ALC888_LENOVO_MS7195_DIG] = {
7385                 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
7386                 .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
7387                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7388                 .dac_nids = alc883_dac_nids,
7389                 .dig_out_nid = ALC883_DIGOUT_NID,
7390                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7391                 .adc_nids = alc883_adc_nids,
7392                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
7393                 .channel_mode = alc883_3ST_6ch_modes,
7394                 .need_dac_fix = 1,
7395                 .input_mux = &alc883_capture_source,
7396                 .unsol_event = alc883_lenovo_ms7195_unsol_event,
7397                 .init_hook = alc888_lenovo_ms7195_front_automute,
7398         },
7399         [ALC883_HAIER_W66] = {
7400                 .mixers = { alc883_tagra_2ch_mixer},
7401                 .init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs},
7402                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7403                 .dac_nids = alc883_dac_nids,
7404                 .dig_out_nid = ALC883_DIGOUT_NID,
7405                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7406                 .adc_nids = alc883_adc_nids,
7407                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7408                 .channel_mode = alc883_3ST_2ch_modes,
7409                 .input_mux = &alc883_capture_source,
7410                 .unsol_event = alc883_haier_w66_unsol_event,
7411                 .init_hook = alc883_haier_w66_automute,
7412         },      
7413         [ALC888_6ST_HP] = {
7414                 .mixers = { alc888_6st_hp_mixer, alc883_chmode_mixer },
7415                 .init_verbs = { alc883_init_verbs, alc888_6st_hp_verbs },
7416                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7417                 .dac_nids = alc883_dac_nids,
7418                 .dig_out_nid = ALC883_DIGOUT_NID,
7419                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7420                 .adc_nids = alc883_adc_nids,
7421                 .dig_in_nid = ALC883_DIGIN_NID,
7422                 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
7423                 .channel_mode = alc883_sixstack_modes,
7424                 .input_mux = &alc883_capture_source,
7425         },
7426         [ALC888_3ST_HP] = {
7427                 .mixers = { alc888_3st_hp_mixer, alc883_chmode_mixer },
7428                 .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
7429                 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
7430                 .dac_nids = alc883_dac_nids,
7431                 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
7432                 .adc_nids = alc883_adc_nids,
7433                 .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
7434                 .channel_mode = alc888_3st_hp_modes,
7435                 .need_dac_fix = 1,
7436                 .input_mux = &alc883_capture_source,
7437         },
7438 };
7439
7440
7441 /*
7442  * BIOS auto configuration
7443  */
7444 static void alc883_auto_set_output_and_unmute(struct hda_codec *codec,
7445                                               hda_nid_t nid, int pin_type,
7446                                               int dac_idx)
7447 {
7448         /* set as output */
7449         struct alc_spec *spec = codec->spec;
7450         int idx;
7451
7452         if (spec->multiout.dac_nids[dac_idx] == 0x25)
7453                 idx = 4;
7454         else
7455                 idx = spec->multiout.dac_nids[dac_idx] - 2;
7456
7457         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
7458                             pin_type);
7459         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
7460                             AMP_OUT_UNMUTE);
7461         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
7462
7463 }
7464
7465 static void alc883_auto_init_multi_out(struct hda_codec *codec)
7466 {
7467         struct alc_spec *spec = codec->spec;
7468         int i;
7469
7470         alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
7471         for (i = 0; i <= HDA_SIDE; i++) {
7472                 hda_nid_t nid = spec->autocfg.line_out_pins[i];
7473                 int pin_type = get_pin_type(spec->autocfg.line_out_type);
7474                 if (nid)
7475                         alc883_auto_set_output_and_unmute(codec, nid, pin_type,
7476                                                           i);
7477         }
7478 }
7479
7480 static void alc883_auto_init_hp_out(struct hda_codec *codec)
7481 {
7482         struct alc_spec *spec = codec->spec;
7483         hda_nid_t pin;
7484
7485         pin = spec->autocfg.hp_pins[0];
7486         if (pin) /* connect to front */
7487                 /* use dac 0 */
7488                 alc883_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
7489 }
7490
7491 #define alc883_is_input_pin(nid)        alc880_is_input_pin(nid)
7492 #define ALC883_PIN_CD_NID               ALC880_PIN_CD_NID
7493
7494 static void alc883_auto_init_analog_input(struct hda_codec *codec)
7495 {
7496         struct alc_spec *spec = codec->spec;
7497         int i;
7498
7499         for (i = 0; i < AUTO_PIN_LAST; i++) {
7500                 hda_nid_t nid = spec->autocfg.input_pins[i];
7501                 if (alc883_is_input_pin(nid)) {
7502                         snd_hda_codec_write(codec, nid, 0,
7503                                             AC_VERB_SET_PIN_WIDGET_CONTROL,
7504                                             (i <= AUTO_PIN_FRONT_MIC ?
7505                                              PIN_VREF80 : PIN_IN));
7506                         if (nid != ALC883_PIN_CD_NID)
7507                                 snd_hda_codec_write(codec, nid, 0,
7508                                                     AC_VERB_SET_AMP_GAIN_MUTE,
7509                                                     AMP_OUT_MUTE);
7510                 }
7511         }
7512 }
7513
7514 /* almost identical with ALC880 parser... */
7515 static int alc883_parse_auto_config(struct hda_codec *codec)
7516 {
7517         struct alc_spec *spec = codec->spec;
7518         int err = alc880_parse_auto_config(codec);
7519
7520         if (err < 0)
7521                 return err;
7522         else if (!err)
7523                 return 0; /* no config found */
7524
7525         err = alc_auto_add_mic_boost(codec);
7526         if (err < 0)
7527                 return err;
7528
7529         /* hack - override the init verbs */
7530         spec->init_verbs[0] = alc883_auto_init_verbs;
7531         spec->mixers[spec->num_mixers] = alc883_capture_mixer;
7532         spec->num_mixers++;
7533
7534         return 1; /* config found */
7535 }
7536
7537 /* additional initialization for auto-configuration model */
7538 static void alc883_auto_init(struct hda_codec *codec)
7539 {
7540         alc883_auto_init_multi_out(codec);
7541         alc883_auto_init_hp_out(codec);
7542         alc883_auto_init_analog_input(codec);
7543 }
7544
7545 static int patch_alc883(struct hda_codec *codec)
7546 {
7547         struct alc_spec *spec;
7548         int err, board_config;
7549
7550         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
7551         if (spec == NULL)
7552                 return -ENOMEM;
7553
7554         codec->spec = spec;
7555
7556         board_config = snd_hda_check_board_config(codec, ALC883_MODEL_LAST,
7557                                                   alc883_models,
7558                                                   alc883_cfg_tbl);
7559         if (board_config < 0) {
7560                 printk(KERN_INFO "hda_codec: Unknown model for ALC883, "
7561                        "trying auto-probe from BIOS...\n");
7562                 board_config = ALC883_AUTO;
7563         }
7564
7565         if (board_config == ALC883_AUTO) {
7566                 /* automatic parse from the BIOS config */
7567                 err = alc883_parse_auto_config(codec);
7568                 if (err < 0) {
7569                         alc_free(codec);
7570                         return err;
7571                 } else if (!err) {
7572                         printk(KERN_INFO
7573                                "hda_codec: Cannot set up configuration "
7574                                "from BIOS.  Using base mode...\n");
7575                         board_config = ALC883_3ST_2ch_DIG;
7576                 }
7577         }
7578
7579         if (board_config != ALC883_AUTO)
7580                 setup_preset(spec, &alc883_presets[board_config]);
7581
7582         spec->stream_name_analog = "ALC883 Analog";
7583         spec->stream_analog_playback = &alc883_pcm_analog_playback;
7584         spec->stream_analog_capture = &alc883_pcm_analog_capture;
7585
7586         spec->stream_name_digital = "ALC883 Digital";
7587         spec->stream_digital_playback = &alc883_pcm_digital_playback;
7588         spec->stream_digital_capture = &alc883_pcm_digital_capture;
7589
7590         if (!spec->adc_nids && spec->input_mux) {
7591                 spec->adc_nids = alc883_adc_nids;
7592                 spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids);
7593         }
7594
7595         codec->patch_ops = alc_patch_ops;
7596         if (board_config == ALC883_AUTO)
7597                 spec->init_hook = alc883_auto_init;
7598 #ifdef CONFIG_SND_HDA_POWER_SAVE
7599         if (!spec->loopback.amplist)
7600                 spec->loopback.amplist = alc883_loopbacks;
7601 #endif
7602
7603         return 0;
7604 }
7605
7606 /*
7607  * ALC262 support
7608  */
7609
7610 #define ALC262_DIGOUT_NID       ALC880_DIGOUT_NID
7611 #define ALC262_DIGIN_NID        ALC880_DIGIN_NID
7612
7613 #define alc262_dac_nids         alc260_dac_nids
7614 #define alc262_adc_nids         alc882_adc_nids
7615 #define alc262_adc_nids_alt     alc882_adc_nids_alt
7616
7617 #define alc262_modes            alc260_modes
7618 #define alc262_capture_source   alc882_capture_source
7619
7620 static struct snd_kcontrol_new alc262_base_mixer[] = {
7621         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7622         HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7623         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7624         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7625         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7626         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7627         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7628         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7629         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7630         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7631         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
7632         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7633         /* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
7634            HDA_CODEC_MUTE("PC Beelp Playback Switch", 0x0b, 0x05, HDA_INPUT), */
7635         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
7636         HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7637         HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7638         HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
7639         { } /* end */
7640 };
7641
7642 static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
7643         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7644         HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7645         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7646         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7647         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7648         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7649         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7650         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7651         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7652         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7653         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
7654         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7655         /* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
7656            HDA_CODEC_MUTE("PC Beelp Playback Switch", 0x0b, 0x05, HDA_INPUT), */
7657         /*HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),*/
7658         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7659         { } /* end */
7660 };
7661
7662 static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
7663         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7664         HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7665         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7666         HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7667         HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
7668
7669         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7670         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7671         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7672         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7673         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
7674         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7675         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7676         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7677         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7678         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7679         HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
7680         HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT),
7681         HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
7682         HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
7683         { } /* end */
7684 };
7685
7686 static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
7687         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7688         HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7689         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7690         HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7691         HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7692         HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
7693         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
7694         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
7695         HDA_CODEC_VOLUME("Front Mic Boost", 0x1a, 0, HDA_INPUT),
7696         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
7697         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
7698         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7699         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7700         HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
7701         HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT),
7702         { } /* end */
7703 };
7704
7705 static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
7706         HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7707         HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7708         HDA_CODEC_VOLUME("Rear Mic Boost", 0x18, 0, HDA_INPUT),
7709         { } /* end */
7710 };
7711
7712 /* bind hp and internal speaker mute (with plug check) */
7713 static int alc262_sony_master_sw_put(struct snd_kcontrol *kcontrol,
7714                                      struct snd_ctl_elem_value *ucontrol)
7715 {
7716         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
7717         long *valp = ucontrol->value.integer.value;
7718         int change;
7719
7720         /* change hp mute */
7721         change = snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
7722                                           HDA_AMP_MUTE,
7723                                           valp[0] ? 0 : HDA_AMP_MUTE);
7724         change |= snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
7725                                            HDA_AMP_MUTE,
7726                                            valp[1] ? 0 : HDA_AMP_MUTE);
7727         if (change) {
7728                 /* change speaker according to HP jack state */
7729                 struct alc_spec *spec = codec->spec;
7730                 unsigned int mute;
7731                 if (spec->jack_present)
7732                         mute = HDA_AMP_MUTE;
7733                 else
7734                         mute = snd_hda_codec_amp_read(codec, 0x15, 0,
7735                                                       HDA_OUTPUT, 0);
7736                 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7737                                          HDA_AMP_MUTE, mute);
7738         }
7739         return change;
7740 }
7741
7742 static struct snd_kcontrol_new alc262_sony_mixer[] = {
7743         HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7744         {
7745                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7746                 .name = "Master Playback Switch",
7747                 .info = snd_hda_mixer_amp_switch_info,
7748                 .get = snd_hda_mixer_amp_switch_get,
7749                 .put = alc262_sony_master_sw_put,
7750                 .private_value = HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
7751         },
7752         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7753         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7754         HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7755         HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
7756         { } /* end */
7757 };
7758
7759 static struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
7760         HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7761         HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
7762         HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7763         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7764         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7765         HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7766         HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
7767         { } /* end */
7768 };
7769
7770 #define alc262_capture_mixer            alc882_capture_mixer
7771 #define alc262_capture_alt_mixer        alc882_capture_alt_mixer
7772
7773 /*
7774  * generic initialization of ADC, input mixers and output mixers
7775  */
7776 static struct hda_verb alc262_init_verbs[] = {
7777         /*
7778          * Unmute ADC0-2 and set the default input to mic-in
7779          */
7780         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
7781         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7782         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7783         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7784         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
7785         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7786
7787         /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
7788          * mixer widget
7789          * Note: PASD motherboards uses the Line In 2 as the input for
7790          * front panel mic (mic 2)
7791          */
7792         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
7793         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7794         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7795         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7796         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7797         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7798
7799         /*
7800          * Set up output mixers (0x0c - 0x0e)
7801          */
7802         /* set vol=0 to output mixers */
7803         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7804         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7805         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7806         /* set up input amps for analog loopback */
7807         /* Amp Indices: DAC = 0, mixer = 1 */
7808         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7809         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7810         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7811         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7812         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7813         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7814
7815         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
7816         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
7817         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
7818         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
7819         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
7820         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
7821
7822         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
7823         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
7824         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
7825         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
7826         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
7827         
7828         {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7829         {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7830         
7831         /* FIXME: use matrix-type input source selection */
7832         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7833         /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7834         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7835         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
7836         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
7837         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
7838         /* Input mixer2 */
7839         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7840         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
7841         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
7842         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
7843         /* Input mixer3 */
7844         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7845         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
7846         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
7847         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
7848
7849         { }
7850 };
7851
7852 static struct hda_verb alc262_hippo_unsol_verbs[] = {
7853         {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
7854         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7855         {}
7856 };
7857
7858 static struct hda_verb alc262_hippo1_unsol_verbs[] = {
7859         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
7860         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
7861         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
7862
7863         {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
7864         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7865         {}
7866 };
7867
7868 static struct hda_verb alc262_sony_unsol_verbs[] = {
7869         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
7870         {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7871         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},   // Front Mic
7872
7873         {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
7874         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7875 };
7876
7877 /* mute/unmute internal speaker according to the hp jack and mute state */
7878 static void alc262_hippo_automute(struct hda_codec *codec)
7879 {
7880         struct alc_spec *spec = codec->spec;
7881         unsigned int mute;
7882         unsigned int present;
7883
7884         /* need to execute and sync at first */
7885         snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
7886         present = snd_hda_codec_read(codec, 0x15, 0,
7887                                      AC_VERB_GET_PIN_SENSE, 0);
7888         spec->jack_present = (present & 0x80000000) != 0;
7889         if (spec->jack_present) {
7890                 /* mute internal speaker */
7891                 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7892                                          HDA_AMP_MUTE, HDA_AMP_MUTE);
7893         } else {
7894                 /* unmute internal speaker if necessary */
7895                 mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
7896                 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7897                                          HDA_AMP_MUTE, mute);
7898         }
7899 }
7900
7901 /* unsolicited event for HP jack sensing */
7902 static void alc262_hippo_unsol_event(struct hda_codec *codec,
7903                                        unsigned int res)
7904 {
7905         if ((res >> 26) != ALC880_HP_EVENT)
7906                 return;
7907         alc262_hippo_automute(codec);
7908 }
7909
7910 static void alc262_hippo1_automute(struct hda_codec *codec)
7911 {
7912         unsigned int mute;
7913         unsigned int present;
7914
7915         snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
7916         present = snd_hda_codec_read(codec, 0x1b, 0,
7917                                      AC_VERB_GET_PIN_SENSE, 0);
7918         present = (present & 0x80000000) != 0;
7919         if (present) {
7920                 /* mute internal speaker */
7921                 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7922                                          HDA_AMP_MUTE, HDA_AMP_MUTE);
7923         } else {
7924                 /* unmute internal speaker if necessary */
7925                 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
7926                 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
7927                                          HDA_AMP_MUTE, mute);
7928         }
7929 }
7930
7931 /* unsolicited event for HP jack sensing */
7932 static void alc262_hippo1_unsol_event(struct hda_codec *codec,
7933                                        unsigned int res)
7934 {
7935         if ((res >> 26) != ALC880_HP_EVENT)
7936                 return;
7937         alc262_hippo1_automute(codec);
7938 }
7939
7940 /*
7941  * fujitsu model
7942  *  0x14 = headphone/spdif-out, 0x15 = internal speaker
7943  */
7944
7945 #define ALC_HP_EVENT    0x37
7946
7947 static struct hda_verb alc262_fujitsu_unsol_verbs[] = {
7948         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
7949         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7950         {}
7951 };
7952
7953 static struct hda_input_mux alc262_fujitsu_capture_source = {
7954         .num_items = 3,
7955         .items = {
7956                 { "Mic", 0x0 },
7957                 { "Int Mic", 0x1 },
7958                 { "CD", 0x4 },
7959         },
7960 };
7961
7962 static struct hda_input_mux alc262_HP_capture_source = {
7963         .num_items = 5,
7964         .items = {
7965                 { "Mic", 0x0 },
7966                 { "Front Mic", 0x1 },
7967                 { "Line", 0x2 },
7968                 { "CD", 0x4 },
7969                 { "AUX IN", 0x6 },
7970         },
7971 };
7972
7973 static struct hda_input_mux alc262_HP_D7000_capture_source = {
7974         .num_items = 4,
7975         .items = {
7976                 { "Mic", 0x0 },
7977                 { "Front Mic", 0x2 },
7978                 { "Line", 0x1 },
7979                 { "CD", 0x4 },
7980         },
7981 };
7982
7983 /* mute/unmute internal speaker according to the hp jack and mute state */
7984 static void alc262_fujitsu_automute(struct hda_codec *codec, int force)
7985 {
7986         struct alc_spec *spec = codec->spec;
7987         unsigned int mute;
7988
7989         if (force || !spec->sense_updated) {
7990                 unsigned int present;
7991                 /* need to execute and sync at first */
7992                 snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
7993                 present = snd_hda_codec_read(codec, 0x14, 0,
7994                                          AC_VERB_GET_PIN_SENSE, 0);
7995                 spec->jack_present = (present & 0x80000000) != 0;
7996                 spec->sense_updated = 1;
7997         }
7998         if (spec->jack_present) {
7999                 /* mute internal speaker */
8000                 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8001                                          HDA_AMP_MUTE, HDA_AMP_MUTE);
8002         } else {
8003                 /* unmute internal speaker if necessary */
8004                 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
8005                 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8006                                          HDA_AMP_MUTE, mute);
8007         }
8008 }
8009
8010 /* unsolicited event for HP jack sensing */
8011 static void alc262_fujitsu_unsol_event(struct hda_codec *codec,
8012                                        unsigned int res)
8013 {
8014         if ((res >> 26) != ALC_HP_EVENT)
8015                 return;
8016         alc262_fujitsu_automute(codec, 1);
8017 }
8018
8019 /* bind volumes of both NID 0x0c and 0x0d */
8020 static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
8021         .ops = &snd_hda_bind_vol,
8022         .values = {
8023                 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
8024                 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
8025                 0
8026         },
8027 };
8028
8029 /* bind hp and internal speaker mute (with plug check) */
8030 static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol,
8031                                          struct snd_ctl_elem_value *ucontrol)
8032 {
8033         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
8034         long *valp = ucontrol->value.integer.value;
8035         int change;
8036
8037         change = snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
8038                                           HDA_AMP_MUTE,
8039                                           valp[0] ? 0 : HDA_AMP_MUTE);
8040         change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
8041                                            HDA_AMP_MUTE,
8042                                            valp[1] ? 0 : HDA_AMP_MUTE);
8043         if (change)
8044                 alc262_fujitsu_automute(codec, 0);
8045         return change;
8046 }
8047
8048 static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
8049         HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
8050         {
8051                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8052                 .name = "Master Playback Switch",
8053                 .info = snd_hda_mixer_amp_switch_info,
8054                 .get = snd_hda_mixer_amp_switch_get,
8055                 .put = alc262_fujitsu_master_sw_put,
8056                 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
8057         },
8058         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8059         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8060         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8061         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8062         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8063         HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
8064         HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8065         HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8066         { } /* end */
8067 };
8068
8069 /* additional init verbs for Benq laptops */
8070 static struct hda_verb alc262_EAPD_verbs[] = {
8071         {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8072         {0x20, AC_VERB_SET_PROC_COEF,  0x3070},
8073         {}
8074 };
8075
8076 static struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
8077         {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8078         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8079
8080         {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8081         {0x20, AC_VERB_SET_PROC_COEF,  0x3050},
8082         {}
8083 };
8084
8085 /* add playback controls from the parsed DAC table */
8086 static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
8087                                              const struct auto_pin_cfg *cfg)
8088 {
8089         hda_nid_t nid;
8090         int err;
8091
8092         spec->multiout.num_dacs = 1;    /* only use one dac */
8093         spec->multiout.dac_nids = spec->private_dac_nids;
8094         spec->multiout.dac_nids[0] = 2;
8095
8096         nid = cfg->line_out_pins[0];
8097         if (nid) {
8098                 err = add_control(spec, ALC_CTL_WIDGET_VOL,
8099                                   "Front Playback Volume",
8100                                   HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT));
8101                 if (err < 0)
8102                         return err;
8103                 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
8104                                   "Front Playback Switch",
8105                                   HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
8106                 if (err < 0)
8107                         return err;
8108         }
8109
8110         nid = cfg->speaker_pins[0];
8111         if (nid) {
8112                 if (nid == 0x16) {
8113                         err = add_control(spec, ALC_CTL_WIDGET_VOL,
8114                                           "Speaker Playback Volume",
8115                                           HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
8116                                                               HDA_OUTPUT));
8117                         if (err < 0)
8118                                 return err;
8119                         err = add_control(spec, ALC_CTL_WIDGET_MUTE,
8120                                           "Speaker Playback Switch",
8121                                           HDA_COMPOSE_AMP_VAL(nid, 2, 0,
8122                                                               HDA_OUTPUT));
8123                         if (err < 0)
8124                                 return err;
8125                 } else {
8126                         err = add_control(spec, ALC_CTL_WIDGET_MUTE,
8127                                           "Speaker Playback Switch",
8128                                           HDA_COMPOSE_AMP_VAL(nid, 3, 0,
8129                                                               HDA_OUTPUT));
8130                         if (err < 0)
8131                                 return err;
8132                 }
8133         }
8134         nid = cfg->hp_pins[0];
8135         if (nid) {
8136                 /* spec->multiout.hp_nid = 2; */
8137                 if (nid == 0x16) {
8138                         err = add_control(spec, ALC_CTL_WIDGET_VOL,
8139                                           "Headphone Playback Volume",
8140                                           HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
8141                                                               HDA_OUTPUT));
8142                         if (err < 0)
8143                                 return err;
8144                         err = add_control(spec, ALC_CTL_WIDGET_MUTE,
8145                                           "Headphone Playback Switch",
8146                                           HDA_COMPOSE_AMP_VAL(nid, 2, 0,
8147                                                               HDA_OUTPUT));
8148                         if (err < 0)
8149                                 return err;
8150                 } else {
8151                         err = add_control(spec, ALC_CTL_WIDGET_MUTE,
8152                                           "Headphone Playback Switch",
8153                                           HDA_COMPOSE_AMP_VAL(nid, 3, 0,
8154                                                               HDA_OUTPUT));
8155                         if (err < 0)
8156                                 return err;
8157                 }
8158         }
8159         return 0;
8160 }
8161
8162 /* identical with ALC880 */
8163 #define alc262_auto_create_analog_input_ctls \
8164         alc880_auto_create_analog_input_ctls
8165
8166 /*
8167  * generic initialization of ADC, input mixers and output mixers
8168  */
8169 static struct hda_verb alc262_volume_init_verbs[] = {
8170         /*
8171          * Unmute ADC0-2 and set the default input to mic-in
8172          */
8173         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8174         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8175         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8176         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8177         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8178         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8179
8180         /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
8181          * mixer widget
8182          * Note: PASD motherboards uses the Line In 2 as the input for
8183          * front panel mic (mic 2)
8184          */
8185         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
8186         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8187         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8188         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8189         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8190         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8191
8192         /*
8193          * Set up output mixers (0x0c - 0x0f)
8194          */
8195         /* set vol=0 to output mixers */
8196         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8197         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8198         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8199         
8200         /* set up input amps for analog loopback */
8201         /* Amp Indices: DAC = 0, mixer = 1 */
8202         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8203         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8204         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8205         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8206         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8207         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8208
8209         /* FIXME: use matrix-type input source selection */
8210         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8211         /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8212         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8213         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
8214         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
8215         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
8216         /* Input mixer2 */
8217         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8218         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
8219         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
8220         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
8221         /* Input mixer3 */
8222         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8223         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
8224         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
8225         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
8226
8227         { }
8228 };
8229
8230 static struct hda_verb alc262_HP_BPC_init_verbs[] = {
8231         /*
8232          * Unmute ADC0-2 and set the default input to mic-in
8233          */
8234         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8235         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8236         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8237         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8238         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8239         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8240
8241         /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
8242          * mixer widget
8243          * Note: PASD motherboards uses the Line In 2 as the input for
8244          * front panel mic (mic 2)
8245          */
8246         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
8247         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8248         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8249         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8250         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8251         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8252         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
8253         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
8254         
8255         /*
8256          * Set up output mixers (0x0c - 0x0e)
8257          */
8258         /* set vol=0 to output mixers */
8259         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8260         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8261         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8262
8263         /* set up input amps for analog loopback */
8264         /* Amp Indices: DAC = 0, mixer = 1 */
8265         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8266         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8267         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8268         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8269         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8270         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8271
8272         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
8273         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8274         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8275
8276         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8277         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8278
8279         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
8280         {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8281
8282         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8283         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8284         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8285         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8286         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8287
8288         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
8289         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
8290         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
8291         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
8292         {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
8293         {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
8294
8295
8296         /* FIXME: use matrix-type input source selection */
8297         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8298         /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8299         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8300         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
8301         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
8302         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
8303         /* Input mixer2 */
8304         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8305         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
8306         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
8307         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
8308         /* Input mixer3 */
8309         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8310         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
8311         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
8312         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
8313
8314         { }
8315 };
8316
8317 static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
8318         /*
8319          * Unmute ADC0-2 and set the default input to mic-in
8320          */
8321         {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8322         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8323         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8324         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8325         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8326         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8327
8328         /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
8329          * mixer widget
8330          * Note: PASD motherboards uses the Line In 2 as the input for front
8331          * panel mic (mic 2)
8332          */
8333         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
8334         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8335         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8336         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8337         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8338         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8339         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
8340         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
8341         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
8342         /*
8343          * Set up output mixers (0x0c - 0x0e)
8344          */
8345         /* set vol=0 to output mixers */
8346         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8347         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8348         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8349
8350         /* set up input amps for analog loopback */
8351         /* Amp Indices: DAC = 0, mixer = 1 */
8352         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8353         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8354         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8355         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8356         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8357         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8358
8359
8360         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },        /* HP */
8361         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },       /* Mono */
8362         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },    /* rear MIC */
8363         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },        /* Line in */
8364         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },    /* Front MIC */
8365         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },       /* Line out */
8366         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },        /* CD in */
8367
8368         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8369         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8370
8371         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
8372         {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
8373
8374         /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
8375         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
8376         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
8377         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
8378         {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
8379         {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
8380
8381         /* FIXME: use matrix-type input source selection */
8382         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8383         /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8384         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
8385         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
8386         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
8387         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
8388         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
8389         /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))},  */
8390         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
8391         /* Input mixer2 */
8392         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8393         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
8394         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
8395         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
8396         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
8397         /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
8398         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
8399         /* Input mixer3 */
8400         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8401         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
8402         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
8403         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
8404         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
8405         /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
8406         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
8407
8408         { }
8409 };
8410
8411 #ifdef CONFIG_SND_HDA_POWER_SAVE
8412 #define alc262_loopbacks        alc880_loopbacks
8413 #endif
8414
8415 /* pcm configuration: identiacal with ALC880 */
8416 #define alc262_pcm_analog_playback      alc880_pcm_analog_playback
8417 #define alc262_pcm_analog_capture       alc880_pcm_analog_capture
8418 #define alc262_pcm_digital_playback     alc880_pcm_digital_playback
8419 #define alc262_pcm_digital_capture      alc880_pcm_digital_capture
8420
8421 /*
8422  * BIOS auto configuration
8423  */
8424 static int alc262_parse_auto_config(struct hda_codec *codec)
8425 {
8426         struct alc_spec *spec = codec->spec;
8427         int err;
8428         static hda_nid_t alc262_ignore[] = { 0x1d, 0 };
8429
8430         err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
8431                                            alc262_ignore);
8432         if (err < 0)
8433                 return err;
8434         if (!spec->autocfg.line_outs)
8435                 return 0; /* can't find valid BIOS pin config */
8436         err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
8437         if (err < 0)
8438                 return err;
8439         err = alc262_auto_create_analog_input_ctls(spec, &spec->autocfg);
8440         if (err < 0)
8441                 return err;
8442
8443         spec->multiout.max_channels = spec->multiout.num_dacs * 2;
8444
8445         if (spec->autocfg.dig_out_pin)
8446                 spec->multiout.dig_out_nid = ALC262_DIGOUT_NID;
8447         if (spec->autocfg.dig_in_pin)
8448                 spec->dig_in_nid = ALC262_DIGIN_NID;
8449
8450         if (spec->kctl_alloc)
8451                 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
8452
8453         spec->init_verbs[spec->num_init_verbs++] = alc262_volume_init_verbs;
8454         spec->num_mux_defs = 1;
8455         spec->input_mux = &spec->private_imux;
8456
8457         err = alc_auto_add_mic_boost(codec);
8458         if (err < 0)
8459                 return err;
8460
8461         return 1;
8462 }
8463
8464 #define alc262_auto_init_multi_out      alc882_auto_init_multi_out
8465 #define alc262_auto_init_hp_out         alc882_auto_init_hp_out
8466 #define alc262_auto_init_analog_input   alc882_auto_init_analog_input
8467
8468
8469 /* init callback for auto-configuration model -- overriding the default init */
8470 static void alc262_auto_init(struct hda_codec *codec)
8471 {
8472         alc262_auto_init_multi_out(codec);
8473         alc262_auto_init_hp_out(codec);
8474         alc262_auto_init_analog_input(codec);
8475 }
8476
8477 /*
8478  * configuration and preset
8479  */
8480 static const char *alc262_models[ALC262_MODEL_LAST] = {
8481         [ALC262_BASIC]          = "basic",
8482         [ALC262_HIPPO]          = "hippo",
8483         [ALC262_HIPPO_1]        = "hippo_1",
8484         [ALC262_FUJITSU]        = "fujitsu",
8485         [ALC262_HP_BPC]         = "hp-bpc",
8486         [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
8487         [ALC262_BENQ_ED8]       = "benq",
8488         [ALC262_BENQ_T31]       = "benq-t31",
8489         [ALC262_SONY_ASSAMD]    = "sony-assamd",
8490         [ALC262_AUTO]           = "auto",
8491 };
8492
8493 static struct snd_pci_quirk alc262_cfg_tbl[] = {
8494         SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
8495         SND_PCI_QUIRK(0x103c, 0x12fe, "HP xw9400", ALC262_HP_BPC),
8496         SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
8497         SND_PCI_QUIRK(0x103c, 0x12ff, "HP xw4550", ALC262_HP_BPC),
8498         SND_PCI_QUIRK(0x103c, 0x1308, "HP xw4600", ALC262_HP_BPC),
8499         SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
8500         SND_PCI_QUIRK(0x103c, 0x1307, "HP xw6600", ALC262_HP_BPC),
8501         SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
8502         SND_PCI_QUIRK(0x103c, 0x1306, "HP xw8600", ALC262_HP_BPC),
8503         SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
8504         SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
8505         SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
8506         SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
8507         SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
8508         SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
8509         SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
8510         SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
8511         SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
8512         SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
8513         SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
8514         SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
8515         SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
8516         SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
8517         SND_PCI_QUIRK(0x104d, 0x9015, "Sony 0x9015", ALC262_SONY_ASSAMD),
8518         SND_PCI_QUIRK(0x104d, 0x900e, "Sony ASSAMD", ALC262_SONY_ASSAMD),
8519         SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
8520         {}
8521 };
8522
8523 static struct alc_config_preset alc262_presets[] = {
8524         [ALC262_BASIC] = {
8525                 .mixers = { alc262_base_mixer },
8526                 .init_verbs = { alc262_init_verbs },
8527                 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8528                 .dac_nids = alc262_dac_nids,
8529                 .hp_nid = 0x03,
8530                 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8531                 .channel_mode = alc262_modes,
8532                 .input_mux = &alc262_capture_source,
8533         },
8534         [ALC262_HIPPO] = {
8535                 .mixers = { alc262_base_mixer },
8536                 .init_verbs = { alc262_init_verbs, alc262_hippo_unsol_verbs},
8537                 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8538                 .dac_nids = alc262_dac_nids,
8539                 .hp_nid = 0x03,
8540                 .dig_out_nid = ALC262_DIGOUT_NID,
8541                 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8542                 .channel_mode = alc262_modes,
8543                 .input_mux = &alc262_capture_source,
8544                 .unsol_event = alc262_hippo_unsol_event,
8545                 .init_hook = alc262_hippo_automute,
8546         },
8547         [ALC262_HIPPO_1] = {
8548                 .mixers = { alc262_hippo1_mixer },
8549                 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
8550                 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8551                 .dac_nids = alc262_dac_nids,
8552                 .hp_nid = 0x02,
8553                 .dig_out_nid = ALC262_DIGOUT_NID,
8554                 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8555                 .channel_mode = alc262_modes,
8556                 .input_mux = &alc262_capture_source,
8557                 .unsol_event = alc262_hippo1_unsol_event,
8558                 .init_hook = alc262_hippo1_automute,
8559         },
8560         [ALC262_FUJITSU] = {
8561                 .mixers = { alc262_fujitsu_mixer },
8562                 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
8563                                 alc262_fujitsu_unsol_verbs },
8564                 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8565                 .dac_nids = alc262_dac_nids,
8566                 .hp_nid = 0x03,
8567                 .dig_out_nid = ALC262_DIGOUT_NID,
8568                 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8569                 .channel_mode = alc262_modes,
8570                 .input_mux = &alc262_fujitsu_capture_source,
8571                 .unsol_event = alc262_fujitsu_unsol_event,
8572         },
8573         [ALC262_HP_BPC] = {
8574                 .mixers = { alc262_HP_BPC_mixer },
8575                 .init_verbs = { alc262_HP_BPC_init_verbs },
8576                 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8577                 .dac_nids = alc262_dac_nids,
8578                 .hp_nid = 0x03,
8579                 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8580                 .channel_mode = alc262_modes,
8581                 .input_mux = &alc262_HP_capture_source,
8582         },
8583         [ALC262_HP_BPC_D7000_WF] = {
8584                 .mixers = { alc262_HP_BPC_WildWest_mixer },
8585                 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
8586                 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8587                 .dac_nids = alc262_dac_nids,
8588                 .hp_nid = 0x03,
8589                 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8590                 .channel_mode = alc262_modes,
8591                 .input_mux = &alc262_HP_D7000_capture_source,
8592         },
8593         [ALC262_HP_BPC_D7000_WL] = {
8594                 .mixers = { alc262_HP_BPC_WildWest_mixer,
8595                             alc262_HP_BPC_WildWest_option_mixer },
8596                 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
8597                 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8598                 .dac_nids = alc262_dac_nids,
8599                 .hp_nid = 0x03,
8600                 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8601                 .channel_mode = alc262_modes,
8602                 .input_mux = &alc262_HP_D7000_capture_source,
8603         },
8604         [ALC262_BENQ_ED8] = {
8605                 .mixers = { alc262_base_mixer },
8606                 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
8607                 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8608                 .dac_nids = alc262_dac_nids,
8609                 .hp_nid = 0x03,
8610                 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8611                 .channel_mode = alc262_modes,
8612                 .input_mux = &alc262_capture_source,
8613         },
8614         [ALC262_SONY_ASSAMD] = {
8615                 .mixers = { alc262_sony_mixer },
8616                 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
8617                 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8618                 .dac_nids = alc262_dac_nids,
8619                 .hp_nid = 0x02,
8620                 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8621                 .channel_mode = alc262_modes,
8622                 .input_mux = &alc262_capture_source,
8623                 .unsol_event = alc262_hippo_unsol_event,
8624                 .init_hook = alc262_hippo_automute,
8625         },
8626         [ALC262_BENQ_T31] = {
8627                 .mixers = { alc262_benq_t31_mixer },
8628                 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs, alc262_hippo_unsol_verbs },
8629                 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8630                 .dac_nids = alc262_dac_nids,
8631                 .hp_nid = 0x03,
8632                 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8633                 .channel_mode = alc262_modes,
8634                 .input_mux = &alc262_capture_source,
8635                 .unsol_event = alc262_hippo_unsol_event,
8636                 .init_hook = alc262_hippo_automute,
8637         },      
8638 };
8639
8640 static int patch_alc262(struct hda_codec *codec)
8641 {
8642         struct alc_spec *spec;
8643         int board_config;
8644         int err;
8645
8646         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
8647         if (spec == NULL)
8648                 return -ENOMEM;
8649
8650         codec->spec = spec;
8651 #if 0
8652         /* pshou 07/11/05  set a zero PCM sample to DAC when FIFO is
8653          * under-run
8654          */
8655         {
8656         int tmp;
8657         snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
8658         tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
8659         snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
8660         snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
8661         }
8662 #endif
8663
8664         board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
8665                                                   alc262_models,
8666                                                   alc262_cfg_tbl);
8667
8668         if (board_config < 0) {
8669                 printk(KERN_INFO "hda_codec: Unknown model for ALC262, "
8670                        "trying auto-probe from BIOS...\n");
8671                 board_config = ALC262_AUTO;
8672         }
8673
8674         if (board_config == ALC262_AUTO) {
8675                 /* automatic parse from the BIOS config */
8676                 err = alc262_parse_auto_config(codec);
8677                 if (err < 0) {
8678                         alc_free(codec);
8679                         return err;
8680                 } else if (!err) {
8681                         printk(KERN_INFO
8682                                "hda_codec: Cannot set up configuration "
8683                                "from BIOS.  Using base mode...\n");
8684                         board_config = ALC262_BASIC;
8685                 }
8686         }
8687
8688         if (board_config != ALC262_AUTO)
8689                 setup_preset(spec, &alc262_presets[board_config]);
8690
8691         spec->stream_name_analog = "ALC262 Analog";
8692         spec->stream_analog_playback = &alc262_pcm_analog_playback;
8693         spec->stream_analog_capture = &alc262_pcm_analog_capture;
8694                 
8695         spec->stream_name_digital = "ALC262 Digital";
8696         spec->stream_digital_playback = &alc262_pcm_digital_playback;
8697         spec->stream_digital_capture = &alc262_pcm_digital_capture;
8698
8699         if (!spec->adc_nids && spec->input_mux) {
8700                 /* check whether NID 0x07 is valid */
8701                 unsigned int wcap = get_wcaps(codec, 0x07);
8702
8703                 /* get type */
8704                 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
8705                 if (wcap != AC_WID_AUD_IN) {
8706                         spec->adc_nids = alc262_adc_nids_alt;
8707                         spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids_alt);
8708                         spec->mixers[spec->num_mixers] =
8709                                 alc262_capture_alt_mixer;
8710                         spec->num_mixers++;
8711                 } else {
8712                         spec->adc_nids = alc262_adc_nids;
8713                         spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids);
8714                         spec->mixers[spec->num_mixers] = alc262_capture_mixer;
8715                         spec->num_mixers++;
8716                 }
8717         }
8718
8719         codec->patch_ops = alc_patch_ops;
8720         if (board_config == ALC262_AUTO)
8721                 spec->init_hook = alc262_auto_init;
8722 #ifdef CONFIG_SND_HDA_POWER_SAVE
8723         if (!spec->loopback.amplist)
8724                 spec->loopback.amplist = alc262_loopbacks;
8725 #endif
8726                 
8727         return 0;
8728 }
8729
8730 /*
8731  *  ALC268 channel source setting (2 channel)
8732  */
8733 #define ALC268_DIGOUT_NID       ALC880_DIGOUT_NID
8734 #define alc268_modes            alc260_modes
8735         
8736 static hda_nid_t alc268_dac_nids[2] = {
8737         /* front, hp */
8738         0x02, 0x03
8739 };
8740
8741 static hda_nid_t alc268_adc_nids[2] = {
8742         /* ADC0-1 */
8743         0x08, 0x07
8744 };
8745
8746 static hda_nid_t alc268_adc_nids_alt[1] = {
8747         /* ADC0 */
8748         0x08
8749 };
8750
8751 static struct snd_kcontrol_new alc268_base_mixer[] = {
8752         /* output mixer control */
8753         HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
8754         HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8755         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
8756         HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8757         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8758         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
8759         HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
8760         { }
8761 };
8762
8763 static struct hda_verb alc268_eapd_verbs[] = {
8764         {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
8765         {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
8766         { }
8767 };
8768
8769 /* Toshiba specific */
8770 #define alc268_toshiba_automute alc262_hippo_automute
8771
8772 static struct hda_verb alc268_toshiba_verbs[] = {
8773         {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8774         { } /* end */
8775 };
8776
8777 /* Acer specific */
8778 /* bind volumes of both NID 0x02 and 0x03 */
8779 static struct hda_bind_ctls alc268_acer_bind_master_vol = {
8780         .ops = &snd_hda_bind_vol,
8781         .values = {
8782                 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
8783                 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
8784                 0
8785         },
8786 };
8787
8788 /* mute/unmute internal speaker according to the hp jack and mute state */
8789 static void alc268_acer_automute(struct hda_codec *codec, int force)
8790 {
8791         struct alc_spec *spec = codec->spec;
8792         unsigned int mute;
8793
8794         if (force || !spec->sense_updated) {
8795                 unsigned int present;
8796                 present = snd_hda_codec_read(codec, 0x14, 0,
8797                                          AC_VERB_GET_PIN_SENSE, 0);
8798                 spec->jack_present = (present & 0x80000000) != 0;
8799                 spec->sense_updated = 1;
8800         }
8801         if (spec->jack_present)
8802                 mute = HDA_AMP_MUTE; /* mute internal speaker */
8803         else /* unmute internal speaker if necessary */
8804                 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
8805         snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
8806                                  HDA_AMP_MUTE, mute);
8807 }
8808
8809
8810 /* bind hp and internal speaker mute (with plug check) */
8811 static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol,
8812                                      struct snd_ctl_elem_value *ucontrol)
8813 {
8814         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
8815         long *valp = ucontrol->value.integer.value;
8816         int change;
8817
8818         change = snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
8819                                           HDA_AMP_MUTE,
8820                                           valp[0] ? 0 : HDA_AMP_MUTE);
8821         change |= snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
8822                                            HDA_AMP_MUTE,
8823                                            valp[1] ? 0 : HDA_AMP_MUTE);
8824         if (change)
8825                 alc268_acer_automute(codec, 0);
8826         return change;
8827 }
8828
8829 static struct snd_kcontrol_new alc268_acer_mixer[] = {
8830         /* output mixer control */
8831         HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
8832         {
8833                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8834                 .name = "Master Playback Switch",
8835                 .info = snd_hda_mixer_amp_switch_info,
8836                 .get = snd_hda_mixer_amp_switch_get,
8837                 .put = alc268_acer_master_sw_put,
8838                 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
8839         },
8840         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8841         HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
8842         HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
8843         { }
8844 };
8845
8846 static struct hda_verb alc268_acer_verbs[] = {
8847         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8848         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8849
8850         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8851         { }
8852 };
8853
8854 /* unsolicited event for HP jack sensing */
8855 static void alc268_toshiba_unsol_event(struct hda_codec *codec,
8856                                        unsigned int res)
8857 {
8858         if ((res >> 26) != ALC880_HP_EVENT)
8859                 return;
8860         alc268_toshiba_automute(codec);
8861 }
8862
8863 static void alc268_acer_unsol_event(struct hda_codec *codec,
8864                                        unsigned int res)
8865 {
8866         if ((res >> 26) != ALC880_HP_EVENT)
8867                 return;
8868         alc268_acer_automute(codec, 1);
8869 }
8870
8871 static void alc268_acer_init_hook(struct hda_codec *codec)
8872 {
8873         alc268_acer_automute(codec, 1);
8874 }
8875
8876 /*
8877  * generic initialization of ADC, input mixers and output mixers
8878  */
8879 static struct hda_verb alc268_base_init_verbs[] = {
8880         /* Unmute DAC0-1 and set vol = 0 */
8881         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8882         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8883         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8884         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8885         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8886         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8887
8888         /*
8889          * Set up output mixers (0x0c - 0x0e)
8890          */
8891         /* set vol=0 to output mixers */
8892         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8893         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8894         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8895         {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
8896
8897         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8898         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8899
8900         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
8901         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
8902         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
8903         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8904         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8905         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8906         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8907         {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8908
8909         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8910         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8911         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8912         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8913         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8914         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8915         {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8916         {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8917
8918         /* FIXME: use matrix-type input source selection */
8919         /* Mixer elements: 0x18, 19, 1a, 1c, 14, 15, 0b */
8920         /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8921         /* Input mixer2 */
8922         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8923         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
8924         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
8925         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
8926
8927         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
8928         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
8929         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
8930         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
8931         { }
8932 };
8933
8934 /*
8935  * generic initialization of ADC, input mixers and output mixers
8936  */
8937 static struct hda_verb alc268_volume_init_verbs[] = {
8938         /* set output DAC */
8939         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8940         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8941         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8942         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8943
8944         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8945         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
8946         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8947         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8948         {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
8949
8950         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8951         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8952         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8953         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8954         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8955
8956         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8957         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8958         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8959         {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8960
8961         /* set PCBEEP vol = 0 */
8962         {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, (0xb000 | (0x00 << 8))},
8963
8964         { }
8965 };
8966
8967 #define alc268_mux_enum_info alc_mux_enum_info
8968 #define alc268_mux_enum_get alc_mux_enum_get
8969
8970 static int alc268_mux_enum_put(struct snd_kcontrol *kcontrol,
8971                                struct snd_ctl_elem_value *ucontrol)
8972 {
8973         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
8974         struct alc_spec *spec = codec->spec;
8975         const struct hda_input_mux *imux = spec->input_mux;
8976         unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
8977         static hda_nid_t capture_mixers[3] = { 0x23, 0x24 };
8978         hda_nid_t nid = capture_mixers[adc_idx];
8979         unsigned int *cur_val = &spec->cur_mux[adc_idx];
8980         unsigned int i, idx;
8981
8982         idx = ucontrol->value.enumerated.item[0];
8983         if (idx >= imux->num_items)
8984                 idx = imux->num_items - 1;
8985         if (*cur_val == idx)
8986                 return 0;
8987         for (i = 0; i < imux->num_items; i++) {
8988                 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
8989                 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
8990                                          imux->items[i].index,
8991                                          HDA_AMP_MUTE, v);
8992                 snd_hda_codec_write_cache(codec, nid, 0,
8993                                           AC_VERB_SET_CONNECT_SEL,
8994                                           idx );
8995         }
8996         *cur_val = idx;
8997         return 1;
8998 }
8999
9000 static struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
9001         HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
9002         HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
9003         {
9004                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9005                 /* The multiple "Capture Source" controls confuse alsamixer
9006                  * So call somewhat different..
9007                  * FIXME: the controls appear in the "playback" view!
9008                  */
9009                 /* .name = "Capture Source", */
9010                 .name = "Input Source",
9011                 .count = 1,
9012                 .info = alc268_mux_enum_info,
9013                 .get = alc268_mux_enum_get,
9014                 .put = alc268_mux_enum_put,
9015         },
9016         { } /* end */
9017 };
9018
9019 static struct snd_kcontrol_new alc268_capture_mixer[] = {
9020         HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
9021         HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
9022         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
9023         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
9024         {
9025                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9026                 /* The multiple "Capture Source" controls confuse alsamixer
9027                  * So call somewhat different..
9028                  * FIXME: the controls appear in the "playback" view!
9029                  */
9030                 /* .name = "Capture Source", */
9031                 .name = "Input Source",
9032                 .count = 2,
9033                 .info = alc268_mux_enum_info,
9034                 .get = alc268_mux_enum_get,
9035                 .put = alc268_mux_enum_put,
9036         },
9037         { } /* end */
9038 };
9039
9040 static struct hda_input_mux alc268_capture_source = {
9041         .num_items = 4,
9042         .items = {
9043                 { "Mic", 0x0 },
9044                 { "Front Mic", 0x1 },
9045                 { "Line", 0x2 },
9046                 { "CD", 0x3 },
9047         },
9048 };
9049
9050 /* create input playback/capture controls for the given pin */
9051 static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
9052                                     const char *ctlname, int idx)
9053 {
9054         char name[32];
9055         int err;
9056
9057         sprintf(name, "%s Playback Volume", ctlname);
9058         if (nid == 0x14) {
9059                 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
9060                                   HDA_COMPOSE_AMP_VAL(0x02, 3, idx,
9061                                                       HDA_OUTPUT));
9062                 if (err < 0)
9063                         return err;
9064         } else if (nid == 0x15) {
9065                 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
9066                                   HDA_COMPOSE_AMP_VAL(0x03, 3, idx,
9067                                                       HDA_OUTPUT));
9068                 if (err < 0)
9069                         return err;
9070         } else
9071                 return -1;
9072         sprintf(name, "%s Playback Switch", ctlname);
9073         err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
9074                           HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
9075         if (err < 0)
9076                 return err;
9077         return 0;
9078 }
9079
9080 /* add playback controls from the parsed DAC table */
9081 static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
9082                                              const struct auto_pin_cfg *cfg)
9083 {
9084         hda_nid_t nid;
9085         int err;
9086
9087         spec->multiout.num_dacs = 2;    /* only use one dac */
9088         spec->multiout.dac_nids = spec->private_dac_nids;
9089         spec->multiout.dac_nids[0] = 2;
9090         spec->multiout.dac_nids[1] = 3;
9091
9092         nid = cfg->line_out_pins[0];
9093         if (nid)
9094                 alc268_new_analog_output(spec, nid, "Front", 0);        
9095
9096         nid = cfg->speaker_pins[0];
9097         if (nid == 0x1d) {
9098                 err = add_control(spec, ALC_CTL_WIDGET_VOL,
9099                                   "Speaker Playback Volume",
9100                                   HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
9101                 if (err < 0)
9102                         return err;
9103         }
9104         nid = cfg->hp_pins[0];
9105         if (nid)
9106                 alc268_new_analog_output(spec, nid, "Headphone", 0);
9107
9108         nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
9109         if (nid == 0x16) {
9110                 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
9111                                   "Mono Playback Switch",
9112                                   HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_INPUT));
9113                 if (err < 0)
9114                         return err;
9115         }
9116         return 0;       
9117 }
9118
9119 /* create playback/capture controls for input pins */
9120 static int alc268_auto_create_analog_input_ctls(struct alc_spec *spec,
9121                                                 const struct auto_pin_cfg *cfg)
9122 {
9123         struct hda_input_mux *imux = &spec->private_imux;
9124         int i, idx1;
9125
9126         for (i = 0; i < AUTO_PIN_LAST; i++) {
9127                 switch(cfg->input_pins[i]) {
9128                 case 0x18:
9129                         idx1 = 0;       /* Mic 1 */
9130                         break;
9131                 case 0x19:
9132                         idx1 = 1;       /* Mic 2 */
9133                         break;
9134                 case 0x1a:
9135                         idx1 = 2;       /* Line In */
9136                         break;
9137                 case 0x1c:      
9138                         idx1 = 3;       /* CD */
9139                         break;
9140                 default:
9141                         continue;
9142                 }
9143                 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
9144                 imux->items[imux->num_items].index = idx1;
9145                 imux->num_items++;      
9146         }
9147         return 0;
9148 }
9149
9150 static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
9151 {
9152         struct alc_spec *spec = codec->spec;
9153         hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
9154         hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
9155         hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
9156         unsigned int    dac_vol1, dac_vol2;
9157
9158         if (speaker_nid) {
9159                 snd_hda_codec_write(codec, speaker_nid, 0,
9160                                     AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
9161                 snd_hda_codec_write(codec, 0x0f, 0,
9162                                     AC_VERB_SET_AMP_GAIN_MUTE,
9163                                     AMP_IN_UNMUTE(1));
9164                 snd_hda_codec_write(codec, 0x10, 0,
9165                                     AC_VERB_SET_AMP_GAIN_MUTE,
9166                                     AMP_IN_UNMUTE(1));
9167         } else {
9168                 snd_hda_codec_write(codec, 0x0f, 0,
9169                                     AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
9170                 snd_hda_codec_write(codec, 0x10, 0,
9171                                     AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
9172         }
9173
9174         dac_vol1 = dac_vol2 = 0xb000 | 0x40;    /* set max volume  */
9175         if (line_nid == 0x14)   
9176                 dac_vol2 = AMP_OUT_ZERO;
9177         else if (line_nid == 0x15)
9178                 dac_vol1 = AMP_OUT_ZERO;
9179         if (hp_nid == 0x14)     
9180                 dac_vol2 = AMP_OUT_ZERO;
9181         else if (hp_nid == 0x15)
9182                 dac_vol1 = AMP_OUT_ZERO;
9183         if (line_nid != 0x16 || hp_nid != 0x16 ||
9184             spec->autocfg.line_out_pins[1] != 0x16 ||
9185             spec->autocfg.line_out_pins[2] != 0x16)
9186                 dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
9187
9188         snd_hda_codec_write(codec, 0x02, 0,
9189                             AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
9190         snd_hda_codec_write(codec, 0x03, 0,
9191                             AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
9192 }
9193
9194 /* pcm configuration: identiacal with ALC880 */
9195 #define alc268_pcm_analog_playback      alc880_pcm_analog_playback
9196 #define alc268_pcm_analog_capture       alc880_pcm_analog_capture
9197 #define alc268_pcm_digital_playback     alc880_pcm_digital_playback
9198
9199 /*
9200  * BIOS auto configuration
9201  */
9202 static int alc268_parse_auto_config(struct hda_codec *codec)
9203 {
9204         struct alc_spec *spec = codec->spec;
9205         int err;
9206         static hda_nid_t alc268_ignore[] = { 0 };
9207
9208         err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
9209                                            alc268_ignore);
9210         if (err < 0)
9211                 return err;
9212         if (!spec->autocfg.line_outs)
9213                 return 0; /* can't find valid BIOS pin config */
9214
9215         err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
9216         if (err < 0)
9217                 return err;
9218         err = alc268_auto_create_analog_input_ctls(spec, &spec->autocfg);
9219         if (err < 0)
9220                 return err;
9221
9222         spec->multiout.max_channels = 2;
9223
9224         /* digital only support output */
9225         if (spec->autocfg.dig_out_pin)
9226                 spec->multiout.dig_out_nid = ALC268_DIGOUT_NID;
9227
9228         if (spec->kctl_alloc)
9229                 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
9230
9231         spec->init_verbs[spec->num_init_verbs++] = alc268_volume_init_verbs;
9232         spec->num_mux_defs = 1;
9233         spec->input_mux = &spec->private_imux;
9234
9235         err = alc_auto_add_mic_boost(codec);
9236         if (err < 0)
9237                 return err;
9238
9239         return 1;
9240 }
9241
9242 #define alc268_auto_init_multi_out      alc882_auto_init_multi_out
9243 #define alc268_auto_init_hp_out         alc882_auto_init_hp_out
9244 #define alc268_auto_init_analog_input   alc882_auto_init_analog_input
9245
9246 /* init callback for auto-configuration model -- overriding the default init */
9247 static void alc268_auto_init(struct hda_codec *codec)
9248 {
9249         alc268_auto_init_multi_out(codec);
9250         alc268_auto_init_hp_out(codec);
9251         alc268_auto_init_mono_speaker_out(codec);
9252         alc268_auto_init_analog_input(codec);
9253 }
9254
9255 /*
9256  * configuration and preset
9257  */
9258 static const char *alc268_models[ALC268_MODEL_LAST] = {
9259         [ALC268_3ST]            = "3stack",
9260         [ALC268_TOSHIBA]        = "toshiba",
9261         [ALC268_ACER]           = "acer",
9262         [ALC268_AUTO]           = "auto",
9263 };
9264
9265 static struct snd_pci_quirk alc268_cfg_tbl[] = {
9266         SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
9267         SND_PCI_QUIRK(0x1179, 0xff10, "TOSHIBA A205", ALC268_TOSHIBA),
9268         SND_PCI_QUIRK(0x1179, 0xff50, "TOSHIBA A305", ALC268_TOSHIBA),
9269         SND_PCI_QUIRK(0x103c, 0x30cc, "TOSHIBA", ALC268_TOSHIBA),
9270         SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
9271         SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
9272         SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER),
9273         {}
9274 };
9275
9276 static struct alc_config_preset alc268_presets[] = {
9277         [ALC268_3ST] = {
9278                 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer },
9279                 .init_verbs = { alc268_base_init_verbs },
9280                 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
9281                 .dac_nids = alc268_dac_nids,
9282                 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
9283                 .adc_nids = alc268_adc_nids_alt,
9284                 .hp_nid = 0x03,
9285                 .dig_out_nid = ALC268_DIGOUT_NID,
9286                 .num_channel_mode = ARRAY_SIZE(alc268_modes),
9287                 .channel_mode = alc268_modes,
9288                 .input_mux = &alc268_capture_source,
9289         },
9290         [ALC268_TOSHIBA] = {
9291                 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer },
9292                 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
9293                                 alc268_toshiba_verbs },
9294                 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
9295                 .dac_nids = alc268_dac_nids,
9296                 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
9297                 .adc_nids = alc268_adc_nids_alt,
9298                 .hp_nid = 0x03,
9299                 .num_channel_mode = ARRAY_SIZE(alc268_modes),
9300                 .channel_mode = alc268_modes,
9301                 .input_mux = &alc268_capture_source,
9302                 .input_mux = &alc268_capture_source,
9303                 .unsol_event = alc268_toshiba_unsol_event,
9304                 .init_hook = alc268_toshiba_automute,
9305         },
9306         [ALC268_ACER] = {
9307                 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer },
9308                 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
9309                                 alc268_acer_verbs },
9310                 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
9311                 .dac_nids = alc268_dac_nids,
9312                 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
9313                 .adc_nids = alc268_adc_nids_alt,
9314                 .hp_nid = 0x02,
9315                 .num_channel_mode = ARRAY_SIZE(alc268_modes),
9316                 .channel_mode = alc268_modes,
9317                 .input_mux = &alc268_capture_source,
9318                 .unsol_event = alc268_acer_unsol_event,
9319                 .init_hook = alc268_acer_init_hook,
9320         },
9321 };
9322
9323 static int patch_alc268(struct hda_codec *codec)
9324 {
9325         struct alc_spec *spec;
9326         int board_config;
9327         int err;
9328
9329         spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
9330         if (spec == NULL)
9331                 return -ENOMEM;
9332
9333         codec->spec = spec;
9334
9335         board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
9336                                                   alc268_models,
9337                                                   alc268_cfg_tbl);
9338
9339         if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
9340                 printk(KERN_INFO "hda_codec: Unknown model for ALC268, "
9341                        "trying auto-probe from BIOS...\n");
9342                 board_config = ALC268_AUTO;
9343         }
9344
9345         if (board_config == ALC268_AUTO) {
9346                 /* automatic parse from the BIOS config */
9347                 err = alc268_parse_auto_config(codec);
9348                 if (err < 0) {
9349                         alc_free(codec);
9350                         return err;
9351                 } else if (!err) {
9352                         printk(KERN_INFO
9353                                "hda_codec: Cannot set up configuration "
9354                                "from BIOS.  Using base mode...\n");
9355                         board_config = ALC268_3ST;
9356                 }
9357         }
9358
9359         if (board_config != ALC268_AUTO)
9360                 setup_preset(spec, &alc268_presets[board_config]);
9361
9362         spec->stream_name_analog = "ALC268 Analog";
9363         spec->stream_analog_playback = &alc268_pcm_analog_playback;
9364         spec->stream_analog_capture = &alc268_pcm_analog_capture;
9365
9366         spec->stream_name_digital = "ALC268 Digital";
9367         spec->stream_digital_playback = &alc268_pcm_digital_playback;
9368
9369         if (board_config == ALC268_AUTO) {
9370                 if (!spec->adc_nids && spec->input_mux) {
9371                         /* check whether NID 0x07 is valid */
9372                         unsigned int wcap = get_wcaps(codec, 0x07);
9373
9374                         /* get type */
9375                         wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
9376                         if (wcap != AC_WID_AUD_IN) {
9377                                 spec->adc_nids = alc268_adc_nids_alt;
9378                                 spec->num_adc_nids =
9379                                         ARRAY_SIZE(alc268_adc_nids_alt);
9380                                 spec->mixers[spec->num_mixers] =
9381                                         alc268_capture_alt_mixer;
9382                                 spec->num_mixers++;
9383                         } else {
9384                                 spec->adc_nids = alc268_adc_nids;
9385                                 spec->num_adc_nids =
9386                                         ARRAY_SIZE(alc268_adc_nids);
9387                                 spec->mixers[spec->num_mixers] =
9388                                         alc268_capture_mixer;
9389                                 spec->num_mixers++;
9390                         }
9391                 }
9392         }
9393         codec->patch_ops = alc_patch_ops;
9394         if (board_config == ALC268_AUTO)
9395                 spec->init_hook = alc268_auto_init;
9396                 
9397         return 0;
9398 }
9399
9400 /*
9401  *  ALC861 channel source setting (2/6 channel selection for 3-stack)
9402  */
9403
9404 /*
9405  * set the path ways for 2 channel output
9406  * need to set the codec line out and mic 1 pin widgets to inputs
9407  */
9408 static struct hda_verb alc861_threestack_ch2_init[] = {
9409         /* set pin widget 1Ah (line in) for input */
9410         { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
9411         /* set pin widget 18h (mic1/2) for input, for mic also enable
9412          * the vref
9413          */
9414         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9415
9416         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
9417 #if 0
9418         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
9419         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
9420 #endif
9421         { } /* end */
9422 };
9423 /*
9424  * 6ch mode
9425  * need to set the codec line out and mic 1 pin widgets to outputs
9426  */
9427 static struct hda_verb alc861_threestack_ch6_init[] = {
9428         /* set pin widget 1Ah (line in) for output (Back Surround)*/
9429         { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
9430         /* set pin widget 18h (mic1) for output (CLFE)*/
9431         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
9432
9433         { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
9434         { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
9435
9436         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
9437 #if 0
9438         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
9439         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
9440 #endif
9441         { } /* end */
9442 };
9443
9444 static struct hda_channel_mode alc861_threestack_modes[2] = {
9445         { 2, alc861_threestack_ch2_init },
9446         { 6, alc861_threestack_ch6_init },
9447 };
9448 /* Set mic1 as input and unmute the mixer */
9449 static struct hda_verb alc861_uniwill_m31_ch2_init[] = {
9450         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9451         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
9452         { } /* end */
9453 };
9454 /* Set mic1 as output and mute mixer */
9455 static struct hda_verb alc861_uniwill_m31_ch4_init[] = {
9456         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
9457         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
9458         { } /* end */
9459 };
9460
9461 static struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
9462         { 2, alc861_uniwill_m31_ch2_init },
9463         { 4, alc861_uniwill_m31_ch4_init },
9464 };
9465
9466 /* Set mic1 and line-in as input and unmute the mixer */
9467 static struct hda_verb alc861_asus_ch2_init[] = {
9468         /* set pin widget 1Ah (line in) for input */
9469         { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
9470         /* set pin widget 18h (mic1/2) for input, for mic also enable
9471          * the vref
9472          */
9473         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9474
9475         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
9476 #if 0
9477         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
9478         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
9479 #endif
9480         { } /* end */
9481 };
9482 /* Set mic1 nad line-in as output and mute mixer */
9483 static struct hda_verb alc861_asus_ch6_init[] = {
9484         /* set pin widget 1Ah (line in) for output (Back Surround)*/
9485         { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
9486         /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
9487         /* set pin widget 18h (mic1) for output (CLFE)*/
9488         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
9489         /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
9490         { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
9491         { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
9492
9493         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
9494 #if 0
9495         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
9496         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
9497 #endif
9498         { } /* end */
9499 };
9500
9501 static struct hda_channel_mode alc861_asus_modes[2] = {
9502         { 2, alc861_asus_ch2_init },
9503         { 6, alc861_asus_ch6_init },
9504 };
9505
9506 /* patch-ALC861 */
9507
9508 static struct snd_kcontrol_new alc861_base_mixer[] = {
9509         /* output mixer control */
9510         HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
9511         HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
9512         HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
9513         HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
9514         HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
9515
9516         /*Input mixer control */
9517         /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
9518            HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
9519         HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
9520         HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
9521         HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
9522         HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
9523         HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
9524         HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
9525         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
9526         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
9527
9528         /* Capture mixer control */
9529         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
9530         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
9531         {
9532                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9533                 .name = "Capture Source",
9534                 .count = 1,
9535                 .info = alc_mux_enum_info,
9536                 .get = alc_mux_enum_get,
9537                 .put = alc_mux_enum_put,
9538         },
9539         { } /* end */
9540 };
9541
9542 static struct snd_kcontrol_new alc861_3ST_mixer[] = {
9543         /* output mixer control */
9544         HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
9545         HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
9546         HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
9547         HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
9548         /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
9549
9550         /* Input mixer control */
9551         /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
9552            HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
9553         HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
9554         HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
9555         HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
9556         HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
9557         HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
9558         HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
9559         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
9560         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
9561
9562         /* Capture mixer control */
9563         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
9564         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
9565         {
9566                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9567                 .name = "Capture Source",
9568                 .count = 1,
9569                 .info = alc_mux_enum_info,
9570                 .get = alc_mux_enum_get,
9571                 .put = alc_mux_enum_put,
9572         },
9573         {
9574                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9575                 .name = "Channel Mode",
9576                 .info = alc_ch_mode_info,
9577                 .get = alc_ch_mode_get,
9578                 .put = alc_ch_mode_put,
9579                 .private_value = ARRAY_SIZE(alc861_threestack_modes),
9580         },
9581         { } /* end */
9582 };
9583
9584 static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
9585         /* output mixer control */
9586         HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
9587         HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
9588         HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
9589         
9590         /*Capture mixer control */
9591         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
9592         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
9593         {
9594                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9595                 .name = "Capture Source",
9596                 .count = 1,
9597                 .info = alc_mux_enum_info,
9598                 .get = alc_mux_enum_get,
9599                 .put = alc_mux_enum_put,
9600         },
9601
9602         { } /* end */
9603 };
9604
9605 static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
9606         /* output mixer control */
9607         HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
9608         HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
9609         HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
9610         HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
9611         /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
9612
9613         /* Input mixer control */
9614         /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
9615            HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
9616         HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
9617         HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
9618         HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
9619         HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
9620         HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
9621         HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
9622         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
9623         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
9624
9625         /* Capture mixer control */
9626         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
9627         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
9628         {
9629                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9630                 .name = "Capture Source",
9631                 .count = 1,
9632                 .info = alc_mux_enum_info,
9633                 .get = alc_mux_enum_get,
9634                 .put = alc_mux_enum_put,
9635         },
9636         {
9637                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9638                 .name = "Channel Mode",
9639                 .info = alc_ch_mode_info,
9640                 .get = alc_ch_mode_get,
9641                 .put = alc_ch_mode_put,
9642                 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
9643         },
9644         { } /* end */
9645 };
9646
9647 static struct snd_kcontrol_new alc861_asus_mixer[] = {
9648         /* output mixer control */
9649         HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
9650         HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
9651         HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
9652         HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
9653         HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
9654
9655         /* Input mixer control */
9656         HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
9657         HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9658         HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
9659         HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
9660         HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
9661         HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
9662         HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
9663         HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
9664         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
9665         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
9666
9667         /* Capture mixer control */
9668         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
9669         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
9670         {
9671                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9672                 .name = "Capture Source",
9673                 .count = 1,
9674                 .info = alc_mux_enum_info,
9675                 .get = alc_mux_enum_get,
9676                 .put = alc_mux_enum_put,
9677         },
9678         {
9679                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9680                 .name = "Channel Mode",
9681                 .info = alc_ch_mode_info,
9682                 .get = alc_ch_mode_get,
9683                 .put = alc_ch_mode_put,
9684                 .private_value = ARRAY_SIZE(alc861_asus_modes),
9685         },
9686         { }
9687 };
9688
9689 /* additional mixer */
9690 static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
9691         HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
9692         HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
9693         HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x23, 0x0, HDA_OUTPUT),
9694         HDA_CODEC_MUTE("PC Beep Playback Switch", 0x23, 0x0, HDA_OUTPUT),
9695         { }
9696 };
9697
9698 /*
9699  * generic initialization of ADC, input mixers and output mixers
9700  */
9701 static struct hda_verb alc861_base_init_verbs[] = {
9702         /*
9703          * Unmute ADC0 and set the default input to mic-in
9704          */
9705         /* port-A for surround (rear panel) */
9706         { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
9707         { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
9708         /* port-B for mic-in (rear panel) with vref */
9709         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9710         /* port-C for line-in (rear panel) */
9711         { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
9712         /* port-D for Front */
9713         { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
9714         { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
9715         /* port-E for HP out (front panel) */
9716         { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
9717         /* route front PCM to HP */
9718         { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
9719         /* port-F for mic-in (front panel) with vref */
9720         { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9721         /* port-G for CLFE (rear panel) */
9722         { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
9723         { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
9724         /* port-H for side (rear panel) */
9725         { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
9726         { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
9727         /* CD-in */
9728         { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
9729         /* route front mic to ADC1*/
9730         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9731         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9732         
9733         /* Unmute DAC0~3 & spdif out*/
9734         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9735         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9736         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9737         {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9738         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9739         
9740         /* Unmute Mixer 14 (mic) 1c (Line in)*/
9741         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9742         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9743         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9744         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9745         
9746         /* Unmute Stereo Mixer 15 */
9747         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9748         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9749         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9750         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
9751
9752         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9753         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9754         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9755         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9756         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9757         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9758         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9759         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9760         /* hp used DAC 3 (Front) */
9761         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
9762         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9763
9764         { }
9765 };
9766
9767 static struct hda_verb alc861_threestack_init_verbs[] = {
9768         /*
9769          * Unmute ADC0 and set the default input to mic-in
9770          */
9771         /* port-A for surround (rear panel) */
9772         { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
9773         /* port-B for mic-in (rear panel) with vref */
9774         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9775         /* port-C for line-in (rear panel) */
9776         { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
9777         /* port-D for Front */
9778         { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
9779         { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
9780         /* port-E for HP out (front panel) */
9781         { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
9782         /* route front PCM to HP */
9783         { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
9784         /* port-F for mic-in (front panel) with vref */
9785         { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9786         /* port-G for CLFE (rear panel) */
9787         { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
9788         /* port-H for side (rear panel) */
9789         { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
9790         /* CD-in */
9791         { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
9792         /* route front mic to ADC1*/
9793         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9794         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9795         /* Unmute DAC0~3 & spdif out*/
9796         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9797         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9798         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9799         {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9800         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9801         
9802         /* Unmute Mixer 14 (mic) 1c (Line in)*/
9803         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9804         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9805         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9806         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9807         
9808         /* Unmute Stereo Mixer 15 */
9809         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9810         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9811         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9812         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
9813
9814         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9815         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9816         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9817         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9818         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9819         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9820         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9821         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9822         /* hp used DAC 3 (Front) */
9823         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
9824         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9825         { }
9826 };
9827
9828 static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
9829         /*
9830          * Unmute ADC0 and set the default input to mic-in
9831          */
9832         /* port-A for surround (rear panel) */
9833         { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
9834         /* port-B for mic-in (rear panel) with vref */
9835         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9836         /* port-C for line-in (rear panel) */
9837         { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
9838         /* port-D for Front */
9839         { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
9840         { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
9841         /* port-E for HP out (front panel) */
9842         /* this has to be set to VREF80 */
9843         { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9844         /* route front PCM to HP */
9845         { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
9846         /* port-F for mic-in (front panel) with vref */
9847         { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9848         /* port-G for CLFE (rear panel) */
9849         { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
9850         /* port-H for side (rear panel) */
9851         { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
9852         /* CD-in */
9853         { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
9854         /* route front mic to ADC1*/
9855         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9856         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9857         /* Unmute DAC0~3 & spdif out*/
9858         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9859         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9860         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9861         {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9862         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9863         
9864         /* Unmute Mixer 14 (mic) 1c (Line in)*/
9865         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9866         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9867         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9868         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9869         
9870         /* Unmute Stereo Mixer 15 */
9871         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9872         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9873         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9874         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
9875
9876         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9877         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9878         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9879         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9880         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9881         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9882         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9883         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9884         /* hp used DAC 3 (Front) */
9885         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
9886         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9887         { }
9888 };
9889
9890 static struct hda_verb alc861_asus_init_verbs[] = {
9891         /*
9892          * Unmute ADC0 and set the default input to mic-in
9893          */
9894         /* port-A for surround (rear panel)
9895          * according to codec#0 this is the HP jack
9896          */
9897         { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
9898         /* route front PCM to HP */
9899         { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
9900         /* port-B for mic-in (rear panel) with vref */
9901         { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9902         /* port-C for line-in (rear panel) */
9903         { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
9904         /* port-D for Front */
9905         { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
9906         { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
9907         /* port-E for HP out (front panel) */
9908         /* this has to be set to VREF80 */
9909         { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9910         /* route front PCM to HP */
9911         { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
9912         /* port-F for mic-in (front panel) with vref */
9913         { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
9914         /* port-G for CLFE (rear panel) */
9915         { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
9916         /* port-H for side (rear panel) */
9917         { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
9918         /* CD-in */
9919         { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
9920         /* route front mic to ADC1*/
9921         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9922         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9923         /* Unmute DAC0~3 & spdif out*/
9924         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9925         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9926         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9927         {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9928         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9929         /* Unmute Mixer 14 (mic) 1c (Line in)*/
9930         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9931         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9932         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9933         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9934         
9935         /* Unmute Stereo Mixer 15 */
9936         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9937         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9938         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9939         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
9940
9941         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9942         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9943         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9944         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9945         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9946         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9947         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9948         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9949         /* hp used DAC 3 (Front) */
9950         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
9951         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9952         { }
9953 };
9954
9955 /* additional init verbs for ASUS laptops */
9956 static struct hda_verb alc861_asus_laptop_init_verbs[] = {
9957         { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
9958         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
9959         { }
9960 };
9961
9962 /*
9963  * generic initialization of ADC, input mixers and output mixers
9964  */
9965 static struct hda_verb alc861_auto_init_verbs[] = {
9966         /*
9967          * Unmute ADC0 and set the default input to mic-in
9968          */
9969         /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
9970         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9971         
9972         /* Unmute DAC0~3 & spdif out*/
9973         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9974         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9975         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9976         {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
9977         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9978         
9979         /* Unmute Mixer 14 (mic) 1c (Line in)*/
9980         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9981         {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9982         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9983         {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9984         
9985         /* Unmute Stereo Mixer 15 */
9986         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9987         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9988         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
9989         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
9990
9991         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9992         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9993         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9994         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9995         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9996         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9997         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9998         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9999
10000         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10001         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10002         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
10003         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
10004         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10005         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10006         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
10007         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
10008
10009         {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},  /* set Mic 1 */
10010
10011         { }
10012 };
10013
10014 static struct hda_verb alc861_toshiba_init_verbs[] = {
10015         {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10016
10017         { }
10018 };
10019
10020 /* toggle speaker-output according to the hp-jack state */
10021 static void alc861_toshiba_automute(struct hda_codec *codec)
10022 {
10023         unsigned int present;
10024
10025         present = snd_hda_codec_read(codec, 0x0f, 0,
10026                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
10027         snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
10028                                  HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
10029         snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
10030                                  HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
10031 }
10032
10033 static void alc861_toshiba_unsol_event(struct hda_codec *codec,
10034                                        unsigned int res)
10035 {
10036         if ((res >> 26) == ALC880_HP_EVENT)
10037                 alc861_toshiba_automute(codec);
10038 }
10039
10040 /* pcm configuration: identiacal with ALC880 */
10041 #define alc861_pcm_analog_playback      alc880_pcm_analog_playback
10042 #define alc861_pcm_analog_capture       alc880_pcm_analog_capture
10043 #define alc861_pcm_digital_playback     alc880_pcm_digital_playback
10044 #define alc861_pcm_digital_capture      alc880_pcm_digital_capture
10045
10046
10047 #define ALC861_DIGOUT_NID       0x07
10048
10049 static struct hda_channel_mode alc861_8ch_modes[1] = {
10050         { 8, NULL }
10051 };
10052
10053 static hda_nid_t alc861_dac_nids[4] = {
10054         /* front, surround, clfe, side */
10055         0x03, 0x06, 0x05, 0x04
10056 };
10057
10058 static hda_nid_t alc660_dac_nids[3] = {
10059         /* front, clfe, surround */
10060         0x03, 0x05, 0x06
10061 };
10062
10063 static hda_nid_t alc861_adc_nids[1] = {
10064         /* ADC0-2 */
10065         0x08,
10066 };
10067
10068 static struct hda_input_mux alc861_capture_source = {
10069         .num_items = 5,
10070         .items = {
10071                 { "Mic", 0x0 },
10072                 { "Front Mic", 0x3 },
10073                 { "Line", 0x1 },
10074                 { "CD", 0x4 },
10075                 { "Mixer", 0x5 },
10076         },
10077 };
10078
10079 /* fill in the dac_nids table from the parsed pin configuration */
10080 static int alc861_auto_fill_dac_nids(struct alc_spec *spec,
10081                                      const struct auto_pin_cfg *cfg)
10082 {
10083         int i;
10084         hda_nid_t nid;
10085
10086         spec->multiout.dac_nids = spec->private_dac_nids;
10087         for (i = 0; i < cfg->line_outs; i++) {
10088                 nid = cfg->line_out_pins[i];
10089                 if (nid) {
10090                         if (i >= ARRAY_SIZE(alc861_dac_nids))
10091                                 continue;
10092                         spec->multiout.dac_nids[i] = alc861_dac_nids[i];
10093                 }
10094         }
10095         spec->multiout.num_dacs = cfg->line_outs;
10096         return 0;
10097 }
10098
10099 /* add playback controls from the parsed DAC table */
10100 static int alc861_auto_create_multi_out_ctls(struct alc_spec *spec,
10101                                              const struct auto_pin_cfg *cfg)
10102 {
10103         char name[32];
10104         static const char *chname[4] = {
10105                 "Front", "Surround", NULL /*CLFE*/, "Side"
10106         };
10107         hda_nid_t nid;
10108         int i, idx, err;
10109
10110         for (i = 0; i < cfg->line_outs; i++) {
10111                 nid = spec->multiout.dac_nids[i];
10112                 if (!nid)
10113                         continue;
10114                 if (nid == 0x05) {
10115                         /* Center/LFE */
10116                         err = add_control(spec, ALC_CTL_BIND_MUTE,
10117                                           "Center Playback Switch",
10118                                           HDA_COMPOSE_AMP_VAL(nid, 1, 0,
10119                                                               HDA_OUTPUT));
10120                         if (err < 0)
10121                                 return err;
10122                         err = add_control(spec, ALC_CTL_BIND_MUTE,
10123                                           "LFE Playback Switch",
10124                                           HDA_COMPOSE_AMP_VAL(nid, 2, 0,
10125                                                               HDA_OUTPUT));
10126                         if (err < 0)
10127                                 return err;
10128                 } else {
10129                         for (idx = 0; idx < ARRAY_SIZE(alc861_dac_nids) - 1;
10130                              idx++)
10131                                 if (nid == alc861_dac_nids[idx])
10132                                         break;
10133                         sprintf(name, "%s Playback Switch", chname[idx]);
10134                         err = add_control(spec, ALC_CTL_BIND_MUTE, name,
10135                                           HDA_COMPOSE_AMP_VAL(nid, 3, 0,
10136                                                               HDA_OUTPUT));
10137                         if (err < 0)
10138                                 return err;
10139                 }
10140         }
10141         return 0;
10142 }
10143
10144 static int alc861_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin)
10145 {
10146         int err;
10147         hda_nid_t nid;
10148
10149         if (!pin)
10150                 return 0;
10151
10152         if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
10153                 nid = 0x03;
10154                 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10155                                   "Headphone Playback Switch",
10156                                   HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
10157                 if (err < 0)
10158                         return err;
10159                 spec->multiout.hp_nid = nid;
10160         }
10161         return 0;
10162 }
10163
10164 /* create playback/capture controls for input pins */
10165 static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec,
10166                                                 const struct auto_pin_cfg *cfg)
10167 {
10168         struct hda_input_mux *imux = &spec->private_imux;
10169         int i, err, idx, idx1;
10170
10171         for (i = 0; i < AUTO_PIN_LAST; i++) {
10172                 switch (cfg->input_pins[i]) {
10173                 case 0x0c:
10174                         idx1 = 1;
10175                         idx = 2;        /* Line In */
10176                         break;
10177                 case 0x0f:
10178                         idx1 = 2;
10179                         idx = 2;        /* Line In */
10180                         break;
10181                 case 0x0d:
10182                         idx1 = 0;
10183                         idx = 1;        /* Mic In */
10184                         break;
10185                 case 0x10:
10186                         idx1 = 3;
10187                         idx = 1;        /* Mic In */
10188                         break;
10189                 case 0x11:
10190                         idx1 = 4;
10191                         idx = 0;        /* CD */
10192                         break;
10193                 default:
10194                         continue;
10195                 }
10196
10197                 err = new_analog_input(spec, cfg->input_pins[i],
10198                                        auto_pin_cfg_labels[i], idx, 0x15);
10199                 if (err < 0)
10200                         return err;
10201
10202                 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
10203                 imux->items[imux->num_items].index = idx1;
10204                 imux->num_items++;
10205         }
10206         return 0;
10207 }
10208
10209 static struct snd_kcontrol_new alc861_capture_mixer[] = {
10210         HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
10211         HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
10212
10213         {
10214                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10215                 /* The multiple "Capture Source" controls confuse alsamixer
10216                  * So call somewhat different..
10217                  *FIXME: the controls appear in the "playback" view!
10218                  */
10219                 /* .name = "Capture Source", */
10220                 .name = "Input Source",
10221                 .count = 1,
10222                 .info = alc_mux_enum_info,
10223                 .get = alc_mux_enum_get,
10224                 .put = alc_mux_enum_put,
10225         },
10226         { } /* end */
10227 };
10228
10229 static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
10230                                               hda_nid_t nid,
10231                                               int pin_type, int dac_idx)
10232 {
10233         /* set as output */
10234
10235         snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
10236                             pin_type);
10237         snd_hda_codec_write(codec, dac_idx, 0, AC_VERB_SET_AMP_GAIN_MUTE,
10238                             AMP_OUT_UNMUTE);
10239
10240 }
10241
10242 static void alc861_auto_init_multi_out(struct hda_codec *codec)
10243 {
10244         struct alc_spec *spec = codec->spec;
10245         int i;
10246
10247         alc_subsystem_id(codec, 0x0e, 0x0f, 0x0b);
10248         for (i = 0; i < spec->autocfg.line_outs; i++) {
10249                 hda_nid_t nid = spec->autocfg.line_out_pins[i];
10250                 int pin_type = get_pin_type(spec->autocfg.line_out_type);
10251                 if (nid)
10252                         alc861_auto_set_output_and_unmute(codec, nid, pin_type,
10253                                                           spec->multiout.dac_nids[i]);
10254         }
10255 }
10256
10257 static void alc861_auto_init_hp_out(struct hda_codec *codec)
10258 {
10259         struct alc_spec *spec = codec->spec;
10260         hda_nid_t pin;
10261
10262         pin = spec->autocfg.hp_pins[0];
10263         if (pin) /* connect to front */
10264                 alc861_auto_set_output_and_unmute(codec, pin, PIN_HP,
10265                                                   spec->multiout.dac_nids[0]);
10266 }
10267
10268 static void alc861_auto_init_analog_input(struct hda_codec *codec)
10269 {
10270         struct alc_spec *spec = codec->spec;
10271         int i;
10272
10273         for (i = 0; i < AUTO_PIN_LAST; i++) {
10274                 hda_nid_t nid = spec->autocfg.input_pins[i];
10275                 if (nid >= 0x0c && nid <= 0x11) {
10276                         snd_hda_codec_write(codec, nid, 0,
10277                                             AC_VERB_SET_PIN_WIDGET_CONTROL,
10278                                             i <= AUTO_PIN_FRONT_MIC ?
10279                                             PIN_VREF80 : PIN_IN);
10280                 }
10281         }
10282 }
10283
10284 /* parse the BIOS configuration and set up the alc_spec */
10285 /* return 1 if successful, 0 if the proper config is not found,
10286  * or a negative error code
10287  */
10288 static int alc861_parse_auto_config(struct hda_codec *codec)
10289 {
10290         struct alc_spec *spec = codec->spec;
10291         int err;
10292         static hda_nid_t alc861_ignore[] = { 0x1d, 0 };
10293
10294         err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
10295                                            alc861_ignore);
10296         if (err < 0)
10297                 return err;
10298         if (!spec->autocfg.line_outs)
10299                 return 0; /* can't find valid BIOS pin config */
10300
10301         err = alc861_auto_fill_dac_nids(spec, &spec->autocfg);
10302         if (err < 0)
10303                 return err;
10304         err = alc861_auto_create_multi_out_ctls(spec, &spec->autocfg);
10305         if (err < 0)
10306                 return err;
10307         err = alc861_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
10308         if (err < 0)
10309                 return err;
10310         err = alc861_auto_create_analog_input_ctls(spec, &spec->autocfg);
10311         if (err < 0)
10312                 return err;
10313
10314         spec->multiout.max_channels = spec->multiout.num_dacs * 2;
10315
10316         if (spec->autocfg.dig_out_pin)
10317                 spec->multiout.dig_out_nid = ALC861_DIGOUT_NID;
10318
10319         if (spec->kctl_alloc)
10320                 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
10321
10322         spec->init_verbs[spec->num_init_verbs++] = alc861_auto_init_verbs;
10323
10324         spec->num_mux_defs = 1;
10325         spec->input_mux = &spec->private_imux;
10326
10327         spec->adc_nids = alc861_adc_nids;
10328         spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
10329         spec->mixers[spec->num_mixers] = alc861_capture_mixer;
10330         spec->num_mixers++;
10331
10332         return 1;
10333 }
10334
10335 /* additional initialization for auto-configuration model */
10336 static void alc861_auto_init(struct hda_codec *codec)
10337 {
10338         alc861_auto_init_multi_out(codec);
10339         alc861_auto_init_hp_out(codec);
10340         alc861_auto_init_analog_input(codec);
10341 }
10342
10343 #ifdef CONFIG_SND_HDA_POWER_SAVE
10344 static struct hda_amp_list alc861_loopbacks[] = {
10345         { 0x15, HDA_INPUT, 0 },
10346         { 0x15, HDA_INPUT, 1 },
10347         { 0x15, HDA_INPUT, 2 },
10348         { 0x15, HDA_INPUT, 3 },
10349         { } /* end */
10350 };
10351 #endif
10352
10353
10354 /*
10355  * configuration and preset
10356  */
10357 static const char *alc861_models[ALC861_MODEL_LAST] = {
10358         [ALC861_3ST]            = "3stack",
10359         [ALC660_3ST]            = "3stack-660",
10360         [ALC861_3ST_DIG]        = "3stack-dig",
10361         [ALC861_6ST_DIG]        = "6stack-dig",
10362         [ALC861_UNIWILL_M31]    = "uniwill-m31",
10363         [ALC861_TOSHIBA]        = "toshiba",
10364         [ALC861_ASUS]           = "asus",
10365         [ALC861_ASUS_LAPTOP]    = "asus-laptop",
10366         [ALC861_AUTO]           = "auto",
10367 };
10368
10369 static struct snd_pci_quirk alc861_cfg_tbl[] = {
10370         SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
10371         SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
10372         SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
10373         SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
10374         SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
10375         SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
10376         SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
10377         SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
10378         /* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
10379          *        Any other models that need this preset?
10380          */
10381         /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
10382         SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
10383         SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31),
10384         SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
10385         SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
10386         SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
10387         SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
10388         SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
10389         {}
10390 };
10391
10392 static struct alc_config_preset alc861_presets[] = {
10393         [ALC861_3ST] = {
10394                 .mixers = { alc861_3ST_mixer },
10395                 .init_verbs = { alc861_threestack_init_verbs },
10396                 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
10397                 .dac_nids = alc861_dac_nids,
10398                 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
10399                 .channel_mode = alc861_threestack_modes,
10400                 .need_dac_fix = 1,
10401                 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
10402                 .adc_nids = alc861_adc_nids,
10403                 .input_mux = &alc861_capture_source,
10404         },
10405         [ALC861_3ST_DIG] = {
10406                 .mixers = { alc861_base_mixer },
10407                 .init_verbs = { alc861_threestack_init_verbs },
10408                 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
10409                 .dac_nids = alc861_dac_nids,
10410                 .dig_out_nid = ALC861_DIGOUT_NID,
10411                 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
10412                 .channel_mode = alc861_threestack_modes,
10413                 .need_dac_fix = 1,
10414                 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
10415                 .adc_nids = alc861_adc_nids,
10416                 .input_mux = &alc861_capture_source,
10417         },
10418         [ALC861_6ST_DIG] = {
10419                 .mixers = { alc861_base_mixer },
10420                 .init_verbs = { alc861_base_init_verbs },
10421                 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
10422                 .dac_nids = alc861_dac_nids,
10423                 .dig_out_nid = ALC861_DIGOUT_NID,
10424                 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
10425                 .channel_mode = alc861_8ch_modes,
10426                 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
10427                 .adc_nids = alc861_adc_nids,
10428                 .input_mux = &alc861_capture_source,
10429         },
10430         [ALC660_3ST] = {
10431                 .mixers = { alc861_3ST_mixer },
10432                 .init_verbs = { alc861_threestack_init_verbs },
10433                 .num_dacs = ARRAY_SIZE(alc660_dac_nids),
10434                 .dac_nids = alc660_dac_nids,
10435                 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
10436                 .channel_mode = alc861_threestack_modes,
10437                 .need_dac_fix = 1,
10438                 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
10439                 .adc_nids = alc861_adc_nids,
10440                 .input_mux = &alc861_capture_source,
10441         },
10442         [ALC861_UNIWILL_M31] = {
10443                 .mixers = { alc861_uniwill_m31_mixer },
10444                 .init_verbs = { alc861_uniwill_m31_init_verbs },
10445                 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
10446                 .dac_nids = alc861_dac_nids,
10447                 .dig_out_nid = ALC861_DIGOUT_NID,
10448                 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
10449                 .channel_mode = alc861_uniwill_m31_modes,
10450                 .need_dac_fix = 1,
10451                 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
10452                 .adc_nids = alc861_adc_nids,
10453                 .input_mux = &alc861_capture_source,
10454         },
10455         [ALC861_TOSHIBA] = {
10456                 .mixers = { alc861_toshiba_mixer },
10457                 .init_verbs = { alc861_base_init_verbs,
10458                                 alc861_toshiba_init_verbs },
10459                 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
10460                 .dac_nids = alc861_dac_nids,
10461                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10462                 .channel_mode = alc883_3ST_2ch_modes,
10463                 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
10464                 .adc_nids = alc861_adc_nids,
10465                 .input_mux = &alc861_capture_source,
10466                 .unsol_event = alc861_toshiba_unsol_event,
10467                 .init_hook = alc861_toshiba_automute,
10468         },
10469         [ALC861_ASUS] = {
10470                 .mixers = { alc861_asus_mixer },
10471                 .init_verbs = { alc861_asus_init_verbs },
10472                 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
10473                 .dac_nids = alc861_dac_nids,
10474                 .dig_out_nid = ALC861_DIGOUT_NID,
10475                 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
10476                 .channel_mode = alc861_asus_modes,
10477                 .need_dac_fix = 1,
10478                 .hp_nid = 0x06,
10479                 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
10480                 .adc_nids = alc861_adc_nids,
10481                 .input_mux = &alc861_capture_source,
10482         },
10483         [ALC861_ASUS_LAPTOP] = {
10484                 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
10485                 .init_verbs = { alc861_asus_init_verbs,
10486                                 alc861_asus_laptop_init_verbs },
10487                 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
10488                 .dac_nids = alc861_dac_nids,
10489                 .dig_out_nid = ALC861_DIGOUT_NID,
10490                 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10491                 .channel_mode = alc883_3ST_2ch_modes,
10492                 .need_dac_fix = 1,
10493                 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
10494                 .adc_nids = alc861_adc_nids,
10495                 .input_mux = &alc861_capture_source,
10496         },
10497 };
10498
10499
10500 static int patch_alc861(struct hda_codec *codec)
10501 {
10502         struct alc_spec *spec;
10503         int board_config;
10504         int err;
10505
10506         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
10507         if (spec == NULL)
10508                 return -ENOMEM;
10509
10510         codec->spec = spec;
10511
10512         board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
10513                                                   alc861_models,
10514                                                   alc861_cfg_tbl);
10515
10516         if (board_config < 0) {
10517                 printk(KERN_INFO "hda_codec: Unknown model for ALC861, "
10518                        "trying auto-probe from BIOS...\n");
10519                 board_config = ALC861_AUTO;
10520         }
10521
10522         if (board_config == ALC861_AUTO) {
10523                 /* automatic parse from the BIOS config */
10524                 err = alc861_parse_auto_config(codec);
10525                 if (err < 0) {
10526                         alc_free(codec);
10527                         return err;
10528                 } else if (!err) {
10529                         printk(KERN_INFO
10530                                "hda_codec: Cannot set up configuration "
10531                                "from BIOS.  Using base mode...\n");
10532                    board_config = ALC861_3ST_DIG;
10533                 }
10534         }
10535
10536         if (board_config != ALC861_AUTO)
10537                 setup_preset(spec, &alc861_presets[board_config]);
10538
10539         spec->stream_name_analog = "ALC861 Analog";
10540         spec->stream_analog_playback = &alc861_pcm_analog_playback;
10541         spec->stream_analog_capture = &alc861_pcm_analog_capture;
10542
10543         spec->stream_name_digital = "ALC861 Digital";
10544         spec->stream_digital_playback = &alc861_pcm_digital_playback;
10545         spec->stream_digital_capture = &alc861_pcm_digital_capture;
10546
10547         codec->patch_ops = alc_patch_ops;
10548         if (board_config == ALC861_AUTO)
10549                 spec->init_hook = alc861_auto_init;
10550 #ifdef CONFIG_SND_HDA_POWER_SAVE
10551         if (!spec->loopback.amplist)
10552                 spec->loopback.amplist = alc861_loopbacks;
10553 #endif
10554                 
10555         return 0;
10556 }
10557
10558 /*
10559  * ALC861-VD support
10560  *
10561  * Based on ALC882
10562  *
10563  * In addition, an independent DAC
10564  */
10565 #define ALC861VD_DIGOUT_NID     0x06
10566
10567 static hda_nid_t alc861vd_dac_nids[4] = {
10568         /* front, surr, clfe, side surr */
10569         0x02, 0x03, 0x04, 0x05
10570 };
10571
10572 /* dac_nids for ALC660vd are in a different order - according to
10573  * Realtek's driver.
10574  * This should probably tesult in a different mixer for 6stack models
10575  * of ALC660vd codecs, but for now there is only 3stack mixer
10576  * - and it is the same as in 861vd.
10577  * adc_nids in ALC660vd are (is) the same as in 861vd
10578  */
10579 static hda_nid_t alc660vd_dac_nids[3] = {
10580         /* front, rear, clfe, rear_surr */
10581         0x02, 0x04, 0x03
10582 };
10583
10584 static hda_nid_t alc861vd_adc_nids[1] = {
10585         /* ADC0 */
10586         0x09,
10587 };
10588
10589 /* input MUX */
10590 /* FIXME: should be a matrix-type input source selection */
10591 static struct hda_input_mux alc861vd_capture_source = {
10592         .num_items = 4,
10593         .items = {
10594                 { "Mic", 0x0 },
10595                 { "Front Mic", 0x1 },
10596                 { "Line", 0x2 },
10597                 { "CD", 0x4 },
10598         },
10599 };
10600
10601 static struct hda_input_mux alc861vd_dallas_capture_source = {
10602         .num_items = 3,
10603         .items = {
10604                 { "Front Mic", 0x0 },
10605                 { "ATAPI Mic", 0x1 },
10606                 { "Line In", 0x5 },
10607         },
10608 };
10609
10610 static struct hda_input_mux alc861vd_hp_capture_source = {
10611         .num_items = 2,
10612         .items = {
10613                 { "Front Mic", 0x0 },
10614                 { "ATAPI Mic", 0x1 },
10615         },
10616 };
10617
10618 #define alc861vd_mux_enum_info alc_mux_enum_info
10619 #define alc861vd_mux_enum_get alc_mux_enum_get
10620
10621 static int alc861vd_mux_enum_put(struct snd_kcontrol *kcontrol,
10622                                 struct snd_ctl_elem_value *ucontrol)
10623 {
10624         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
10625         struct alc_spec *spec = codec->spec;
10626         const struct hda_input_mux *imux = spec->input_mux;
10627         unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
10628         static hda_nid_t capture_mixers[1] = { 0x22 };
10629         hda_nid_t nid = capture_mixers[adc_idx];
10630         unsigned int *cur_val = &spec->cur_mux[adc_idx];
10631         unsigned int i, idx;
10632
10633         idx = ucontrol->value.enumerated.item[0];
10634         if (idx >= imux->num_items)
10635                 idx = imux->num_items - 1;
10636         if (*cur_val == idx)
10637                 return 0;
10638         for (i = 0; i < imux->num_items; i++) {
10639                 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
10640                 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
10641                                          imux->items[i].index,
10642                                          HDA_AMP_MUTE, v);
10643         }
10644         *cur_val = idx;
10645         return 1;
10646 }
10647
10648 /*
10649  * 2ch mode
10650  */
10651 static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
10652         { 2, NULL }
10653 };
10654
10655 /*
10656  * 6ch mode
10657  */
10658 static struct hda_verb alc861vd_6stack_ch6_init[] = {
10659         { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
10660         { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10661         { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10662         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10663         { } /* end */
10664 };
10665
10666 /*
10667  * 8ch mode
10668  */
10669 static struct hda_verb alc861vd_6stack_ch8_init[] = {
10670         { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10671         { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10672         { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10673         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
10674         { } /* end */
10675 };
10676
10677 static struct hda_channel_mode alc861vd_6stack_modes[2] = {
10678         { 6, alc861vd_6stack_ch6_init },
10679         { 8, alc861vd_6stack_ch8_init },
10680 };
10681
10682 static struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
10683         {
10684                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10685                 .name = "Channel Mode",
10686                 .info = alc_ch_mode_info,
10687                 .get = alc_ch_mode_get,
10688                 .put = alc_ch_mode_put,
10689         },
10690         { } /* end */
10691 };
10692
10693 static struct snd_kcontrol_new alc861vd_capture_mixer[] = {
10694         HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
10695         HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
10696
10697         {
10698                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
10699                 /* The multiple "Capture Source" controls confuse alsamixer
10700                  * So call somewhat different..
10701                  *FIXME: the controls appear in the "playback" view!
10702                  */
10703                 /* .name = "Capture Source", */
10704                 .name = "Input Source",
10705                 .count = 1,
10706                 .info = alc861vd_mux_enum_info,
10707                 .get = alc861vd_mux_enum_get,
10708                 .put = alc861vd_mux_enum_put,
10709         },
10710         { } /* end */
10711 };
10712
10713 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
10714  *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
10715  */
10716 static struct snd_kcontrol_new alc861vd_6st_mixer[] = {
10717         HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
10718         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
10719
10720         HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
10721         HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
10722
10723         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
10724                                 HDA_OUTPUT),
10725         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
10726                                 HDA_OUTPUT),
10727         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
10728         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
10729
10730         HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
10731         HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
10732
10733         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
10734
10735         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10736         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10737         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10738
10739         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10740         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
10741         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
10742
10743         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
10744         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
10745
10746         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10747         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10748
10749         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
10750         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
10751
10752         { } /* end */
10753 };
10754
10755 static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
10756         HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
10757         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
10758
10759         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
10760
10761         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10762         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10763         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10764
10765         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10766         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
10767         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
10768
10769         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
10770         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
10771
10772         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10773         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10774
10775         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
10776         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
10777
10778         { } /* end */
10779 };
10780
10781 static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
10782         HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
10783         /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
10784         HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
10785
10786         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
10787
10788         HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
10789         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10790         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10791
10792         HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
10793         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
10794         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
10795
10796         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
10797         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
10798
10799         { } /* end */
10800 };
10801
10802 /* Pin assignment: Front=0x14, HP = 0x15,
10803  *                 Front Mic=0x18, ATAPI Mic = 0x19, Line In = 0x1d
10804  */
10805 static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
10806         HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
10807         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
10808         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
10809         HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
10810         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10811         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10812         HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
10813         HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
10814         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x05, HDA_INPUT),
10815         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x05, HDA_INPUT),
10816         { } /* end */
10817 };
10818
10819 /* Pin assignment: Speaker=0x14, Line-out = 0x15,
10820  *                 Front Mic=0x18, ATAPI Mic = 0x19,
10821  */
10822 static struct snd_kcontrol_new alc861vd_hp_mixer[] = {
10823         HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
10824         HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
10825         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
10826         HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
10827         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
10828         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10829         HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
10830         HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
10831         
10832         { } /* end */
10833 };
10834
10835 /*
10836  * generic initialization of ADC, input mixers and output mixers
10837  */
10838 static struct hda_verb alc861vd_volume_init_verbs[] = {
10839         /*
10840          * Unmute ADC0 and set the default input to mic-in
10841          */
10842         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
10843         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10844
10845         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
10846          * the analog-loopback mixer widget
10847          */
10848         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
10849         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10850         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10851         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
10852         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
10853         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
10854
10855         /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
10856         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10857         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10858         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
10859         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
10860
10861         /*
10862          * Set up output mixers (0x02 - 0x05)
10863          */
10864         /* set vol=0 to output mixers */
10865         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10866         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10867         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10868         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
10869
10870         /* set up input amps for analog loopback */
10871         /* Amp Indices: DAC = 0, mixer = 1 */
10872         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10873         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10874         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10875         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10876         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10877         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10878         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
10879         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
10880
10881         { }
10882 };
10883
10884 /*
10885  * 3-stack pin configuration:
10886  * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
10887  */
10888 static struct hda_verb alc861vd_3stack_init_verbs[] = {
10889         /*
10890          * Set pin mode and muting
10891          */
10892         /* set front pin widgets 0x14 for output */
10893         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10894         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10895         {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
10896
10897         /* Mic (rear) pin: input vref at 80% */
10898         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10899         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10900         /* Front Mic pin: input vref at 80% */
10901         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10902         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10903         /* Line In pin: input */
10904         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10905         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10906         /* Line-2 In: Headphone output (output 0 - 0x0c) */
10907         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10908         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10909         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
10910         /* CD pin widget for input */
10911         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10912
10913         { }
10914 };
10915
10916 /*
10917  * 6-stack pin configuration:
10918  */
10919 static struct hda_verb alc861vd_6stack_init_verbs[] = {
10920         /*
10921          * Set pin mode and muting
10922          */
10923         /* set front pin widgets 0x14 for output */
10924         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10925         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10926         {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
10927
10928         /* Rear Pin: output 1 (0x0d) */
10929         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10930         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10931         {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
10932         /* CLFE Pin: output 2 (0x0e) */
10933         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10934         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10935         {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
10936         /* Side Pin: output 3 (0x0f) */
10937         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
10938         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10939         {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
10940
10941         /* Mic (rear) pin: input vref at 80% */
10942         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10943         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10944         /* Front Mic pin: input vref at 80% */
10945         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
10946         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10947         /* Line In pin: input */
10948         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10949         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
10950         /* Line-2 In: Headphone output (output 0 - 0x0c) */
10951         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10952         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
10953         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
10954         /* CD pin widget for input */
10955         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10956
10957         { }
10958 };
10959
10960 static struct hda_verb alc861vd_eapd_verbs[] = {
10961         {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
10962         { }
10963 };
10964
10965 static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
10966         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
10967         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
10968         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
10969         {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10970         {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, 
10971         {}
10972 };
10973
10974 /* toggle speaker-output according to the hp-jack state */
10975 static void alc861vd_lenovo_hp_automute(struct hda_codec *codec)
10976 {
10977         unsigned int present;
10978         unsigned char bits;
10979
10980         present = snd_hda_codec_read(codec, 0x1b, 0,
10981                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
10982         bits = present ? HDA_AMP_MUTE : 0;
10983         snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10984                                  HDA_AMP_MUTE, bits);
10985 }
10986
10987 static void alc861vd_lenovo_mic_automute(struct hda_codec *codec)
10988 {
10989         unsigned int present;
10990         unsigned char bits;
10991
10992         present = snd_hda_codec_read(codec, 0x18, 0,
10993                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
10994         bits = present ? HDA_AMP_MUTE : 0;
10995         snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
10996                                  HDA_AMP_MUTE, bits);
10997 }
10998
10999 static void alc861vd_lenovo_automute(struct hda_codec *codec)
11000 {
11001         alc861vd_lenovo_hp_automute(codec);
11002         alc861vd_lenovo_mic_automute(codec);
11003 }
11004
11005 static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
11006                                         unsigned int res)
11007 {
11008         switch (res >> 26) {
11009         case ALC880_HP_EVENT:
11010                 alc861vd_lenovo_hp_automute(codec);
11011                 break;
11012         case ALC880_MIC_EVENT:
11013                 alc861vd_lenovo_mic_automute(codec);
11014                 break;
11015         }
11016 }
11017
11018 static struct hda_verb alc861vd_dallas_verbs[] = {
11019         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11020         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11021         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11022         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11023
11024         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11025         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11026         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11027         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11028         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11029         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11030         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11031         {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11032         
11033         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11034         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11035         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11036         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11037         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11038         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11039         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11040         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11041
11042         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
11043         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11044         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
11045         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11046         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11047         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11048         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11049         {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11050
11051         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11052         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11053         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11054         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11055
11056         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11057         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},  
11058         {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11059
11060         { } /* end */
11061 };
11062
11063 /* toggle speaker-output according to the hp-jack state */
11064 static void alc861vd_dallas_automute(struct hda_codec *codec)
11065 {
11066         unsigned int present;
11067
11068         present = snd_hda_codec_read(codec, 0x15, 0,
11069                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11070         snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11071                                  HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
11072 }
11073
11074 static void alc861vd_dallas_unsol_event(struct hda_codec *codec, unsigned int res)
11075 {
11076         if ((res >> 26) == ALC880_HP_EVENT)
11077                 alc861vd_dallas_automute(codec);
11078 }
11079
11080 #ifdef CONFIG_SND_HDA_POWER_SAVE
11081 #define alc861vd_loopbacks      alc880_loopbacks
11082 #endif
11083
11084 /* pcm configuration: identiacal with ALC880 */
11085 #define alc861vd_pcm_analog_playback    alc880_pcm_analog_playback
11086 #define alc861vd_pcm_analog_capture     alc880_pcm_analog_capture
11087 #define alc861vd_pcm_digital_playback   alc880_pcm_digital_playback
11088 #define alc861vd_pcm_digital_capture    alc880_pcm_digital_capture
11089
11090 /*
11091  * configuration and preset
11092  */
11093 static const char *alc861vd_models[ALC861VD_MODEL_LAST] = {
11094         [ALC660VD_3ST]          = "3stack-660",
11095         [ALC660VD_3ST_DIG]      = "3stack-660-digout",
11096         [ALC861VD_3ST]          = "3stack",
11097         [ALC861VD_3ST_DIG]      = "3stack-digout",
11098         [ALC861VD_6ST_DIG]      = "6stack-digout",
11099         [ALC861VD_LENOVO]       = "lenovo",
11100         [ALC861VD_DALLAS]       = "dallas",
11101         [ALC861VD_HP]           = "hp",
11102         [ALC861VD_AUTO]         = "auto",
11103 };
11104
11105 static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
11106         SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
11107         SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),
11108         SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
11109         SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
11110         SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
11111
11112         /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
11113         SND_PCI_QUIRK(0x1179, 0xff01, "DALLAS", ALC861VD_DALLAS),
11114         SND_PCI_QUIRK(0x17aa, 0x3802, "Lenovo 3000 C200", ALC861VD_LENOVO),
11115         SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo", ALC861VD_LENOVO),
11116         SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
11117         SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
11118         SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
11119         SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
11120         SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
11121         {}
11122 };
11123
11124 static struct alc_config_preset alc861vd_presets[] = {
11125         [ALC660VD_3ST] = {
11126                 .mixers = { alc861vd_3st_mixer },
11127                 .init_verbs = { alc861vd_volume_init_verbs,
11128                                  alc861vd_3stack_init_verbs },
11129                 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
11130                 .dac_nids = alc660vd_dac_nids,
11131                 .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
11132                 .adc_nids = alc861vd_adc_nids,
11133                 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
11134                 .channel_mode = alc861vd_3stack_2ch_modes,
11135                 .input_mux = &alc861vd_capture_source,
11136         },
11137         [ALC660VD_3ST_DIG] = {
11138                 .mixers = { alc861vd_3st_mixer },
11139                 .init_verbs = { alc861vd_volume_init_verbs,
11140                                  alc861vd_3stack_init_verbs },
11141                 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
11142                 .dac_nids = alc660vd_dac_nids,
11143                 .dig_out_nid = ALC861VD_DIGOUT_NID,
11144                 .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
11145                 .adc_nids = alc861vd_adc_nids,
11146                 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
11147                 .channel_mode = alc861vd_3stack_2ch_modes,
11148                 .input_mux = &alc861vd_capture_source,
11149         },
11150         [ALC861VD_3ST] = {
11151                 .mixers = { alc861vd_3st_mixer },
11152                 .init_verbs = { alc861vd_volume_init_verbs,
11153                                  alc861vd_3stack_init_verbs },
11154                 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
11155                 .dac_nids = alc861vd_dac_nids,
11156                 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
11157                 .channel_mode = alc861vd_3stack_2ch_modes,
11158                 .input_mux = &alc861vd_capture_source,
11159         },
11160         [ALC861VD_3ST_DIG] = {
11161                 .mixers = { alc861vd_3st_mixer },
11162                 .init_verbs = { alc861vd_volume_init_verbs,
11163                                  alc861vd_3stack_init_verbs },
11164                 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
11165                 .dac_nids = alc861vd_dac_nids,
11166                 .dig_out_nid = ALC861VD_DIGOUT_NID,
11167                 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
11168                 .channel_mode = alc861vd_3stack_2ch_modes,
11169                 .input_mux = &alc861vd_capture_source,
11170         },
11171         [ALC861VD_6ST_DIG] = {
11172                 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
11173                 .init_verbs = { alc861vd_volume_init_verbs,
11174                                 alc861vd_6stack_init_verbs },
11175                 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
11176                 .dac_nids = alc861vd_dac_nids,
11177                 .dig_out_nid = ALC861VD_DIGOUT_NID,
11178                 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
11179                 .channel_mode = alc861vd_6stack_modes,
11180                 .input_mux = &alc861vd_capture_source,
11181         },
11182         [ALC861VD_LENOVO] = {
11183                 .mixers = { alc861vd_lenovo_mixer },
11184                 .init_verbs = { alc861vd_volume_init_verbs,
11185                                 alc861vd_3stack_init_verbs,
11186                                 alc861vd_eapd_verbs,
11187                                 alc861vd_lenovo_unsol_verbs },
11188                 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
11189                 .dac_nids = alc660vd_dac_nids,
11190                 .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
11191                 .adc_nids = alc861vd_adc_nids,
11192                 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
11193                 .channel_mode = alc861vd_3stack_2ch_modes,
11194                 .input_mux = &alc861vd_capture_source,
11195                 .unsol_event = alc861vd_lenovo_unsol_event,
11196                 .init_hook = alc861vd_lenovo_automute,
11197         },
11198         [ALC861VD_DALLAS] = {
11199                 .mixers = { alc861vd_dallas_mixer },
11200                 .init_verbs = { alc861vd_dallas_verbs },
11201                 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
11202                 .dac_nids = alc861vd_dac_nids,
11203                 .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
11204                 .adc_nids = alc861vd_adc_nids,
11205                 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
11206                 .channel_mode = alc861vd_3stack_2ch_modes,
11207                 .input_mux = &alc861vd_dallas_capture_source,
11208                 .unsol_event = alc861vd_dallas_unsol_event,
11209                 .init_hook = alc861vd_dallas_automute,
11210         },
11211         [ALC861VD_HP] = {
11212                 .mixers = { alc861vd_hp_mixer },
11213                 .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
11214                 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
11215                 .dac_nids = alc861vd_dac_nids,
11216                 .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
11217                 .dig_out_nid = ALC861VD_DIGOUT_NID,
11218                 .adc_nids = alc861vd_adc_nids,
11219                 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
11220                 .channel_mode = alc861vd_3stack_2ch_modes,
11221                 .input_mux = &alc861vd_hp_capture_source,
11222                 .unsol_event = alc861vd_dallas_unsol_event,
11223                 .init_hook = alc861vd_dallas_automute,
11224         },              
11225 };
11226
11227 /*
11228  * BIOS auto configuration
11229  */
11230 static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
11231                                 hda_nid_t nid, int pin_type, int dac_idx)
11232 {
11233         /* set as output */
11234         snd_hda_codec_write(codec, nid, 0,
11235                                 AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
11236         snd_hda_codec_write(codec, nid, 0,
11237                                 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
11238 }
11239
11240 static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
11241 {
11242         struct alc_spec *spec = codec->spec;
11243         int i;
11244
11245         alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
11246         for (i = 0; i <= HDA_SIDE; i++) {
11247                 hda_nid_t nid = spec->autocfg.line_out_pins[i];
11248                 int pin_type = get_pin_type(spec->autocfg.line_out_type);
11249                 if (nid)
11250                         alc861vd_auto_set_output_and_unmute(codec, nid,
11251                                                             pin_type, i);
11252         }
11253 }
11254
11255
11256 static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
11257 {
11258         struct alc_spec *spec = codec->spec;
11259         hda_nid_t pin;
11260
11261         pin = spec->autocfg.hp_pins[0];
11262         if (pin) /* connect to front and  use dac 0 */
11263                 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
11264 }
11265
11266 #define alc861vd_is_input_pin(nid)      alc880_is_input_pin(nid)
11267 #define ALC861VD_PIN_CD_NID             ALC880_PIN_CD_NID
11268
11269 static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
11270 {
11271         struct alc_spec *spec = codec->spec;
11272         int i;
11273
11274         for (i = 0; i < AUTO_PIN_LAST; i++) {
11275                 hda_nid_t nid = spec->autocfg.input_pins[i];
11276                 if (alc861vd_is_input_pin(nid)) {
11277                         snd_hda_codec_write(codec, nid, 0,
11278                                         AC_VERB_SET_PIN_WIDGET_CONTROL,
11279                                         i <= AUTO_PIN_FRONT_MIC ?
11280                                                         PIN_VREF80 : PIN_IN);
11281                         if (nid != ALC861VD_PIN_CD_NID)
11282                                 snd_hda_codec_write(codec, nid, 0,
11283                                                 AC_VERB_SET_AMP_GAIN_MUTE,
11284                                                 AMP_OUT_MUTE);
11285                 }
11286         }
11287 }
11288
11289 #define alc861vd_idx_to_mixer_vol(nid)          ((nid) + 0x02)
11290 #define alc861vd_idx_to_mixer_switch(nid)       ((nid) + 0x0c)
11291
11292 /* add playback controls from the parsed DAC table */
11293 /* Based on ALC880 version. But ALC861VD has separate,
11294  * different NIDs for mute/unmute switch and volume control */
11295 static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
11296                                              const struct auto_pin_cfg *cfg)
11297 {
11298         char name[32];
11299         static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"};
11300         hda_nid_t nid_v, nid_s;
11301         int i, err;
11302
11303         for (i = 0; i < cfg->line_outs; i++) {
11304                 if (!spec->multiout.dac_nids[i])
11305                         continue;
11306                 nid_v = alc861vd_idx_to_mixer_vol(
11307                                 alc880_dac_to_idx(
11308                                         spec->multiout.dac_nids[i]));
11309                 nid_s = alc861vd_idx_to_mixer_switch(
11310                                 alc880_dac_to_idx(
11311                                         spec->multiout.dac_nids[i]));
11312
11313                 if (i == 2) {
11314                         /* Center/LFE */
11315                         err = add_control(spec, ALC_CTL_WIDGET_VOL,
11316                                           "Center Playback Volume",
11317                                           HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
11318                                                               HDA_OUTPUT));
11319                         if (err < 0)
11320                                 return err;
11321                         err = add_control(spec, ALC_CTL_WIDGET_VOL,
11322                                           "LFE Playback Volume",
11323                                           HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
11324                                                               HDA_OUTPUT));
11325                         if (err < 0)
11326                                 return err;
11327                         err = add_control(spec, ALC_CTL_BIND_MUTE,
11328                                           "Center Playback Switch",
11329                                           HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
11330                                                               HDA_INPUT));
11331                         if (err < 0)
11332                                 return err;
11333                         err = add_control(spec, ALC_CTL_BIND_MUTE,
11334                                           "LFE Playback Switch",
11335                                           HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
11336                                                               HDA_INPUT));
11337                         if (err < 0)
11338                                 return err;
11339                 } else {
11340                         sprintf(name, "%s Playback Volume", chname[i]);
11341                         err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
11342                                           HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
11343                                                               HDA_OUTPUT));
11344                         if (err < 0)
11345                                 return err;
11346                         sprintf(name, "%s Playback Switch", chname[i]);
11347                         err = add_control(spec, ALC_CTL_BIND_MUTE, name,
11348                                           HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
11349                                                               HDA_INPUT));
11350                         if (err < 0)
11351                                 return err;
11352                 }
11353         }
11354         return 0;
11355 }
11356
11357 /* add playback controls for speaker and HP outputs */
11358 /* Based on ALC880 version. But ALC861VD has separate,
11359  * different NIDs for mute/unmute switch and volume control */
11360 static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
11361                                         hda_nid_t pin, const char *pfx)
11362 {
11363         hda_nid_t nid_v, nid_s;
11364         int err;
11365         char name[32];
11366
11367         if (!pin)
11368                 return 0;
11369
11370         if (alc880_is_fixed_pin(pin)) {
11371                 nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
11372                 /* specify the DAC as the extra output */
11373                 if (!spec->multiout.hp_nid)
11374                         spec->multiout.hp_nid = nid_v;
11375                 else
11376                         spec->multiout.extra_out_nid[0] = nid_v;
11377                 /* control HP volume/switch on the output mixer amp */
11378                 nid_v = alc861vd_idx_to_mixer_vol(
11379                                 alc880_fixed_pin_idx(pin));
11380                 nid_s = alc861vd_idx_to_mixer_switch(
11381                                 alc880_fixed_pin_idx(pin));
11382
11383                 sprintf(name, "%s Playback Volume", pfx);
11384                 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
11385                                   HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
11386                 if (err < 0)
11387                         return err;
11388                 sprintf(name, "%s Playback Switch", pfx);
11389                 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
11390                                   HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
11391                 if (err < 0)
11392                         return err;
11393         } else if (alc880_is_multi_pin(pin)) {
11394                 /* set manual connection */
11395                 /* we have only a switch on HP-out PIN */
11396                 sprintf(name, "%s Playback Switch", pfx);
11397                 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
11398                                   HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
11399                 if (err < 0)
11400                         return err;
11401         }
11402         return 0;
11403 }
11404
11405 /* parse the BIOS configuration and set up the alc_spec
11406  * return 1 if successful, 0 if the proper config is not found,
11407  * or a negative error code
11408  * Based on ALC880 version - had to change it to override
11409  * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
11410 static int alc861vd_parse_auto_config(struct hda_codec *codec)
11411 {
11412         struct alc_spec *spec = codec->spec;
11413         int err;
11414         static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
11415
11416         err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
11417                                            alc861vd_ignore);
11418         if (err < 0)
11419                 return err;
11420         if (!spec->autocfg.line_outs)
11421                 return 0; /* can't find valid BIOS pin config */
11422
11423         err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
11424         if (err < 0)
11425                 return err;
11426         err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
11427         if (err < 0)
11428                 return err;
11429         err = alc861vd_auto_create_extra_out(spec,
11430                                              spec->autocfg.speaker_pins[0],
11431                                              "Speaker");
11432         if (err < 0)
11433                 return err;
11434         err = alc861vd_auto_create_extra_out(spec,
11435                                              spec->autocfg.hp_pins[0],
11436                                              "Headphone");
11437         if (err < 0)
11438                 return err;
11439         err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg);
11440         if (err < 0)
11441                 return err;
11442
11443         spec->multiout.max_channels = spec->multiout.num_dacs * 2;
11444
11445         if (spec->autocfg.dig_out_pin)
11446                 spec->multiout.dig_out_nid = ALC861VD_DIGOUT_NID;
11447
11448         if (spec->kctl_alloc)
11449                 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
11450
11451         spec->init_verbs[spec->num_init_verbs++]
11452                 = alc861vd_volume_init_verbs;
11453
11454         spec->num_mux_defs = 1;
11455         spec->input_mux = &spec->private_imux;
11456
11457         err = alc_auto_add_mic_boost(codec);
11458         if (err < 0)
11459                 return err;
11460
11461         return 1;
11462 }
11463
11464 /* additional initialization for auto-configuration model */
11465 static void alc861vd_auto_init(struct hda_codec *codec)
11466 {
11467         alc861vd_auto_init_multi_out(codec);
11468         alc861vd_auto_init_hp_out(codec);
11469         alc861vd_auto_init_analog_input(codec);
11470 }
11471
11472 static int patch_alc861vd(struct hda_codec *codec)
11473 {
11474         struct alc_spec *spec;
11475         int err, board_config;
11476
11477         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
11478         if (spec == NULL)
11479                 return -ENOMEM;
11480
11481         codec->spec = spec;
11482
11483         board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
11484                                                   alc861vd_models,
11485                                                   alc861vd_cfg_tbl);
11486
11487         if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
11488                 printk(KERN_INFO "hda_codec: Unknown model for ALC660VD/"
11489                         "ALC861VD, trying auto-probe from BIOS...\n");
11490                 board_config = ALC861VD_AUTO;
11491         }
11492
11493         if (board_config == ALC861VD_AUTO) {
11494                 /* automatic parse from the BIOS config */
11495                 err = alc861vd_parse_auto_config(codec);
11496                 if (err < 0) {
11497                         alc_free(codec);
11498                         return err;
11499                 } else if (!err) {
11500                         printk(KERN_INFO
11501                                "hda_codec: Cannot set up configuration "
11502                                "from BIOS.  Using base mode...\n");
11503                         board_config = ALC861VD_3ST;
11504                 }
11505         }
11506
11507         if (board_config != ALC861VD_AUTO)
11508                 setup_preset(spec, &alc861vd_presets[board_config]);
11509
11510         spec->stream_name_analog = "ALC861VD Analog";
11511         spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
11512         spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
11513
11514         spec->stream_name_digital = "ALC861VD Digital";
11515         spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
11516         spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
11517
11518         spec->adc_nids = alc861vd_adc_nids;
11519         spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
11520
11521         spec->mixers[spec->num_mixers] = alc861vd_capture_mixer;
11522         spec->num_mixers++;
11523
11524         codec->patch_ops = alc_patch_ops;
11525
11526         if (board_config == ALC861VD_AUTO)
11527                 spec->init_hook = alc861vd_auto_init;
11528 #ifdef CONFIG_SND_HDA_POWER_SAVE
11529         if (!spec->loopback.amplist)
11530                 spec->loopback.amplist = alc861vd_loopbacks;
11531 #endif
11532
11533         return 0;
11534 }
11535
11536 /*
11537  * ALC662 support
11538  *
11539  * ALC662 is almost identical with ALC880 but has cleaner and more flexible
11540  * configuration.  Each pin widget can choose any input DACs and a mixer.
11541  * Each ADC is connected from a mixer of all inputs.  This makes possible
11542  * 6-channel independent captures.
11543  *
11544  * In addition, an independent DAC for the multi-playback (not used in this
11545  * driver yet).
11546  */
11547 #define ALC662_DIGOUT_NID       0x06
11548 #define ALC662_DIGIN_NID        0x0a
11549
11550 static hda_nid_t alc662_dac_nids[4] = {
11551         /* front, rear, clfe, rear_surr */
11552         0x02, 0x03, 0x04
11553 };
11554
11555 static hda_nid_t alc662_adc_nids[1] = {
11556         /* ADC1-2 */
11557         0x09,
11558 };
11559 /* input MUX */
11560 /* FIXME: should be a matrix-type input source selection */
11561
11562 static struct hda_input_mux alc662_capture_source = {
11563         .num_items = 4,
11564         .items = {
11565                 { "Mic", 0x0 },
11566                 { "Front Mic", 0x1 },
11567                 { "Line", 0x2 },
11568                 { "CD", 0x4 },
11569         },
11570 };
11571
11572 static struct hda_input_mux alc662_lenovo_101e_capture_source = {
11573         .num_items = 2,
11574         .items = {
11575                 { "Mic", 0x1 },
11576                 { "Line", 0x2 },
11577         },
11578 };
11579
11580 static struct hda_input_mux alc662_eeepc_capture_source = {
11581         .num_items = 2,
11582         .items = {
11583                 { "i-Mic", 0x1 },
11584                 { "e-Mic", 0x0 },
11585         },
11586 };
11587
11588 #define alc662_mux_enum_info alc_mux_enum_info
11589 #define alc662_mux_enum_get alc_mux_enum_get
11590
11591 static int alc662_mux_enum_put(struct snd_kcontrol *kcontrol,
11592                                struct snd_ctl_elem_value *ucontrol)
11593 {
11594         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11595         struct alc_spec *spec = codec->spec;
11596         const struct hda_input_mux *imux = spec->input_mux;
11597         unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
11598         static hda_nid_t capture_mixers[2] = { 0x23, 0x22 };
11599         hda_nid_t nid = capture_mixers[adc_idx];
11600         unsigned int *cur_val = &spec->cur_mux[adc_idx];
11601         unsigned int i, idx;
11602
11603         idx = ucontrol->value.enumerated.item[0];
11604         if (idx >= imux->num_items)
11605                 idx = imux->num_items - 1;
11606         if (*cur_val == idx)
11607                 return 0;
11608         for (i = 0; i < imux->num_items; i++) {
11609                 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
11610                 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
11611                                          imux->items[i].index,
11612                                          HDA_AMP_MUTE, v);
11613         }
11614         *cur_val = idx;
11615         return 1;
11616 }
11617 /*
11618  * 2ch mode
11619  */
11620 static struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
11621         { 2, NULL }
11622 };
11623
11624 /*
11625  * 2ch mode
11626  */
11627 static struct hda_verb alc662_3ST_ch2_init[] = {
11628         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
11629         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
11630         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
11631         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
11632         { } /* end */
11633 };
11634
11635 /*
11636  * 6ch mode
11637  */
11638 static struct hda_verb alc662_3ST_ch6_init[] = {
11639         { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11640         { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
11641         { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
11642         { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11643         { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
11644         { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
11645         { } /* end */
11646 };
11647
11648 static struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
11649         { 2, alc662_3ST_ch2_init },
11650         { 6, alc662_3ST_ch6_init },
11651 };
11652
11653 /*
11654  * 2ch mode
11655  */
11656 static struct hda_verb alc662_sixstack_ch6_init[] = {
11657         { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
11658         { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
11659         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11660         { } /* end */
11661 };
11662
11663 /*
11664  * 6ch mode
11665  */
11666 static struct hda_verb alc662_sixstack_ch8_init[] = {
11667         { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11668         { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11669         { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
11670         { } /* end */
11671 };
11672
11673 static struct hda_channel_mode alc662_5stack_modes[2] = {
11674         { 2, alc662_sixstack_ch6_init },
11675         { 6, alc662_sixstack_ch8_init },
11676 };
11677
11678 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
11679  *                 Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
11680  */
11681
11682 static struct snd_kcontrol_new alc662_base_mixer[] = {
11683         /* output mixer control */
11684         HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
11685         HDA_CODEC_MUTE("Front Playback Switch", 0x02, 0x0, HDA_OUTPUT),
11686         HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
11687         HDA_CODEC_MUTE("Surround Playback Switch", 0x03, 0x0, HDA_OUTPUT),
11688         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
11689         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
11690         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT),
11691         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT),
11692         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11693
11694         /*Input mixer control */
11695         HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
11696         HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
11697         HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
11698         HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
11699         HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
11700         HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
11701         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
11702         HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
11703
11704         /* Capture mixer control */
11705         HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
11706         HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
11707         {
11708                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11709                 .name = "Capture Source",
11710                 .count = 1,
11711                 .info = alc_mux_enum_info,
11712                 .get = alc_mux_enum_get,
11713                 .put = alc_mux_enum_put,
11714         },
11715         { } /* end */
11716 };
11717
11718 static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
11719         HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11720         HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
11721         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11722         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11723         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11724         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11725         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11726         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11727         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11728         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11729         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
11730         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
11731         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
11732         HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
11733         HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
11734         {
11735                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11736                 /* .name = "Capture Source", */
11737                 .name = "Input Source",
11738                 .count = 1,
11739                 .info = alc662_mux_enum_info,
11740                 .get = alc662_mux_enum_get,
11741                 .put = alc662_mux_enum_put,
11742         },
11743         { } /* end */
11744 };
11745
11746 static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
11747         HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11748         HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
11749         HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
11750         HDA_BIND_MUTE("Surround Playback Switch", 0x03, 2, HDA_INPUT),
11751         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
11752         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
11753         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT),
11754         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT),
11755         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11756         HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11757         HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11758         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11759         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11760         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11761         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11762         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11763         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
11764         HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
11765         HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
11766         HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
11767         HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
11768         {
11769                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11770                 /* .name = "Capture Source", */
11771                 .name = "Input Source",
11772                 .count = 1,
11773                 .info = alc662_mux_enum_info,
11774                 .get = alc662_mux_enum_get,
11775                 .put = alc662_mux_enum_put,
11776         },
11777         { } /* end */
11778 };
11779
11780 static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
11781         HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11782         HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
11783         HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
11784         HDA_BIND_MUTE("iSpeaker Playback Switch", 0x03, 2, HDA_INPUT),
11785         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11786         HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11787         HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11788         HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11789         HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
11790         HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
11791         HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
11792         {
11793                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11794                 /* .name = "Capture Source", */
11795                 .name = "Input Source",
11796                 .count = 1,
11797                 .info = alc662_mux_enum_info,
11798                 .get = alc662_mux_enum_get,
11799                 .put = alc662_mux_enum_put,
11800         },
11801         { } /* end */
11802 };
11803
11804 static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
11805         HDA_CODEC_MUTE("iSpeaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11806
11807         HDA_CODEC_VOLUME("LineOut Playback Volume", 0x02, 0x0, HDA_OUTPUT),
11808         HDA_CODEC_MUTE("LineOut Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11809
11810         HDA_CODEC_VOLUME("e-Mic Boost", 0x18, 0, HDA_INPUT),
11811         HDA_CODEC_VOLUME("e-Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11812         HDA_CODEC_MUTE("e-Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11813
11814         HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT),
11815         HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11816         HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
11817         { } /* end */
11818 };
11819
11820 static struct snd_kcontrol_new alc662_chmode_mixer[] = {
11821         {
11822                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11823                 .name = "Channel Mode",
11824                 .info = alc_ch_mode_info,
11825                 .get = alc_ch_mode_get,
11826                 .put = alc_ch_mode_put,
11827         },
11828         { } /* end */
11829 };
11830
11831 static struct hda_verb alc662_init_verbs[] = {
11832         /* ADC: mute amp left and right */
11833         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11834         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11835         /* Front mixer: unmute input/output amp left and right (volume = 0) */
11836
11837         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11838         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11839         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11840         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11841         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11842
11843         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11844         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11845         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11846         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11847         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11848         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11849
11850         /* Front Pin: output 0 (0x0c) */
11851         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11852         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11853
11854         /* Rear Pin: output 1 (0x0d) */
11855         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11856         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11857
11858         /* CLFE Pin: output 2 (0x0e) */
11859         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11860         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11861
11862         /* Mic (rear) pin: input vref at 80% */
11863         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11864         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11865         /* Front Mic pin: input vref at 80% */
11866         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11867         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11868         /* Line In pin: input */
11869         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11870         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11871         /* Line-2 In: Headphone output (output 0 - 0x0c) */
11872         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11873         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11874         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11875         /* CD pin widget for input */
11876         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11877
11878         /* FIXME: use matrix-type input source selection */
11879         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
11880         /* Input mixer */
11881         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11882         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11883         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
11884         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
11885
11886         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11887         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11888         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
11889         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
11890         { }
11891 };
11892
11893 static struct hda_verb alc662_sue_init_verbs[] = {
11894         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
11895         {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
11896         {}
11897 };
11898
11899 static struct hda_verb alc662_eeepc_sue_init_verbs[] = {
11900         {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11901         {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11902         {}
11903 };
11904
11905 /*
11906  * generic initialization of ADC, input mixers and output mixers
11907  */
11908 static struct hda_verb alc662_auto_init_verbs[] = {
11909         /*
11910          * Unmute ADC and set the default input to mic-in
11911          */
11912         {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11913         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11914
11915         /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
11916          * mixer widget
11917          * Note: PASD motherboards uses the Line In 2 as the input for front
11918          * panel mic (mic 2)
11919          */
11920         /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
11921         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11922         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11923         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11924         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11925         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11926
11927         /*
11928          * Set up output mixers (0x0c - 0x0f)
11929          */
11930         /* set vol=0 to output mixers */
11931         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11932         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11933         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11934
11935         /* set up input amps for analog loopback */
11936         /* Amp Indices: DAC = 0, mixer = 1 */
11937         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11938         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11939         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11940         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11941         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11942         {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11943
11944
11945         /* FIXME: use matrix-type input source selection */
11946         /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
11947         /* Input mixer */
11948         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11949         {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11950         { }
11951 };
11952
11953 /* capture mixer elements */
11954 static struct snd_kcontrol_new alc662_capture_mixer[] = {
11955         HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
11956         HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
11957         {
11958                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11959                 /* The multiple "Capture Source" controls confuse alsamixer
11960                  * So call somewhat different..
11961                  * FIXME: the controls appear in the "playback" view!
11962                  */
11963                 /* .name = "Capture Source", */
11964                 .name = "Input Source",
11965                 .count = 1,
11966                 .info = alc882_mux_enum_info,
11967                 .get = alc882_mux_enum_get,
11968                 .put = alc882_mux_enum_put,
11969         },
11970         { } /* end */
11971 };
11972
11973 static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
11974 {
11975         unsigned int present;
11976         unsigned char bits;
11977
11978         present = snd_hda_codec_read(codec, 0x14, 0,
11979                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11980         bits = present ? HDA_AMP_MUTE : 0;
11981         snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
11982                                  HDA_AMP_MUTE, bits);
11983 }
11984
11985 static void alc662_lenovo_101e_all_automute(struct hda_codec *codec)
11986 {
11987         unsigned int present;
11988         unsigned char bits;
11989
11990         present = snd_hda_codec_read(codec, 0x1b, 0,
11991                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11992         bits = present ? HDA_AMP_MUTE : 0;
11993         snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
11994                                  HDA_AMP_MUTE, bits);
11995         snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11996                                  HDA_AMP_MUTE, bits);
11997 }
11998
11999 static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec,
12000                                            unsigned int res)
12001 {
12002         if ((res >> 26) == ALC880_HP_EVENT)
12003                 alc662_lenovo_101e_all_automute(codec);
12004         if ((res >> 26) == ALC880_FRONT_EVENT)
12005                 alc662_lenovo_101e_ispeaker_automute(codec);
12006 }
12007
12008 static void alc662_eeepc_mic_automute(struct hda_codec *codec)
12009 {
12010         unsigned int present;
12011
12012         present = snd_hda_codec_read(codec, 0x18, 0,
12013                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12014         snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
12015                             0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
12016         snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
12017                             0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
12018         snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
12019                             0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
12020         snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
12021                             0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
12022 }
12023
12024 /* unsolicited event for HP jack sensing */
12025 static void alc662_eeepc_unsol_event(struct hda_codec *codec,
12026                                      unsigned int res)
12027 {
12028         if ((res >> 26) == ALC880_HP_EVENT)
12029                 alc262_hippo1_automute( codec );
12030
12031         if ((res >> 26) == ALC880_MIC_EVENT)
12032                 alc662_eeepc_mic_automute(codec);
12033 }
12034
12035 static void alc662_eeepc_inithook(struct hda_codec *codec)
12036 {
12037         alc262_hippo1_automute( codec );
12038         alc662_eeepc_mic_automute(codec);
12039 }
12040
12041 #ifdef CONFIG_SND_HDA_POWER_SAVE
12042 #define alc662_loopbacks        alc880_loopbacks
12043 #endif
12044
12045
12046 /* pcm configuration: identiacal with ALC880 */
12047 #define alc662_pcm_analog_playback      alc880_pcm_analog_playback
12048 #define alc662_pcm_analog_capture       alc880_pcm_analog_capture
12049 #define alc662_pcm_digital_playback     alc880_pcm_digital_playback
12050 #define alc662_pcm_digital_capture      alc880_pcm_digital_capture
12051
12052 /*
12053  * configuration and preset
12054  */
12055 static const char *alc662_models[ALC662_MODEL_LAST] = {
12056         [ALC662_3ST_2ch_DIG]    = "3stack-dig",
12057         [ALC662_3ST_6ch_DIG]    = "3stack-6ch-dig",
12058         [ALC662_3ST_6ch]        = "3stack-6ch",
12059         [ALC662_5ST_DIG]        = "6stack-dig",
12060         [ALC662_LENOVO_101E]    = "lenovo-101e",
12061         [ALC662_AUTO]           = "auto",
12062 };
12063
12064 static struct snd_pci_quirk alc662_cfg_tbl[] = {
12065         SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
12066         SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
12067         {}
12068 };
12069
12070 static struct alc_config_preset alc662_presets[] = {
12071         [ALC662_3ST_2ch_DIG] = {
12072                 .mixers = { alc662_3ST_2ch_mixer, alc662_capture_mixer },
12073                 .init_verbs = { alc662_init_verbs },
12074                 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
12075                 .dac_nids = alc662_dac_nids,
12076                 .dig_out_nid = ALC662_DIGOUT_NID,
12077                 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
12078                 .adc_nids = alc662_adc_nids,
12079                 .dig_in_nid = ALC662_DIGIN_NID,
12080                 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
12081                 .channel_mode = alc662_3ST_2ch_modes,
12082                 .input_mux = &alc662_capture_source,
12083         },
12084         [ALC662_3ST_6ch_DIG] = {
12085                 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer,
12086                             alc662_capture_mixer },
12087                 .init_verbs = { alc662_init_verbs },
12088                 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
12089                 .dac_nids = alc662_dac_nids,
12090                 .dig_out_nid = ALC662_DIGOUT_NID,
12091                 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
12092                 .adc_nids = alc662_adc_nids,
12093                 .dig_in_nid = ALC662_DIGIN_NID,
12094                 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
12095                 .channel_mode = alc662_3ST_6ch_modes,
12096                 .need_dac_fix = 1,
12097                 .input_mux = &alc662_capture_source,
12098         },
12099         [ALC662_3ST_6ch] = {
12100                 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer,
12101                             alc662_capture_mixer },
12102                 .init_verbs = { alc662_init_verbs },
12103                 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
12104                 .dac_nids = alc662_dac_nids,
12105                 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
12106                 .adc_nids = alc662_adc_nids,
12107                 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
12108                 .channel_mode = alc662_3ST_6ch_modes,
12109                 .need_dac_fix = 1,
12110                 .input_mux = &alc662_capture_source,
12111         },
12112         [ALC662_5ST_DIG] = {
12113                 .mixers = { alc662_base_mixer, alc662_chmode_mixer,
12114                             alc662_capture_mixer },
12115                 .init_verbs = { alc662_init_verbs },
12116                 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
12117                 .dac_nids = alc662_dac_nids,
12118                 .dig_out_nid = ALC662_DIGOUT_NID,
12119                 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
12120                 .adc_nids = alc662_adc_nids,
12121                 .dig_in_nid = ALC662_DIGIN_NID,
12122                 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
12123                 .channel_mode = alc662_5stack_modes,
12124                 .input_mux = &alc662_capture_source,
12125         },
12126         [ALC662_LENOVO_101E] = {
12127                 .mixers = { alc662_lenovo_101e_mixer, alc662_capture_mixer },
12128                 .init_verbs = { alc662_init_verbs, alc662_sue_init_verbs },
12129                 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
12130                 .dac_nids = alc662_dac_nids,
12131                 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
12132                 .adc_nids = alc662_adc_nids,
12133                 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
12134                 .channel_mode = alc662_3ST_2ch_modes,
12135                 .input_mux = &alc662_lenovo_101e_capture_source,
12136                 .unsol_event = alc662_lenovo_101e_unsol_event,
12137                 .init_hook = alc662_lenovo_101e_all_automute,
12138         },
12139         [ALC662_ASUS_EEEPC_P701] = {
12140                 .mixers = { alc662_eeepc_p701_mixer, alc662_capture_mixer },
12141                 .init_verbs = { alc662_init_verbs,
12142                                 alc662_eeepc_sue_init_verbs },
12143                 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
12144                 .dac_nids = alc662_dac_nids,
12145                 .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
12146                 .adc_nids = alc662_adc_nids,
12147                 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
12148                 .channel_mode = alc662_3ST_2ch_modes,
12149                 .input_mux = &alc662_eeepc_capture_source,
12150                 .unsol_event = alc662_eeepc_unsol_event,
12151                 .init_hook = alc662_eeepc_inithook,
12152         },
12153
12154 };
12155
12156
12157 /*
12158  * BIOS auto configuration
12159  */
12160
12161 /* add playback controls from the parsed DAC table */
12162 static int alc662_auto_create_multi_out_ctls(struct alc_spec *spec,
12163                                              const struct auto_pin_cfg *cfg)
12164 {
12165         char name[32];
12166         static const char *chname[4] = {
12167                 "Front", "Surround", NULL /*CLFE*/, "Side"
12168         };
12169         hda_nid_t nid;
12170         int i, err;
12171
12172         for (i = 0; i < cfg->line_outs; i++) {
12173                 if (!spec->multiout.dac_nids[i])
12174                         continue;
12175                 nid = alc880_idx_to_dac(i);
12176                 if (i == 2) {
12177                         /* Center/LFE */
12178                         err = add_control(spec, ALC_CTL_WIDGET_VOL,
12179                                           "Center Playback Volume",
12180                                           HDA_COMPOSE_AMP_VAL(nid, 1, 0,
12181                                                               HDA_OUTPUT));
12182                         if (err < 0)
12183                                 return err;
12184                         err = add_control(spec, ALC_CTL_WIDGET_VOL,
12185                                           "LFE Playback Volume",
12186                                           HDA_COMPOSE_AMP_VAL(nid, 2, 0,
12187                                                               HDA_OUTPUT));
12188                         if (err < 0)
12189                                 return err;
12190                         err = add_control(spec, ALC_CTL_BIND_MUTE,
12191                                           "Center Playback Switch",
12192                                           HDA_COMPOSE_AMP_VAL(nid, 1, 2,
12193                                                               HDA_INPUT));
12194                         if (err < 0)
12195                                 return err;
12196                         err = add_control(spec, ALC_CTL_BIND_MUTE,
12197                                           "LFE Playback Switch",
12198                                           HDA_COMPOSE_AMP_VAL(nid, 2, 2,
12199                                                               HDA_INPUT));
12200                         if (err < 0)
12201                                 return err;
12202                 } else {
12203                         sprintf(name, "%s Playback Volume", chname[i]);
12204                         err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
12205                                           HDA_COMPOSE_AMP_VAL(nid, 3, 0,
12206                                                               HDA_OUTPUT));
12207                         if (err < 0)
12208                                 return err;
12209                         sprintf(name, "%s Playback Switch", chname[i]);
12210                         err = add_control(spec, ALC_CTL_BIND_MUTE, name,
12211                                           HDA_COMPOSE_AMP_VAL(nid, 3, 2,
12212                                                               HDA_INPUT));
12213                         if (err < 0)
12214                                 return err;
12215                 }
12216         }
12217         return 0;
12218 }
12219
12220 /* add playback controls for speaker and HP outputs */
12221 static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
12222                                         const char *pfx)
12223 {
12224         hda_nid_t nid;
12225         int err;
12226         char name[32];
12227
12228         if (!pin)
12229                 return 0;
12230
12231         if (alc880_is_fixed_pin(pin)) {
12232                 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
12233                 /* printk("DAC nid=%x\n",nid); */
12234                 /* specify the DAC as the extra output */
12235                 if (!spec->multiout.hp_nid)
12236                         spec->multiout.hp_nid = nid;
12237                 else
12238                         spec->multiout.extra_out_nid[0] = nid;
12239                 /* control HP volume/switch on the output mixer amp */
12240                 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
12241                 sprintf(name, "%s Playback Volume", pfx);
12242                 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
12243                                   HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
12244                 if (err < 0)
12245                         return err;
12246                 sprintf(name, "%s Playback Switch", pfx);
12247                 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
12248                                   HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
12249                 if (err < 0)
12250                         return err;
12251         } else if (alc880_is_multi_pin(pin)) {
12252                 /* set manual connection */
12253                 /* we have only a switch on HP-out PIN */
12254                 sprintf(name, "%s Playback Switch", pfx);
12255                 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
12256                                   HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
12257                 if (err < 0)
12258                         return err;
12259         }
12260         return 0;
12261 }
12262
12263 /* create playback/capture controls for input pins */
12264 static int alc662_auto_create_analog_input_ctls(struct alc_spec *spec,
12265                                                 const struct auto_pin_cfg *cfg)
12266 {
12267         struct hda_input_mux *imux = &spec->private_imux;
12268         int i, err, idx;
12269
12270         for (i = 0; i < AUTO_PIN_LAST; i++) {
12271                 if (alc880_is_input_pin(cfg->input_pins[i])) {
12272                         idx = alc880_input_pin_idx(cfg->input_pins[i]);
12273                         err = new_analog_input(spec, cfg->input_pins[i],
12274                                                auto_pin_cfg_labels[i],
12275                                                idx, 0x0b);
12276                         if (err < 0)
12277                                 return err;
12278                         imux->items[imux->num_items].label =
12279                                 auto_pin_cfg_labels[i];
12280                         imux->items[imux->num_items].index =
12281                                 alc880_input_pin_idx(cfg->input_pins[i]);
12282                         imux->num_items++;
12283                 }
12284         }
12285         return 0;
12286 }
12287
12288 static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
12289                                               hda_nid_t nid, int pin_type,
12290                                               int dac_idx)
12291 {
12292         /* set as output */
12293         snd_hda_codec_write(codec, nid, 0,
12294                             AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
12295         snd_hda_codec_write(codec, nid, 0,
12296                             AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
12297         /* need the manual connection? */
12298         if (alc880_is_multi_pin(nid)) {
12299                 struct alc_spec *spec = codec->spec;
12300                 int idx = alc880_multi_pin_idx(nid);
12301                 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
12302                                     AC_VERB_SET_CONNECT_SEL,
12303                                     alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
12304         }
12305 }
12306
12307 static void alc662_auto_init_multi_out(struct hda_codec *codec)
12308 {
12309         struct alc_spec *spec = codec->spec;
12310         int i;
12311
12312         for (i = 0; i <= HDA_SIDE; i++) {
12313                 hda_nid_t nid = spec->autocfg.line_out_pins[i];
12314                 int pin_type = get_pin_type(spec->autocfg.line_out_type);
12315                 if (nid)
12316                         alc662_auto_set_output_and_unmute(codec, nid, pin_type,
12317                                                           i);
12318         }
12319 }
12320
12321 static void alc662_auto_init_hp_out(struct hda_codec *codec)
12322 {
12323         struct alc_spec *spec = codec->spec;
12324         hda_nid_t pin;
12325
12326         pin = spec->autocfg.hp_pins[0];
12327         if (pin) /* connect to front */
12328                 /* use dac 0 */
12329                 alc662_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
12330 }
12331
12332 #define alc662_is_input_pin(nid)        alc880_is_input_pin(nid)
12333 #define ALC662_PIN_CD_NID               ALC880_PIN_CD_NID
12334
12335 static void alc662_auto_init_analog_input(struct hda_codec *codec)
12336 {
12337         struct alc_spec *spec = codec->spec;
12338         int i;
12339
12340         for (i = 0; i < AUTO_PIN_LAST; i++) {
12341                 hda_nid_t nid = spec->autocfg.input_pins[i];
12342                 if (alc662_is_input_pin(nid)) {
12343                         snd_hda_codec_write(codec, nid, 0,
12344                                             AC_VERB_SET_PIN_WIDGET_CONTROL,
12345                                             (i <= AUTO_PIN_FRONT_MIC ?
12346                                              PIN_VREF80 : PIN_IN));
12347                         if (nid != ALC662_PIN_CD_NID)
12348                                 snd_hda_codec_write(codec, nid, 0,
12349                                                     AC_VERB_SET_AMP_GAIN_MUTE,
12350                                                     AMP_OUT_MUTE);
12351                 }
12352         }
12353 }
12354
12355 static int alc662_parse_auto_config(struct hda_codec *codec)
12356 {
12357         struct alc_spec *spec = codec->spec;
12358         int err;
12359         static hda_nid_t alc662_ignore[] = { 0x1d, 0 };
12360
12361         err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
12362                                            alc662_ignore);
12363         if (err < 0)
12364                 return err;
12365         if (!spec->autocfg.line_outs)
12366                 return 0; /* can't find valid BIOS pin config */
12367
12368         err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
12369         if (err < 0)
12370                 return err;
12371         err = alc662_auto_create_multi_out_ctls(spec, &spec->autocfg);
12372         if (err < 0)
12373                 return err;
12374         err = alc662_auto_create_extra_out(spec,
12375                                            spec->autocfg.speaker_pins[0],
12376                                            "Speaker");
12377         if (err < 0)
12378                 return err;
12379         err = alc662_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
12380                                            "Headphone");
12381         if (err < 0)
12382                 return err;
12383         err = alc662_auto_create_analog_input_ctls(spec, &spec->autocfg);
12384         if (err < 0)
12385                 return err;
12386
12387         spec->multiout.max_channels = spec->multiout.num_dacs * 2;
12388
12389         if (spec->autocfg.dig_out_pin)
12390                 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
12391
12392         if (spec->kctl_alloc)
12393                 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
12394
12395         spec->num_mux_defs = 1;
12396         spec->input_mux = &spec->private_imux;
12397         
12398         spec->init_verbs[spec->num_init_verbs++] = alc662_auto_init_verbs;
12399         spec->mixers[spec->num_mixers] = alc662_capture_mixer;
12400         spec->num_mixers++;
12401         return 1;
12402 }
12403
12404 /* additional initialization for auto-configuration model */
12405 static void alc662_auto_init(struct hda_codec *codec)
12406 {
12407         alc662_auto_init_multi_out(codec);
12408         alc662_auto_init_hp_out(codec);
12409         alc662_auto_init_analog_input(codec);
12410 }
12411
12412 static int patch_alc662(struct hda_codec *codec)
12413 {
12414         struct alc_spec *spec;
12415         int err, board_config;
12416
12417         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
12418         if (!spec)
12419                 return -ENOMEM;
12420
12421         codec->spec = spec;
12422
12423         board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
12424                                                   alc662_models,
12425                                                   alc662_cfg_tbl);
12426         if (board_config < 0) {
12427                 printk(KERN_INFO "hda_codec: Unknown model for ALC662, "
12428                        "trying auto-probe from BIOS...\n");
12429                 board_config = ALC662_AUTO;
12430         }
12431
12432         if (board_config == ALC662_AUTO) {
12433                 /* automatic parse from the BIOS config */
12434                 err = alc662_parse_auto_config(codec);
12435                 if (err < 0) {
12436                         alc_free(codec);
12437                         return err;
12438                 } else if (!err) {
12439                         printk(KERN_INFO
12440                                "hda_codec: Cannot set up configuration "
12441                                "from BIOS.  Using base mode...\n");
12442                         board_config = ALC662_3ST_2ch_DIG;
12443                 }
12444         }
12445
12446         if (board_config != ALC662_AUTO)
12447                 setup_preset(spec, &alc662_presets[board_config]);
12448
12449         spec->stream_name_analog = "ALC662 Analog";
12450         spec->stream_analog_playback = &alc662_pcm_analog_playback;
12451         spec->stream_analog_capture = &alc662_pcm_analog_capture;
12452
12453         spec->stream_name_digital = "ALC662 Digital";
12454         spec->stream_digital_playback = &alc662_pcm_digital_playback;
12455         spec->stream_digital_capture = &alc662_pcm_digital_capture;
12456
12457         if (!spec->adc_nids && spec->input_mux) {
12458                 spec->adc_nids = alc662_adc_nids;
12459                 spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
12460         }
12461
12462         codec->patch_ops = alc_patch_ops;
12463         if (board_config == ALC662_AUTO)
12464                 spec->init_hook = alc662_auto_init;
12465 #ifdef CONFIG_SND_HDA_POWER_SAVE
12466         if (!spec->loopback.amplist)
12467                 spec->loopback.amplist = alc662_loopbacks;
12468 #endif
12469
12470         return 0;
12471 }
12472
12473 /*
12474  * patch entries
12475  */
12476 struct hda_codec_preset snd_hda_preset_realtek[] = {
12477         { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
12478         { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
12479         { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
12480         { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
12481           .patch = patch_alc861 },
12482         { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
12483         { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
12484         { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
12485         { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
12486           .patch = patch_alc883 },
12487         { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
12488           .patch = patch_alc662 },
12489         { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
12490         { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
12491         { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc883 },
12492         { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
12493         { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc883 },
12494         {} /* terminator */
12495 };