~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/sound/pci/hda/patch_analog.c

Version: ~ [ linux-5.9 ] ~ [ linux-5.8.14 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.70 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.150 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.200 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.238 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.238 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.140 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.85 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  * HD audio interface patch for AD1882, AD1884, AD1981HD, AD1983, AD1984,
  3  *   AD1986A, AD1988
  4  *
  5  * Copyright (c) 2005-2007 Takashi Iwai <tiwai@suse.de>
  6  *
  7  *  This driver is free software; you can redistribute it and/or modify
  8  *  it under the terms of the GNU General Public License as published by
  9  *  the Free Software Foundation; either version 2 of the License, or
 10  *  (at your option) any later version.
 11  *
 12  *  This driver is distributed in the hope that it will be useful,
 13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 15  *  GNU General Public License for more details.
 16  *
 17  *  You should have received a copy of the GNU General Public License
 18  *  along with this program; if not, write to the Free Software
 19  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 20  */
 21 
 22 #include <linux/init.h>
 23 #include <linux/slab.h>
 24 #include <linux/pci.h>
 25 #include <linux/module.h>
 26 
 27 #include <sound/core.h>
 28 #include "hda_codec.h"
 29 #include "hda_local.h"
 30 #include "hda_auto_parser.h"
 31 #include "hda_beep.h"
 32 #include "hda_jack.h"
 33 #include "hda_generic.h"
 34 
 35 #define ENABLE_AD_STATIC_QUIRKS
 36 
 37 struct ad198x_spec {
 38         struct hda_gen_spec gen;
 39 
 40         /* for auto parser */
 41         int smux_paths[4];
 42         unsigned int cur_smux;
 43         hda_nid_t eapd_nid;
 44 
 45         unsigned int beep_amp;  /* beep amp value, set via set_beep_amp() */
 46 
 47 #ifdef ENABLE_AD_STATIC_QUIRKS
 48         const struct snd_kcontrol_new *mixers[6];
 49         int num_mixers;
 50         const struct hda_verb *init_verbs[6];   /* initialization verbs
 51                                                  * don't forget NULL termination!
 52                                                  */
 53         unsigned int num_init_verbs;
 54 
 55         /* playback */
 56         struct hda_multi_out multiout;  /* playback set-up
 57                                          * max_channels, dacs must be set
 58                                          * dig_out_nid and hp_nid are optional
 59                                          */
 60         unsigned int cur_eapd;
 61         unsigned int need_dac_fix;
 62 
 63         /* capture */
 64         unsigned int num_adc_nids;
 65         const hda_nid_t *adc_nids;
 66         hda_nid_t dig_in_nid;           /* digital-in NID; optional */
 67 
 68         /* capture source */
 69         const struct hda_input_mux *input_mux;
 70         const hda_nid_t *capsrc_nids;
 71         unsigned int cur_mux[3];
 72 
 73         /* channel model */
 74         const struct hda_channel_mode *channel_mode;
 75         int num_channel_mode;
 76 
 77         /* PCM information */
 78         struct hda_pcm pcm_rec[3];      /* used in alc_build_pcms() */
 79 
 80         unsigned int spdif_route;
 81 
 82         unsigned int jack_present: 1;
 83         unsigned int inv_jack_detect: 1;/* inverted jack-detection */
 84         unsigned int analog_beep: 1;    /* analog beep input present */
 85         unsigned int avoid_init_slave_vol:1;
 86 
 87 #ifdef CONFIG_PM
 88         struct hda_loopback_check loopback;
 89 #endif
 90         /* for virtual master */
 91         hda_nid_t vmaster_nid;
 92         const char * const *slave_vols;
 93         const char * const *slave_sws;
 94 #endif /* ENABLE_AD_STATIC_QUIRKS */
 95 };
 96 
 97 #ifdef ENABLE_AD_STATIC_QUIRKS
 98 /*
 99  * input MUX handling (common part)
100  */
101 static int ad198x_mux_enum_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
102 {
103         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
104         struct ad198x_spec *spec = codec->spec;
105 
106         return snd_hda_input_mux_info(spec->input_mux, uinfo);
107 }
108 
109 static int ad198x_mux_enum_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
110 {
111         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
112         struct ad198x_spec *spec = codec->spec;
113         unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
114 
115         ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
116         return 0;
117 }
118 
119 static int ad198x_mux_enum_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
120 {
121         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
122         struct ad198x_spec *spec = codec->spec;
123         unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
124 
125         return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol,
126                                      spec->capsrc_nids[adc_idx],
127                                      &spec->cur_mux[adc_idx]);
128 }
129 
130 /*
131  * initialization (common callbacks)
132  */
133 static int ad198x_init(struct hda_codec *codec)
134 {
135         struct ad198x_spec *spec = codec->spec;
136         int i;
137 
138         for (i = 0; i < spec->num_init_verbs; i++)
139                 snd_hda_sequence_write(codec, spec->init_verbs[i]);
140         return 0;
141 }
142 
143 static const char * const ad_slave_pfxs[] = {
144         "Front", "Surround", "Center", "LFE", "Side",
145         "Headphone", "Mono", "Speaker", "IEC958",
146         NULL
147 };
148 
149 static const char * const ad1988_6stack_fp_slave_pfxs[] = {
150         "Front", "Surround", "Center", "LFE", "Side", "IEC958",
151         NULL
152 };
153 #endif /* ENABLE_AD_STATIC_QUIRKS */
154 
155 #ifdef CONFIG_SND_HDA_INPUT_BEEP
156 /* additional beep mixers; the actual parameters are overwritten at build */
157 static const struct snd_kcontrol_new ad_beep_mixer[] = {
158         HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_OUTPUT),
159         HDA_CODEC_MUTE_BEEP("Beep Playback Switch", 0, 0, HDA_OUTPUT),
160         { } /* end */
161 };
162 
163 static const struct snd_kcontrol_new ad_beep2_mixer[] = {
164         HDA_CODEC_VOLUME("Digital Beep Playback Volume", 0, 0, HDA_OUTPUT),
165         HDA_CODEC_MUTE_BEEP("Digital Beep Playback Switch", 0, 0, HDA_OUTPUT),
166         { } /* end */
167 };
168 
169 #define set_beep_amp(spec, nid, idx, dir) \
170         ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 1, idx, dir)) /* mono */
171 #else
172 #define set_beep_amp(spec, nid, idx, dir) /* NOP */
173 #endif
174 
175 #ifdef CONFIG_SND_HDA_INPUT_BEEP
176 static int create_beep_ctls(struct hda_codec *codec)
177 {
178         struct ad198x_spec *spec = codec->spec;
179         const struct snd_kcontrol_new *knew;
180 
181         if (!spec->beep_amp)
182                 return 0;
183 
184         knew = spec->analog_beep ? ad_beep2_mixer : ad_beep_mixer;
185         for ( ; knew->name; knew++) {
186                 int err;
187                 struct snd_kcontrol *kctl;
188                 kctl = snd_ctl_new1(knew, codec);
189                 if (!kctl)
190                         return -ENOMEM;
191                 kctl->private_value = spec->beep_amp;
192                 err = snd_hda_ctl_add(codec, 0, kctl);
193                 if (err < 0)
194                         return err;
195         }
196         return 0;
197 }
198 #else
199 #define create_beep_ctls(codec)         0
200 #endif
201 
202 #ifdef ENABLE_AD_STATIC_QUIRKS
203 static int ad198x_build_controls(struct hda_codec *codec)
204 {
205         struct ad198x_spec *spec = codec->spec;
206         struct snd_kcontrol *kctl;
207         unsigned int i;
208         int err;
209 
210         for (i = 0; i < spec->num_mixers; i++) {
211                 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
212                 if (err < 0)
213                         return err;
214         }
215         if (spec->multiout.dig_out_nid) {
216                 err = snd_hda_create_spdif_out_ctls(codec,
217                                                     spec->multiout.dig_out_nid,
218                                                     spec->multiout.dig_out_nid);
219                 if (err < 0)
220                         return err;
221                 err = snd_hda_create_spdif_share_sw(codec,
222                                                     &spec->multiout);
223                 if (err < 0)
224                         return err;
225                 spec->multiout.share_spdif = 1;
226         } 
227         if (spec->dig_in_nid) {
228                 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
229                 if (err < 0)
230                         return err;
231         }
232 
233         /* create beep controls if needed */
234         err = create_beep_ctls(codec);
235         if (err < 0)
236                 return err;
237 
238         /* if we have no master control, let's create it */
239         if (!snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
240                 unsigned int vmaster_tlv[4];
241                 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
242                                         HDA_OUTPUT, vmaster_tlv);
243                 err = __snd_hda_add_vmaster(codec, "Master Playback Volume",
244                                           vmaster_tlv,
245                                           (spec->slave_vols ?
246                                            spec->slave_vols : ad_slave_pfxs),
247                                           "Playback Volume",
248                                           !spec->avoid_init_slave_vol, NULL);
249                 if (err < 0)
250                         return err;
251         }
252         if (!snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
253                 err = snd_hda_add_vmaster(codec, "Master Playback Switch",
254                                           NULL,
255                                           (spec->slave_sws ?
256                                            spec->slave_sws : ad_slave_pfxs),
257                                           "Playback Switch");
258                 if (err < 0)
259                         return err;
260         }
261 
262         /* assign Capture Source enums to NID */
263         kctl = snd_hda_find_mixer_ctl(codec, "Capture Source");
264         if (!kctl)
265                 kctl = snd_hda_find_mixer_ctl(codec, "Input Source");
266         for (i = 0; kctl && i < kctl->count; i++) {
267                 err = snd_hda_add_nid(codec, kctl, i, spec->capsrc_nids[i]);
268                 if (err < 0)
269                         return err;
270         }
271 
272         /* assign IEC958 enums to NID */
273         kctl = snd_hda_find_mixer_ctl(codec,
274                         SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source");
275         if (kctl) {
276                 err = snd_hda_add_nid(codec, kctl, 0,
277                                       spec->multiout.dig_out_nid);
278                 if (err < 0)
279                         return err;
280         }
281 
282         return 0;
283 }
284 
285 #ifdef CONFIG_PM
286 static int ad198x_check_power_status(struct hda_codec *codec, hda_nid_t nid)
287 {
288         struct ad198x_spec *spec = codec->spec;
289         return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
290 }
291 #endif
292 
293 /*
294  * Analog playback callbacks
295  */
296 static int ad198x_playback_pcm_open(struct hda_pcm_stream *hinfo,
297                                     struct hda_codec *codec,
298                                     struct snd_pcm_substream *substream)
299 {
300         struct ad198x_spec *spec = codec->spec;
301         return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
302                                              hinfo);
303 }
304 
305 static int ad198x_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
306                                        struct hda_codec *codec,
307                                        unsigned int stream_tag,
308                                        unsigned int format,
309                                        struct snd_pcm_substream *substream)
310 {
311         struct ad198x_spec *spec = codec->spec;
312         return snd_hda_multi_out_analog_prepare(codec, &spec->multiout, stream_tag,
313                                                 format, substream);
314 }
315 
316 static int ad198x_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
317                                        struct hda_codec *codec,
318                                        struct snd_pcm_substream *substream)
319 {
320         struct ad198x_spec *spec = codec->spec;
321         return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
322 }
323 
324 /*
325  * Digital out
326  */
327 static int ad198x_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
328                                         struct hda_codec *codec,
329                                         struct snd_pcm_substream *substream)
330 {
331         struct ad198x_spec *spec = codec->spec;
332         return snd_hda_multi_out_dig_open(codec, &spec->multiout);
333 }
334 
335 static int ad198x_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
336                                          struct hda_codec *codec,
337                                          struct snd_pcm_substream *substream)
338 {
339         struct ad198x_spec *spec = codec->spec;
340         return snd_hda_multi_out_dig_close(codec, &spec->multiout);
341 }
342 
343 static int ad198x_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
344                                            struct hda_codec *codec,
345                                            unsigned int stream_tag,
346                                            unsigned int format,
347                                            struct snd_pcm_substream *substream)
348 {
349         struct ad198x_spec *spec = codec->spec;
350         return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, stream_tag,
351                                              format, substream);
352 }
353 
354 static int ad198x_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
355                                            struct hda_codec *codec,
356                                            struct snd_pcm_substream *substream)
357 {
358         struct ad198x_spec *spec = codec->spec;
359         return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout);
360 }
361 
362 /*
363  * Analog capture
364  */
365 static int ad198x_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
366                                       struct hda_codec *codec,
367                                       unsigned int stream_tag,
368                                       unsigned int format,
369                                       struct snd_pcm_substream *substream)
370 {
371         struct ad198x_spec *spec = codec->spec;
372         snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
373                                    stream_tag, 0, format);
374         return 0;
375 }
376 
377 static int ad198x_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
378                                       struct hda_codec *codec,
379                                       struct snd_pcm_substream *substream)
380 {
381         struct ad198x_spec *spec = codec->spec;
382         snd_hda_codec_cleanup_stream(codec, spec->adc_nids[substream->number]);
383         return 0;
384 }
385 
386 /*
387  */
388 static const struct hda_pcm_stream ad198x_pcm_analog_playback = {
389         .substreams = 1,
390         .channels_min = 2,
391         .channels_max = 6, /* changed later */
392         .nid = 0, /* fill later */
393         .ops = {
394                 .open = ad198x_playback_pcm_open,
395                 .prepare = ad198x_playback_pcm_prepare,
396                 .cleanup = ad198x_playback_pcm_cleanup,
397         },
398 };
399 
400 static const struct hda_pcm_stream ad198x_pcm_analog_capture = {
401         .substreams = 1,
402         .channels_min = 2,
403         .channels_max = 2,
404         .nid = 0, /* fill later */
405         .ops = {
406                 .prepare = ad198x_capture_pcm_prepare,
407                 .cleanup = ad198x_capture_pcm_cleanup
408         },
409 };
410 
411 static const struct hda_pcm_stream ad198x_pcm_digital_playback = {
412         .substreams = 1,
413         .channels_min = 2,
414         .channels_max = 2,
415         .nid = 0, /* fill later */
416         .ops = {
417                 .open = ad198x_dig_playback_pcm_open,
418                 .close = ad198x_dig_playback_pcm_close,
419                 .prepare = ad198x_dig_playback_pcm_prepare,
420                 .cleanup = ad198x_dig_playback_pcm_cleanup
421         },
422 };
423 
424 static const struct hda_pcm_stream ad198x_pcm_digital_capture = {
425         .substreams = 1,
426         .channels_min = 2,
427         .channels_max = 2,
428         /* NID is set in alc_build_pcms */
429 };
430 
431 static int ad198x_build_pcms(struct hda_codec *codec)
432 {
433         struct ad198x_spec *spec = codec->spec;
434         struct hda_pcm *info = spec->pcm_rec;
435 
436         codec->num_pcms = 1;
437         codec->pcm_info = info;
438 
439         info->name = "AD198x Analog";
440         info->stream[SNDRV_PCM_STREAM_PLAYBACK] = ad198x_pcm_analog_playback;
441         info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->multiout.max_channels;
442         info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
443         info->stream[SNDRV_PCM_STREAM_CAPTURE] = ad198x_pcm_analog_capture;
444         info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = spec->num_adc_nids;
445         info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
446 
447         if (spec->multiout.dig_out_nid) {
448                 info++;
449                 codec->num_pcms++;
450                 codec->spdif_status_reset = 1;
451                 info->name = "AD198x Digital";
452                 info->pcm_type = HDA_PCM_TYPE_SPDIF;
453                 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = ad198x_pcm_digital_playback;
454                 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
455                 if (spec->dig_in_nid) {
456                         info->stream[SNDRV_PCM_STREAM_CAPTURE] = ad198x_pcm_digital_capture;
457                         info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
458                 }
459         }
460 
461         return 0;
462 }
463 #endif /* ENABLE_AD_STATIC_QUIRKS */
464 
465 static void ad198x_power_eapd_write(struct hda_codec *codec, hda_nid_t front,
466                                 hda_nid_t hp)
467 {
468         if (snd_hda_query_pin_caps(codec, front) & AC_PINCAP_EAPD)
469                 snd_hda_codec_write(codec, front, 0, AC_VERB_SET_EAPD_BTLENABLE,
470                             !codec->inv_eapd ? 0x00 : 0x02);
471         if (snd_hda_query_pin_caps(codec, hp) & AC_PINCAP_EAPD)
472                 snd_hda_codec_write(codec, hp, 0, AC_VERB_SET_EAPD_BTLENABLE,
473                             !codec->inv_eapd ? 0x00 : 0x02);
474 }
475 
476 static void ad198x_power_eapd(struct hda_codec *codec)
477 {
478         /* We currently only handle front, HP */
479         switch (codec->vendor_id) {
480         case 0x11d41882:
481         case 0x11d4882a:
482         case 0x11d41884:
483         case 0x11d41984:
484         case 0x11d41883:
485         case 0x11d4184a:
486         case 0x11d4194a:
487         case 0x11d4194b:
488         case 0x11d41988:
489         case 0x11d4198b:
490         case 0x11d4989a:
491         case 0x11d4989b:
492                 ad198x_power_eapd_write(codec, 0x12, 0x11);
493                 break;
494         case 0x11d41981:
495         case 0x11d41983:
496                 ad198x_power_eapd_write(codec, 0x05, 0x06);
497                 break;
498         case 0x11d41986:
499                 ad198x_power_eapd_write(codec, 0x1b, 0x1a);
500                 break;
501         }
502 }
503 
504 static void ad198x_shutup(struct hda_codec *codec)
505 {
506         snd_hda_shutup_pins(codec);
507         ad198x_power_eapd(codec);
508 }
509 
510 static void ad198x_free(struct hda_codec *codec)
511 {
512         struct ad198x_spec *spec = codec->spec;
513 
514         if (!spec)
515                 return;
516 
517         snd_hda_gen_spec_free(&spec->gen);
518         kfree(spec);
519         snd_hda_detach_beep_device(codec);
520 }
521 
522 #ifdef CONFIG_PM
523 static int ad198x_suspend(struct hda_codec *codec)
524 {
525         ad198x_shutup(codec);
526         return 0;
527 }
528 #endif
529 
530 #ifdef ENABLE_AD_STATIC_QUIRKS
531 static const struct hda_codec_ops ad198x_patch_ops = {
532         .build_controls = ad198x_build_controls,
533         .build_pcms = ad198x_build_pcms,
534         .init = ad198x_init,
535         .free = ad198x_free,
536 #ifdef CONFIG_PM
537         .check_power_status = ad198x_check_power_status,
538         .suspend = ad198x_suspend,
539 #endif
540         .reboot_notify = ad198x_shutup,
541 };
542 
543 
544 /*
545  * EAPD control
546  * the private value = nid
547  */
548 #define ad198x_eapd_info        snd_ctl_boolean_mono_info
549 
550 static int ad198x_eapd_get(struct snd_kcontrol *kcontrol,
551                            struct snd_ctl_elem_value *ucontrol)
552 {
553         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
554         struct ad198x_spec *spec = codec->spec;
555         if (codec->inv_eapd)
556                 ucontrol->value.integer.value[0] = ! spec->cur_eapd;
557         else
558                 ucontrol->value.integer.value[0] = spec->cur_eapd;
559         return 0;
560 }
561 
562 static int ad198x_eapd_put(struct snd_kcontrol *kcontrol,
563                            struct snd_ctl_elem_value *ucontrol)
564 {
565         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
566         struct ad198x_spec *spec = codec->spec;
567         hda_nid_t nid = kcontrol->private_value & 0xff;
568         unsigned int eapd;
569         eapd = !!ucontrol->value.integer.value[0];
570         if (codec->inv_eapd)
571                 eapd = !eapd;
572         if (eapd == spec->cur_eapd)
573                 return 0;
574         spec->cur_eapd = eapd;
575         snd_hda_codec_write_cache(codec, nid,
576                                   0, AC_VERB_SET_EAPD_BTLENABLE,
577                                   eapd ? 0x02 : 0x00);
578         return 1;
579 }
580 
581 static int ad198x_ch_mode_info(struct snd_kcontrol *kcontrol,
582                                struct snd_ctl_elem_info *uinfo);
583 static int ad198x_ch_mode_get(struct snd_kcontrol *kcontrol,
584                               struct snd_ctl_elem_value *ucontrol);
585 static int ad198x_ch_mode_put(struct snd_kcontrol *kcontrol,
586                               struct snd_ctl_elem_value *ucontrol);
587 #endif /* ENABLE_AD_STATIC_QUIRKS */
588 
589 
590 /*
591  * Automatic parse of I/O pins from the BIOS configuration
592  */
593 
594 static int ad198x_auto_build_controls(struct hda_codec *codec)
595 {
596         int err;
597 
598         err = snd_hda_gen_build_controls(codec);
599         if (err < 0)
600                 return err;
601         err = create_beep_ctls(codec);
602         if (err < 0)
603                 return err;
604         return 0;
605 }
606 
607 static const struct hda_codec_ops ad198x_auto_patch_ops = {
608         .build_controls = ad198x_auto_build_controls,
609         .build_pcms = snd_hda_gen_build_pcms,
610         .init = snd_hda_gen_init,
611         .free = snd_hda_gen_free,
612         .unsol_event = snd_hda_jack_unsol_event,
613 #ifdef CONFIG_PM
614         .check_power_status = snd_hda_gen_check_power_status,
615         .suspend = ad198x_suspend,
616 #endif
617         .reboot_notify = ad198x_shutup,
618 };
619 
620 
621 static int ad198x_parse_auto_config(struct hda_codec *codec)
622 {
623         struct ad198x_spec *spec = codec->spec;
624         struct auto_pin_cfg *cfg = &spec->gen.autocfg;
625         int err;
626 
627         codec->spdif_status_reset = 1;
628         codec->no_trigger_sense = 1;
629         codec->no_sticky_stream = 1;
630 
631         spec->gen.indep_hp = 1;
632 
633         err = snd_hda_parse_pin_defcfg(codec, cfg, NULL, 0);
634         if (err < 0)
635                 return err;
636         err = snd_hda_gen_parse_auto_config(codec, cfg);
637         if (err < 0)
638                 return err;
639 
640         codec->patch_ops = ad198x_auto_patch_ops;
641 
642         return 0;
643 }
644 
645 /*
646  * AD1986A specific
647  */
648 
649 #ifdef ENABLE_AD_STATIC_QUIRKS
650 #define AD1986A_SPDIF_OUT       0x02
651 #define AD1986A_FRONT_DAC       0x03
652 #define AD1986A_SURR_DAC        0x04
653 #define AD1986A_CLFE_DAC        0x05
654 #define AD1986A_ADC             0x06
655 
656 static const hda_nid_t ad1986a_dac_nids[3] = {
657         AD1986A_FRONT_DAC, AD1986A_SURR_DAC, AD1986A_CLFE_DAC
658 };
659 static const hda_nid_t ad1986a_adc_nids[1] = { AD1986A_ADC };
660 static const hda_nid_t ad1986a_capsrc_nids[1] = { 0x12 };
661 
662 static const struct hda_input_mux ad1986a_capture_source = {
663         .num_items = 7,
664         .items = {
665                 { "Mic", 0x0 },
666                 { "CD", 0x1 },
667                 { "Aux", 0x3 },
668                 { "Line", 0x4 },
669                 { "Mix", 0x5 },
670                 { "Mono", 0x6 },
671                 { "Phone", 0x7 },
672         },
673 };
674 
675 
676 static const struct hda_bind_ctls ad1986a_bind_pcm_vol = {
677         .ops = &snd_hda_bind_vol,
678         .values = {
679                 HDA_COMPOSE_AMP_VAL(AD1986A_FRONT_DAC, 3, 0, HDA_OUTPUT),
680                 HDA_COMPOSE_AMP_VAL(AD1986A_SURR_DAC, 3, 0, HDA_OUTPUT),
681                 HDA_COMPOSE_AMP_VAL(AD1986A_CLFE_DAC, 3, 0, HDA_OUTPUT),
682                 0
683         },
684 };
685 
686 static const struct hda_bind_ctls ad1986a_bind_pcm_sw = {
687         .ops = &snd_hda_bind_sw,
688         .values = {
689                 HDA_COMPOSE_AMP_VAL(AD1986A_FRONT_DAC, 3, 0, HDA_OUTPUT),
690                 HDA_COMPOSE_AMP_VAL(AD1986A_SURR_DAC, 3, 0, HDA_OUTPUT),
691                 HDA_COMPOSE_AMP_VAL(AD1986A_CLFE_DAC, 3, 0, HDA_OUTPUT),
692                 0
693         },
694 };
695 
696 /*
697  * mixers
698  */
699 static const struct snd_kcontrol_new ad1986a_mixers[] = {
700         /*
701          * bind volumes/mutes of 3 DACs as a single PCM control for simplicity
702          */
703         HDA_BIND_VOL("PCM Playback Volume", &ad1986a_bind_pcm_vol),
704         HDA_BIND_SW("PCM Playback Switch", &ad1986a_bind_pcm_sw),
705         HDA_CODEC_VOLUME("Front Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
706         HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
707         HDA_CODEC_VOLUME("Surround Playback Volume", 0x1c, 0x0, HDA_OUTPUT),
708         HDA_CODEC_MUTE("Surround Playback Switch", 0x1c, 0x0, HDA_OUTPUT),
709         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x1d, 1, 0x0, HDA_OUTPUT),
710         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x1d, 2, 0x0, HDA_OUTPUT),
711         HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x1d, 1, 0x0, HDA_OUTPUT),
712         HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x1d, 2, 0x0, HDA_OUTPUT),
713         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x1a, 0x0, HDA_OUTPUT),
714         HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x0, HDA_OUTPUT),
715         HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_OUTPUT),
716         HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_OUTPUT),
717         HDA_CODEC_VOLUME("Line Playback Volume", 0x17, 0x0, HDA_OUTPUT),
718         HDA_CODEC_MUTE("Line Playback Switch", 0x17, 0x0, HDA_OUTPUT),
719         HDA_CODEC_VOLUME("Aux Playback Volume", 0x16, 0x0, HDA_OUTPUT),
720         HDA_CODEC_MUTE("Aux Playback Switch", 0x16, 0x0, HDA_OUTPUT),
721         HDA_CODEC_VOLUME("Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT),
722         HDA_CODEC_MUTE("Mic Playback Switch", 0x13, 0x0, HDA_OUTPUT),
723         HDA_CODEC_VOLUME("Mic Boost Volume", 0x0f, 0x0, HDA_OUTPUT),
724         HDA_CODEC_VOLUME("Mono Playback Volume", 0x1e, 0x0, HDA_OUTPUT),
725         HDA_CODEC_MUTE("Mono Playback Switch", 0x1e, 0x0, HDA_OUTPUT),
726         HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x0, HDA_OUTPUT),
727         HDA_CODEC_MUTE("Capture Switch", 0x12, 0x0, HDA_OUTPUT),
728         {
729                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
730                 .name = "Capture Source",
731                 .info = ad198x_mux_enum_info,
732                 .get = ad198x_mux_enum_get,
733                 .put = ad198x_mux_enum_put,
734         },
735         HDA_CODEC_MUTE("Stereo Downmix Switch", 0x09, 0x0, HDA_OUTPUT),
736         { } /* end */
737 };
738 
739 /* additional mixers for 3stack mode */
740 static const struct snd_kcontrol_new ad1986a_3st_mixers[] = {
741         {
742                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
743                 .name = "Channel Mode",
744                 .info = ad198x_ch_mode_info,
745                 .get = ad198x_ch_mode_get,
746                 .put = ad198x_ch_mode_put,
747         },
748         { } /* end */
749 };
750 
751 /* laptop model - 2ch only */
752 static const hda_nid_t ad1986a_laptop_dac_nids[1] = { AD1986A_FRONT_DAC };
753 
754 /* master controls both pins 0x1a and 0x1b */
755 static const struct hda_bind_ctls ad1986a_laptop_master_vol = {
756         .ops = &snd_hda_bind_vol,
757         .values = {
758                 HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, HDA_OUTPUT),
759                 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
760                 0,
761         },
762 };
763 
764 static const struct hda_bind_ctls ad1986a_laptop_master_sw = {
765         .ops = &snd_hda_bind_sw,
766         .values = {
767                 HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, HDA_OUTPUT),
768                 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
769                 0,
770         },
771 };
772 
773 static const struct snd_kcontrol_new ad1986a_laptop_mixers[] = {
774         HDA_CODEC_VOLUME("PCM Playback Volume", 0x03, 0x0, HDA_OUTPUT),
775         HDA_CODEC_MUTE("PCM Playback Switch", 0x03, 0x0, HDA_OUTPUT),
776         HDA_BIND_VOL("Master Playback Volume", &ad1986a_laptop_master_vol),
777         HDA_BIND_SW("Master Playback Switch", &ad1986a_laptop_master_sw),
778         HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_OUTPUT),
779         HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_OUTPUT),
780         HDA_CODEC_VOLUME("Line Playback Volume", 0x17, 0x0, HDA_OUTPUT),
781         HDA_CODEC_MUTE("Line Playback Switch", 0x17, 0x0, HDA_OUTPUT),
782         HDA_CODEC_VOLUME("Aux Playback Volume", 0x16, 0x0, HDA_OUTPUT),
783         HDA_CODEC_MUTE("Aux Playback Switch", 0x16, 0x0, HDA_OUTPUT),
784         HDA_CODEC_VOLUME("Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT),
785         HDA_CODEC_MUTE("Mic Playback Switch", 0x13, 0x0, HDA_OUTPUT),
786         HDA_CODEC_VOLUME("Mic Boost Volume", 0x0f, 0x0, HDA_OUTPUT),
787         /* 
788            HDA_CODEC_VOLUME("Mono Playback Volume", 0x1e, 0x0, HDA_OUTPUT),
789            HDA_CODEC_MUTE("Mono Playback Switch", 0x1e, 0x0, HDA_OUTPUT), */
790         HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x0, HDA_OUTPUT),
791         HDA_CODEC_MUTE("Capture Switch", 0x12, 0x0, HDA_OUTPUT),
792         {
793                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
794                 .name = "Capture Source",
795                 .info = ad198x_mux_enum_info,
796                 .get = ad198x_mux_enum_get,
797                 .put = ad198x_mux_enum_put,
798         },
799         { } /* end */
800 };
801 
802 /* laptop-eapd model - 2ch only */
803 
804 static const struct hda_input_mux ad1986a_laptop_eapd_capture_source = {
805         .num_items = 3,
806         .items = {
807                 { "Mic", 0x0 },
808                 { "Internal Mic", 0x4 },
809                 { "Mix", 0x5 },
810         },
811 };
812 
813 static const struct hda_input_mux ad1986a_automic_capture_source = {
814         .num_items = 2,
815         .items = {
816                 { "Mic", 0x0 },
817                 { "Mix", 0x5 },
818         },
819 };
820 
821 static const struct snd_kcontrol_new ad1986a_laptop_master_mixers[] = {
822         HDA_BIND_VOL("Master Playback Volume", &ad1986a_laptop_master_vol),
823         HDA_BIND_SW("Master Playback Switch", &ad1986a_laptop_master_sw),
824         { } /* end */
825 };
826 
827 static const struct snd_kcontrol_new ad1986a_laptop_eapd_mixers[] = {
828         HDA_CODEC_VOLUME("PCM Playback Volume", 0x03, 0x0, HDA_OUTPUT),
829         HDA_CODEC_MUTE("PCM Playback Switch", 0x03, 0x0, HDA_OUTPUT),
830         HDA_CODEC_VOLUME("Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT),
831         HDA_CODEC_MUTE("Mic Playback Switch", 0x13, 0x0, HDA_OUTPUT),
832         HDA_CODEC_VOLUME("Mic Boost Volume", 0x0f, 0x0, HDA_OUTPUT),
833         HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x0, HDA_OUTPUT),
834         HDA_CODEC_MUTE("Capture Switch", 0x12, 0x0, HDA_OUTPUT),
835         {
836                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
837                 .name = "Capture Source",
838                 .info = ad198x_mux_enum_info,
839                 .get = ad198x_mux_enum_get,
840                 .put = ad198x_mux_enum_put,
841         },
842         {
843                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
844                 .name = "External Amplifier",
845                 .subdevice = HDA_SUBDEV_NID_FLAG | 0x1b,
846                 .info = ad198x_eapd_info,
847                 .get = ad198x_eapd_get,
848                 .put = ad198x_eapd_put,
849                 .private_value = 0x1b, /* port-D */
850         },
851         { } /* end */
852 };
853 
854 static const struct snd_kcontrol_new ad1986a_laptop_intmic_mixers[] = {
855         HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x17, 0, HDA_OUTPUT),
856         HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x17, 0, HDA_OUTPUT),
857         { } /* end */
858 };
859 
860 /* re-connect the mic boost input according to the jack sensing */
861 static void ad1986a_automic(struct hda_codec *codec)
862 {
863         unsigned int present;
864         present = snd_hda_jack_detect(codec, 0x1f);
865         /* 0 = 0x1f, 2 = 0x1d, 4 = mixed */
866         snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_CONNECT_SEL,
867                             present ? 0 : 2);
868 }
869 
870 #define AD1986A_MIC_EVENT               0x36
871 
872 static void ad1986a_automic_unsol_event(struct hda_codec *codec,
873                                             unsigned int res)
874 {
875         if ((res >> 26) != AD1986A_MIC_EVENT)
876                 return;
877         ad1986a_automic(codec);
878 }
879 
880 static int ad1986a_automic_init(struct hda_codec *codec)
881 {
882         ad198x_init(codec);
883         ad1986a_automic(codec);
884         return 0;
885 }
886 
887 /* laptop-automute - 2ch only */
888 
889 static void ad1986a_update_hp(struct hda_codec *codec)
890 {
891         struct ad198x_spec *spec = codec->spec;
892         unsigned int mute;
893 
894         if (spec->jack_present)
895                 mute = HDA_AMP_MUTE; /* mute internal speaker */
896         else
897                 /* unmute internal speaker if necessary */
898                 mute = snd_hda_codec_amp_read(codec, 0x1a, 0, HDA_OUTPUT, 0);
899         snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
900                                  HDA_AMP_MUTE, mute);
901 }
902 
903 static void ad1986a_hp_automute(struct hda_codec *codec)
904 {
905         struct ad198x_spec *spec = codec->spec;
906 
907         spec->jack_present = snd_hda_jack_detect(codec, 0x1a);
908         if (spec->inv_jack_detect)
909                 spec->jack_present = !spec->jack_present;
910         ad1986a_update_hp(codec);
911 }
912 
913 #define AD1986A_HP_EVENT                0x37
914 
915 static void ad1986a_hp_unsol_event(struct hda_codec *codec, unsigned int res)
916 {
917         if ((res >> 26) != AD1986A_HP_EVENT)
918                 return;
919         ad1986a_hp_automute(codec);
920 }
921 
922 static int ad1986a_hp_init(struct hda_codec *codec)
923 {
924         ad198x_init(codec);
925         ad1986a_hp_automute(codec);
926         return 0;
927 }
928 
929 /* bind hp and internal speaker mute (with plug check) */
930 static int ad1986a_hp_master_sw_put(struct snd_kcontrol *kcontrol,
931                                     struct snd_ctl_elem_value *ucontrol)
932 {
933         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
934         int change = snd_hda_mixer_amp_switch_put(kcontrol, ucontrol);
935         if (change)
936                 ad1986a_update_hp(codec);
937         return change;
938 }
939 
940 static const struct snd_kcontrol_new ad1986a_automute_master_mixers[] = {
941         HDA_BIND_VOL("Master Playback Volume", &ad1986a_laptop_master_vol),
942         {
943                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
944                 .name = "Master Playback Switch",
945                 .subdevice = HDA_SUBDEV_AMP_FLAG,
946                 .info = snd_hda_mixer_amp_switch_info,
947                 .get = snd_hda_mixer_amp_switch_get,
948                 .put = ad1986a_hp_master_sw_put,
949                 .private_value = HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, HDA_OUTPUT),
950         },
951         { } /* end */
952 };
953 
954 
955 /*
956  * initialization verbs
957  */
958 static const struct hda_verb ad1986a_init_verbs[] = {
959         /* Front, Surround, CLFE DAC; mute as default */
960         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
961         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
962         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
963         /* Downmix - off */
964         {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
965         /* HP, Line-Out, Surround, CLFE selectors */
966         {0x0a, AC_VERB_SET_CONNECT_SEL, 0x0},
967         {0x0b, AC_VERB_SET_CONNECT_SEL, 0x0},
968         {0x0c, AC_VERB_SET_CONNECT_SEL, 0x0},
969         {0x0d, AC_VERB_SET_CONNECT_SEL, 0x0},
970         /* Mono selector */
971         {0x0e, AC_VERB_SET_CONNECT_SEL, 0x0},
972         /* Mic selector: Mic 1/2 pin */
973         {0x0f, AC_VERB_SET_CONNECT_SEL, 0x0},
974         /* Line-in selector: Line-in */
975         {0x10, AC_VERB_SET_CONNECT_SEL, 0x0},
976         /* Mic 1/2 swap */
977         {0x11, AC_VERB_SET_CONNECT_SEL, 0x0},
978         /* Record selector: mic */
979         {0x12, AC_VERB_SET_CONNECT_SEL, 0x0},
980         /* Mic, Phone, CD, Aux, Line-In amp; mute as default */
981         {0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
982         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
983         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
984         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
985         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
986         /* PC beep */
987         {0x18, AC_VERB_SET_CONNECT_SEL, 0x0},
988         /* HP, Line-Out, Surround, CLFE, Mono pins; mute as default */
989         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
990         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
991         {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
992         {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
993         {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
994         /* HP Pin */
995         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
996         /* Front, Surround, CLFE Pins */
997         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
998         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
999         {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
1000         /* Mono Pin */
1001         {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
1002         /* Mic Pin */
1003         {0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
1004         /* Line, Aux, CD, Beep-In Pin */
1005         {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
1006         {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
1007         {0x22, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
1008         {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
1009         {0x24, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
1010         { } /* end */
1011 };
1012 
1013 static const struct hda_verb ad1986a_ch2_init[] = {
1014         /* Surround out -> Line In */
1015         { 0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1016         /* Line-in selectors */
1017         { 0x10, AC_VERB_SET_CONNECT_SEL, 0x1 },
1018         /* CLFE -> Mic in */
1019         { 0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1020         /* Mic selector, mix C/LFE (backmic) and Mic (frontmic) */
1021         { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x4 },
1022         { } /* end */
1023 };
1024 
1025 static const struct hda_verb ad1986a_ch4_init[] = {
1026         /* Surround out -> Surround */
1027         { 0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1028         { 0x10, AC_VERB_SET_CONNECT_SEL, 0x0 },
1029         /* CLFE -> Mic in */
1030         { 0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1031         { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x4 },
1032         { } /* end */
1033 };
1034 
1035 static const struct hda_verb ad1986a_ch6_init[] = {
1036         /* Surround out -> Surround out */
1037         { 0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1038         { 0x10, AC_VERB_SET_CONNECT_SEL, 0x0 },
1039         /* CLFE -> CLFE */
1040         { 0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1041         { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x0 },
1042         { } /* end */
1043 };
1044 
1045 static const struct hda_channel_mode ad1986a_modes[3] = {
1046         { 2, ad1986a_ch2_init },
1047         { 4, ad1986a_ch4_init },
1048         { 6, ad1986a_ch6_init },
1049 };
1050 
1051 /* eapd initialization */
1052 static const struct hda_verb ad1986a_eapd_init_verbs[] = {
1053         {0x1b, AC_VERB_SET_EAPD_BTLENABLE, 0x00 },
1054         {}
1055 };
1056 
1057 static const struct hda_verb ad1986a_automic_verbs[] = {
1058         {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1059         {0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1060         /*{0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},*/
1061         {0x0f, AC_VERB_SET_CONNECT_SEL, 0x0},
1062         {0x1f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1986A_MIC_EVENT},
1063         {}
1064 };
1065 
1066 /* Ultra initialization */
1067 static const struct hda_verb ad1986a_ultra_init[] = {
1068         /* eapd initialization */
1069         { 0x1b, AC_VERB_SET_EAPD_BTLENABLE, 0x00 },
1070         /* CLFE -> Mic in */
1071         { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x2 },
1072         { 0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
1073         { 0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
1074         { } /* end */
1075 };
1076 
1077 /* pin sensing on HP jack */
1078 static const struct hda_verb ad1986a_hp_init_verbs[] = {
1079         {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1986A_HP_EVENT},
1080         {}
1081 };
1082 
1083 static void ad1986a_samsung_p50_unsol_event(struct hda_codec *codec,
1084                                             unsigned int res)
1085 {
1086         switch (res >> 26) {
1087         case AD1986A_HP_EVENT:
1088                 ad1986a_hp_automute(codec);
1089                 break;
1090         case AD1986A_MIC_EVENT:
1091                 ad1986a_automic(codec);
1092                 break;
1093         }
1094 }
1095 
1096 static int ad1986a_samsung_p50_init(struct hda_codec *codec)
1097 {
1098         ad198x_init(codec);
1099         ad1986a_hp_automute(codec);
1100         ad1986a_automic(codec);
1101         return 0;
1102 }
1103 
1104 
1105 /* models */
1106 enum {
1107         AD1986A_AUTO,
1108         AD1986A_6STACK,
1109         AD1986A_3STACK,
1110         AD1986A_LAPTOP,
1111         AD1986A_LAPTOP_EAPD,
1112         AD1986A_LAPTOP_AUTOMUTE,
1113         AD1986A_ULTRA,
1114         AD1986A_SAMSUNG,
1115         AD1986A_SAMSUNG_P50,
1116         AD1986A_MODELS
1117 };
1118 
1119 static const char * const ad1986a_models[AD1986A_MODELS] = {
1120         [AD1986A_AUTO]          = "auto",
1121         [AD1986A_6STACK]        = "6stack",
1122         [AD1986A_3STACK]        = "3stack",
1123         [AD1986A_LAPTOP]        = "laptop",
1124         [AD1986A_LAPTOP_EAPD]   = "laptop-eapd",
1125         [AD1986A_LAPTOP_AUTOMUTE] = "laptop-automute",
1126         [AD1986A_ULTRA]         = "ultra",
1127         [AD1986A_SAMSUNG]       = "samsung",
1128         [AD1986A_SAMSUNG_P50]   = "samsung-p50",
1129 };
1130 
1131 static const struct snd_pci_quirk ad1986a_cfg_tbl[] = {
1132         SND_PCI_QUIRK(0x103c, 0x30af, "HP B2800", AD1986A_LAPTOP_EAPD),
1133         SND_PCI_QUIRK(0x1043, 0x1153, "ASUS M9", AD1986A_LAPTOP_EAPD),
1134         SND_PCI_QUIRK(0x1043, 0x11f7, "ASUS U5A", AD1986A_LAPTOP_EAPD),
1135         SND_PCI_QUIRK(0x1043, 0x1213, "ASUS A6J", AD1986A_LAPTOP_EAPD),
1136         SND_PCI_QUIRK(0x1043, 0x1263, "ASUS U5F", AD1986A_LAPTOP_EAPD),
1137         SND_PCI_QUIRK(0x1043, 0x1297, "ASUS Z62F", AD1986A_LAPTOP_EAPD),
1138         SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS V1j", AD1986A_LAPTOP_EAPD),
1139         SND_PCI_QUIRK(0x1043, 0x1302, "ASUS W3j", AD1986A_LAPTOP_EAPD),
1140         SND_PCI_QUIRK(0x1043, 0x1443, "ASUS VX1", AD1986A_LAPTOP),
1141         SND_PCI_QUIRK(0x1043, 0x1447, "ASUS A8J", AD1986A_3STACK),
1142         SND_PCI_QUIRK(0x1043, 0x817f, "ASUS P5", AD1986A_3STACK),
1143         SND_PCI_QUIRK(0x1043, 0x818f, "ASUS P5", AD1986A_LAPTOP),
1144         SND_PCI_QUIRK(0x1043, 0x81b3, "ASUS P5", AD1986A_3STACK),
1145         SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS M2N", AD1986A_3STACK),
1146         SND_PCI_QUIRK(0x1043, 0x8234, "ASUS M2N", AD1986A_3STACK),
1147         SND_PCI_QUIRK(0x10de, 0xcb84, "ASUS A8N-VM", AD1986A_3STACK),
1148         SND_PCI_QUIRK(0x1179, 0xff40, "Toshiba Satellite L40-10Q", AD1986A_3STACK),
1149         SND_PCI_QUIRK(0x144d, 0xb03c, "Samsung R55", AD1986A_3STACK),
1150         SND_PCI_QUIRK(0x144d, 0xc01e, "FSC V2060", AD1986A_LAPTOP),
1151         SND_PCI_QUIRK(0x144d, 0xc024, "Samsung P50", AD1986A_SAMSUNG_P50),
1152         SND_PCI_QUIRK(0x144d, 0xc027, "Samsung Q1", AD1986A_ULTRA),
1153         SND_PCI_QUIRK_MASK(0x144d, 0xff00, 0xc000, "Samsung", AD1986A_SAMSUNG),
1154         SND_PCI_QUIRK(0x144d, 0xc504, "Samsung Q35", AD1986A_3STACK),
1155         SND_PCI_QUIRK(0x17aa, 0x1011, "Lenovo M55", AD1986A_LAPTOP),
1156         SND_PCI_QUIRK(0x17aa, 0x1017, "Lenovo A60", AD1986A_3STACK),
1157         SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo N100", AD1986A_LAPTOP_AUTOMUTE),
1158         SND_PCI_QUIRK(0x17c0, 0x2017, "Samsung M50", AD1986A_LAPTOP),
1159         {}
1160 };
1161 
1162 #ifdef CONFIG_PM
1163 static const struct hda_amp_list ad1986a_loopbacks[] = {
1164         { 0x13, HDA_OUTPUT, 0 }, /* Mic */
1165         { 0x14, HDA_OUTPUT, 0 }, /* Phone */
1166         { 0x15, HDA_OUTPUT, 0 }, /* CD */
1167         { 0x16, HDA_OUTPUT, 0 }, /* Aux */
1168         { 0x17, HDA_OUTPUT, 0 }, /* Line */
1169         { } /* end */
1170 };
1171 #endif
1172 
1173 static int is_jack_available(struct hda_codec *codec, hda_nid_t nid)
1174 {
1175         unsigned int conf = snd_hda_codec_get_pincfg(codec, nid);
1176         return get_defcfg_connect(conf) != AC_JACK_PORT_NONE;
1177 }
1178 #endif /* ENABLE_AD_STATIC_QUIRKS */
1179 
1180 static int alloc_ad_spec(struct hda_codec *codec)
1181 {
1182         struct ad198x_spec *spec;
1183 
1184         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1185         if (!spec)
1186                 return -ENOMEM;
1187         codec->spec = spec;
1188         snd_hda_gen_spec_init(&spec->gen);
1189         return 0;
1190 }
1191 
1192 /*
1193  * AD1986A fixup codes
1194  */
1195 
1196 /* Lenovo N100 seems to report the reversed bit for HP jack-sensing */
1197 static void ad_fixup_inv_jack_detect(struct hda_codec *codec,
1198                                      const struct hda_fixup *fix, int action)
1199 {
1200         struct ad198x_spec *spec = codec->spec;
1201 
1202         if (action == HDA_FIXUP_ACT_PRE_PROBE) {
1203                 codec->inv_jack_detect = 1;
1204                 spec->gen.keep_eapd_on = 1;
1205         }
1206 }
1207 
1208 enum {
1209         AD1986A_FIXUP_INV_JACK_DETECT,
1210 };
1211 
1212 static const struct hda_fixup ad1986a_fixups[] = {
1213         [AD1986A_FIXUP_INV_JACK_DETECT] = {
1214                 .type = HDA_FIXUP_FUNC,
1215                 .v.func = ad_fixup_inv_jack_detect,
1216         },
1217 };
1218 
1219 static const struct snd_pci_quirk ad1986a_fixup_tbl[] = {
1220         SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo N100", AD1986A_FIXUP_INV_JACK_DETECT),
1221         {}
1222 };
1223 
1224 /*
1225  */
1226 static int ad1986a_parse_auto_config(struct hda_codec *codec)
1227 {
1228         int err;
1229         struct ad198x_spec *spec;
1230         static hda_nid_t preferred_pairs[] = {
1231                 0x1a, 0x03,
1232                 0x1b, 0x03,
1233                 0x1c, 0x04,
1234                 0x1d, 0x05,
1235                 0x1e, 0x03,
1236                 0
1237         };
1238 
1239         err = alloc_ad_spec(codec);
1240         if (err < 0)
1241                 return err;
1242         spec = codec->spec;
1243 
1244         /* AD1986A has the inverted EAPD implementation */
1245         codec->inv_eapd = 1;
1246 
1247         spec->gen.mixer_nid = 0x07;
1248         spec->gen.beep_nid = 0x19;
1249         set_beep_amp(spec, 0x18, 0, HDA_OUTPUT);
1250 
1251         /* AD1986A has a hardware problem that it can't share a stream
1252          * with multiple output pins.  The copy of front to surrounds
1253          * causes noisy or silent outputs at a certain timing, e.g.
1254          * changing the volume.
1255          * So, let's disable the shared stream.
1256          */
1257         spec->gen.multiout.no_share_stream = 1;
1258         /* give fixed DAC/pin pairs */
1259         spec->gen.preferred_dacs = preferred_pairs;
1260 
1261         snd_hda_pick_fixup(codec, NULL, ad1986a_fixup_tbl, ad1986a_fixups);
1262         snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
1263 
1264         err = ad198x_parse_auto_config(codec);
1265         if (err < 0) {
1266                 snd_hda_gen_free(codec);
1267                 return err;
1268         }
1269 
1270         snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
1271 
1272         return 0;
1273 }
1274 
1275 #ifdef ENABLE_AD_STATIC_QUIRKS
1276 static int patch_ad1986a(struct hda_codec *codec)
1277 {
1278         struct ad198x_spec *spec;
1279         int err, board_config;
1280 
1281         board_config = snd_hda_check_board_config(codec, AD1986A_MODELS,
1282                                                   ad1986a_models,
1283                                                   ad1986a_cfg_tbl);
1284         if (board_config < 0) {
1285                 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
1286                        codec->chip_name);
1287                 board_config = AD1986A_AUTO;
1288         }
1289 
1290         if (board_config == AD1986A_AUTO)
1291                 return ad1986a_parse_auto_config(codec);
1292 
1293         err = alloc_ad_spec(codec);
1294         if (err < 0)
1295                 return err;
1296         spec = codec->spec;
1297 
1298         err = snd_hda_attach_beep_device(codec, 0x19);
1299         if (err < 0) {
1300                 ad198x_free(codec);
1301                 return err;
1302         }
1303         set_beep_amp(spec, 0x18, 0, HDA_OUTPUT);
1304 
1305         spec->multiout.max_channels = 6;
1306         spec->multiout.num_dacs = ARRAY_SIZE(ad1986a_dac_nids);
1307         spec->multiout.dac_nids = ad1986a_dac_nids;
1308         spec->multiout.dig_out_nid = AD1986A_SPDIF_OUT;
1309         spec->num_adc_nids = 1;
1310         spec->adc_nids = ad1986a_adc_nids;
1311         spec->capsrc_nids = ad1986a_capsrc_nids;
1312         spec->input_mux = &ad1986a_capture_source;
1313         spec->num_mixers = 1;
1314         spec->mixers[0] = ad1986a_mixers;
1315         spec->num_init_verbs = 1;
1316         spec->init_verbs[0] = ad1986a_init_verbs;
1317 #ifdef CONFIG_PM
1318         spec->loopback.amplist = ad1986a_loopbacks;
1319 #endif
1320         spec->vmaster_nid = 0x1b;
1321         codec->inv_eapd = 1; /* AD1986A has the inverted EAPD implementation */
1322 
1323         codec->patch_ops = ad198x_patch_ops;
1324 
1325         /* override some parameters */
1326         switch (board_config) {
1327         case AD1986A_3STACK:
1328                 spec->num_mixers = 2;
1329                 spec->mixers[1] = ad1986a_3st_mixers;
1330                 spec->num_init_verbs = 2;
1331                 spec->init_verbs[1] = ad1986a_ch2_init;
1332                 spec->channel_mode = ad1986a_modes;
1333                 spec->num_channel_mode = ARRAY_SIZE(ad1986a_modes);
1334                 spec->need_dac_fix = 1;
1335                 spec->multiout.max_channels = 2;
1336                 spec->multiout.num_dacs = 1;
1337                 break;
1338         case AD1986A_LAPTOP:
1339                 spec->mixers[0] = ad1986a_laptop_mixers;
1340                 spec->multiout.max_channels = 2;
1341                 spec->multiout.num_dacs = 1;
1342                 spec->multiout.dac_nids = ad1986a_laptop_dac_nids;
1343                 break;
1344         case AD1986A_LAPTOP_EAPD:
1345                 spec->num_mixers = 3;
1346                 spec->mixers[0] = ad1986a_laptop_master_mixers;
1347                 spec->mixers[1] = ad1986a_laptop_eapd_mixers;
1348                 spec->mixers[2] = ad1986a_laptop_intmic_mixers;
1349                 spec->num_init_verbs = 2;
1350                 spec->init_verbs[1] = ad1986a_eapd_init_verbs;
1351                 spec->multiout.max_channels = 2;
1352                 spec->multiout.num_dacs = 1;
1353                 spec->multiout.dac_nids = ad1986a_laptop_dac_nids;
1354                 if (!is_jack_available(codec, 0x25))
1355                         spec->multiout.dig_out_nid = 0;
1356                 spec->input_mux = &ad1986a_laptop_eapd_capture_source;
1357                 break;
1358         case AD1986A_SAMSUNG:
1359                 spec->num_mixers = 2;
1360                 spec->mixers[0] = ad1986a_laptop_master_mixers;
1361                 spec->mixers[1] = ad1986a_laptop_eapd_mixers;
1362                 spec->num_init_verbs = 3;
1363                 spec->init_verbs[1] = ad1986a_eapd_init_verbs;
1364                 spec->init_verbs[2] = ad1986a_automic_verbs;
1365                 spec->multiout.max_channels = 2;
1366                 spec->multiout.num_dacs = 1;
1367                 spec->multiout.dac_nids = ad1986a_laptop_dac_nids;
1368                 if (!is_jack_available(codec, 0x25))
1369                         spec->multiout.dig_out_nid = 0;
1370                 spec->input_mux = &ad1986a_automic_capture_source;
1371                 codec->patch_ops.unsol_event = ad1986a_automic_unsol_event;
1372                 codec->patch_ops.init = ad1986a_automic_init;
1373                 break;
1374         case AD1986A_SAMSUNG_P50:
1375                 spec->num_mixers = 2;
1376                 spec->mixers[0] = ad1986a_automute_master_mixers;
1377                 spec->mixers[1] = ad1986a_laptop_eapd_mixers;
1378                 spec->num_init_verbs = 4;
1379                 spec->init_verbs[1] = ad1986a_eapd_init_verbs;
1380                 spec->init_verbs[2] = ad1986a_automic_verbs;
1381                 spec->init_verbs[3] = ad1986a_hp_init_verbs;
1382                 spec->multiout.max_channels = 2;
1383                 spec->multiout.num_dacs = 1;
1384                 spec->multiout.dac_nids = ad1986a_laptop_dac_nids;
1385                 if (!is_jack_available(codec, 0x25))
1386                         spec->multiout.dig_out_nid = 0;
1387                 spec->input_mux = &ad1986a_automic_capture_source;
1388                 codec->patch_ops.unsol_event = ad1986a_samsung_p50_unsol_event;
1389                 codec->patch_ops.init = ad1986a_samsung_p50_init;
1390                 break;
1391         case AD1986A_LAPTOP_AUTOMUTE:
1392                 spec->num_mixers = 3;
1393                 spec->mixers[0] = ad1986a_automute_master_mixers;
1394                 spec->mixers[1] = ad1986a_laptop_eapd_mixers;
1395                 spec->mixers[2] = ad1986a_laptop_intmic_mixers;
1396                 spec->num_init_verbs = 3;
1397                 spec->init_verbs[1] = ad1986a_eapd_init_verbs;
1398                 spec->init_verbs[2] = ad1986a_hp_init_verbs;
1399                 spec->multiout.max_channels = 2;
1400                 spec->multiout.num_dacs = 1;
1401                 spec->multiout.dac_nids = ad1986a_laptop_dac_nids;
1402                 if (!is_jack_available(codec, 0x25))
1403                         spec->multiout.dig_out_nid = 0;
1404                 spec->input_mux = &ad1986a_laptop_eapd_capture_source;
1405                 codec->patch_ops.unsol_event = ad1986a_hp_unsol_event;
1406                 codec->patch_ops.init = ad1986a_hp_init;
1407                 /* Lenovo N100 seems to report the reversed bit
1408                  * for HP jack-sensing
1409                  */
1410                 spec->inv_jack_detect = 1;
1411                 break;
1412         case AD1986A_ULTRA:
1413                 spec->mixers[0] = ad1986a_laptop_eapd_mixers;
1414                 spec->num_init_verbs = 2;
1415                 spec->init_verbs[1] = ad1986a_ultra_init;
1416                 spec->multiout.max_channels = 2;
1417                 spec->multiout.num_dacs = 1;
1418                 spec->multiout.dac_nids = ad1986a_laptop_dac_nids;
1419                 spec->multiout.dig_out_nid = 0;
1420                 break;
1421         }
1422 
1423         /* AD1986A has a hardware problem that it can't share a stream
1424          * with multiple output pins.  The copy of front to surrounds
1425          * causes noisy or silent outputs at a certain timing, e.g.
1426          * changing the volume.
1427          * So, let's disable the shared stream.
1428          */
1429         spec->multiout.no_share_stream = 1;
1430 
1431         codec->no_trigger_sense = 1;
1432         codec->no_sticky_stream = 1;
1433 
1434         return 0;
1435 }
1436 #else /* ENABLE_AD_STATIC_QUIRKS */
1437 #define patch_ad1986a   ad1986a_parse_auto_config
1438 #endif /* ENABLE_AD_STATIC_QUIRKS */
1439 
1440 /*
1441  * AD1983 specific
1442  */
1443 
1444 #ifdef ENABLE_AD_STATIC_QUIRKS
1445 #define AD1983_SPDIF_OUT        0x02
1446 #define AD1983_DAC              0x03
1447 #define AD1983_ADC              0x04
1448 
1449 static const hda_nid_t ad1983_dac_nids[1] = { AD1983_DAC };
1450 static const hda_nid_t ad1983_adc_nids[1] = { AD1983_ADC };
1451 static const hda_nid_t ad1983_capsrc_nids[1] = { 0x15 };
1452 
1453 static const struct hda_input_mux ad1983_capture_source = {
1454         .num_items = 4,
1455         .items = {
1456                 { "Mic", 0x0 },
1457                 { "Line", 0x1 },
1458                 { "Mix", 0x2 },
1459                 { "Mix Mono", 0x3 },
1460         },
1461 };
1462 
1463 /*
1464  * SPDIF playback route
1465  */
1466 static int ad1983_spdif_route_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
1467 {
1468         static const char * const texts[] = { "PCM", "ADC" };
1469 
1470         uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1471         uinfo->count = 1;
1472         uinfo->value.enumerated.items = 2;
1473         if (uinfo->value.enumerated.item > 1)
1474                 uinfo->value.enumerated.item = 1;
1475         strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
1476         return 0;
1477 }
1478 
1479 static int ad1983_spdif_route_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1480 {
1481         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1482         struct ad198x_spec *spec = codec->spec;
1483 
1484         ucontrol->value.enumerated.item[0] = spec->spdif_route;
1485         return 0;
1486 }
1487 
1488 static int ad1983_spdif_route_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1489 {
1490         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1491         struct ad198x_spec *spec = codec->spec;
1492 
1493         if (ucontrol->value.enumerated.item[0] > 1)
1494                 return -EINVAL;
1495         if (spec->spdif_route != ucontrol->value.enumerated.item[0]) {
1496                 spec->spdif_route = ucontrol->value.enumerated.item[0];
1497                 snd_hda_codec_write_cache(codec, spec->multiout.dig_out_nid, 0,
1498                                           AC_VERB_SET_CONNECT_SEL,
1499                                           spec->spdif_route);
1500                 return 1;
1501         }
1502         return 0;
1503 }
1504 
1505 static const struct snd_kcontrol_new ad1983_mixers[] = {
1506         HDA_CODEC_VOLUME("Front Playback Volume", 0x05, 0x0, HDA_OUTPUT),
1507         HDA_CODEC_MUTE("Front Playback Switch", 0x05, 0x0, HDA_OUTPUT),
1508         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x06, 0x0, HDA_OUTPUT),
1509         HDA_CODEC_MUTE("Headphone Playback Switch", 0x06, 0x0, HDA_OUTPUT),
1510         HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x07, 1, 0x0, HDA_OUTPUT),
1511         HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x07, 1, 0x0, HDA_OUTPUT),
1512         HDA_CODEC_VOLUME("PCM Playback Volume", 0x11, 0x0, HDA_OUTPUT),
1513         HDA_CODEC_MUTE("PCM Playback Switch", 0x11, 0x0, HDA_OUTPUT),
1514         HDA_CODEC_VOLUME("Mic Playback Volume", 0x12, 0x0, HDA_OUTPUT),
1515         HDA_CODEC_MUTE("Mic Playback Switch", 0x12, 0x0, HDA_OUTPUT),
1516         HDA_CODEC_VOLUME("Line Playback Volume", 0x13, 0x0, HDA_OUTPUT),
1517         HDA_CODEC_MUTE("Line Playback Switch", 0x13, 0x0, HDA_OUTPUT),
1518         HDA_CODEC_VOLUME("Mic Boost Volume", 0x0c, 0x0, HDA_OUTPUT),
1519         HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT),
1520         HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_OUTPUT),
1521         {
1522                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1523                 .name = "Capture Source",
1524                 .info = ad198x_mux_enum_info,
1525                 .get = ad198x_mux_enum_get,
1526                 .put = ad198x_mux_enum_put,
1527         },
1528         {
1529                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1530                 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
1531                 .info = ad1983_spdif_route_info,
1532                 .get = ad1983_spdif_route_get,
1533                 .put = ad1983_spdif_route_put,
1534         },
1535         { } /* end */
1536 };
1537 
1538 static const struct hda_verb ad1983_init_verbs[] = {
1539         /* Front, HP, Mono; mute as default */
1540         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1541         {0x06, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1542         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1543         /* Beep, PCM, Mic, Line-In: mute */
1544         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1545         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1546         {0x12, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1547         {0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1548         /* Front, HP selectors; from Mix */
1549         {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
1550         {0x06, AC_VERB_SET_CONNECT_SEL, 0x01},
1551         /* Mono selector; from Mix */
1552         {0x0b, AC_VERB_SET_CONNECT_SEL, 0x03},
1553         /* Mic selector; Mic */
1554         {0x0c, AC_VERB_SET_CONNECT_SEL, 0x0},
1555         /* Line-in selector: Line-in */
1556         {0x0d, AC_VERB_SET_CONNECT_SEL, 0x0},
1557         /* Mic boost: 0dB */
1558         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
1559         /* Record selector: mic */
1560         {0x15, AC_VERB_SET_CONNECT_SEL, 0x0},
1561         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1562         /* SPDIF route: PCM */
1563         {0x02, AC_VERB_SET_CONNECT_SEL, 0x0},
1564         /* Front Pin */
1565         {0x05, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
1566         /* HP Pin */
1567         {0x06, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
1568         /* Mono Pin */
1569         {0x07, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
1570         /* Mic Pin */
1571         {0x08, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
1572         /* Line Pin */
1573         {0x09, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
1574         { } /* end */
1575 };
1576 
1577 #ifdef CONFIG_PM
1578 static const struct hda_amp_list ad1983_loopbacks[] = {
1579         { 0x12, HDA_OUTPUT, 0 }, /* Mic */
1580         { 0x13, HDA_OUTPUT, 0 }, /* Line */
1581         { } /* end */
1582 };
1583 #endif
1584 
1585 /* models */
1586 enum {
1587         AD1983_AUTO,
1588         AD1983_BASIC,
1589         AD1983_MODELS
1590 };
1591 
1592 static const char * const ad1983_models[AD1983_MODELS] = {
1593         [AD1983_AUTO]           = "auto",
1594         [AD1983_BASIC]          = "basic",
1595 };
1596 #endif /* ENABLE_AD_STATIC_QUIRKS */
1597 
1598 
1599 /*
1600  * SPDIF mux control for AD1983 auto-parser
1601  */
1602 static int ad1983_auto_smux_enum_info(struct snd_kcontrol *kcontrol,
1603                                       struct snd_ctl_elem_info *uinfo)
1604 {
1605         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1606         struct ad198x_spec *spec = codec->spec;
1607         static const char * const texts2[] = { "PCM", "ADC" };
1608         static const char * const texts3[] = { "PCM", "ADC1", "ADC2" };
1609         hda_nid_t dig_out = spec->gen.multiout.dig_out_nid;
1610         int num_conns = snd_hda_get_num_conns(codec, dig_out);
1611 
1612         if (num_conns == 2)
1613                 return snd_hda_enum_helper_info(kcontrol, uinfo, 2, texts2);
1614         else if (num_conns == 3)
1615                 return snd_hda_enum_helper_info(kcontrol, uinfo, 3, texts3);
1616         else
1617                 return -EINVAL;
1618 }
1619 
1620 static int ad1983_auto_smux_enum_get(struct snd_kcontrol *kcontrol,
1621                                      struct snd_ctl_elem_value *ucontrol)
1622 {
1623         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1624         struct ad198x_spec *spec = codec->spec;
1625 
1626         ucontrol->value.enumerated.item[0] = spec->cur_smux;
1627         return 0;
1628 }
1629 
1630 static int ad1983_auto_smux_enum_put(struct snd_kcontrol *kcontrol,
1631                                      struct snd_ctl_elem_value *ucontrol)
1632 {
1633         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1634         struct ad198x_spec *spec = codec->spec;
1635         unsigned int val = ucontrol->value.enumerated.item[0];
1636         hda_nid_t dig_out = spec->gen.multiout.dig_out_nid;
1637         int num_conns = snd_hda_get_num_conns(codec, dig_out);
1638 
1639         if (val >= num_conns)
1640                 return -EINVAL;
1641         if (spec->cur_smux == val)
1642                 return 0;
1643         spec->cur_smux = val;
1644         snd_hda_codec_write_cache(codec, dig_out, 0,
1645                                   AC_VERB_SET_CONNECT_SEL, val);
1646         return 1;
1647 }
1648 
1649 static struct snd_kcontrol_new ad1983_auto_smux_mixer = {
1650         .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1651         .name = "IEC958 Playback Source",
1652         .info = ad1983_auto_smux_enum_info,
1653         .get = ad1983_auto_smux_enum_get,
1654         .put = ad1983_auto_smux_enum_put,
1655 };
1656 
1657 static int ad1983_add_spdif_mux_ctl(struct hda_codec *codec)
1658 {
1659         struct ad198x_spec *spec = codec->spec;
1660         hda_nid_t dig_out = spec->gen.multiout.dig_out_nid;
1661         int num_conns;
1662 
1663         if (!dig_out)
1664                 return 0;
1665         num_conns = snd_hda_get_num_conns(codec, dig_out);
1666         if (num_conns != 2 && num_conns != 3)
1667                 return 0;
1668         if (!snd_hda_gen_add_kctl(&spec->gen, NULL, &ad1983_auto_smux_mixer))
1669                 return -ENOMEM;
1670         return 0;
1671 }
1672 
1673 static int ad1983_parse_auto_config(struct hda_codec *codec)
1674 {
1675         struct ad198x_spec *spec;
1676         int err;
1677 
1678         err = alloc_ad_spec(codec);
1679         if (err < 0)
1680                 return err;
1681         spec = codec->spec;
1682 
1683         spec->gen.mixer_nid = 0x0e;
1684         spec->gen.beep_nid = 0x10;
1685         set_beep_amp(spec, 0x10, 0, HDA_OUTPUT);
1686         err = ad198x_parse_auto_config(codec);
1687         if (err < 0)
1688                 goto error;
1689         err = ad1983_add_spdif_mux_ctl(codec);
1690         if (err < 0)
1691                 goto error;
1692         return 0;
1693 
1694  error:
1695         snd_hda_gen_free(codec);
1696         return err;
1697 }
1698 
1699 #ifdef ENABLE_AD_STATIC_QUIRKS
1700 static int patch_ad1983(struct hda_codec *codec)
1701 {
1702         struct ad198x_spec *spec;
1703         int board_config;
1704         int err;
1705 
1706         board_config = snd_hda_check_board_config(codec, AD1983_MODELS,
1707                                                   ad1983_models, NULL);
1708         if (board_config < 0) {
1709                 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
1710                        codec->chip_name);
1711                 board_config = AD1983_AUTO;
1712         }
1713 
1714         if (board_config == AD1983_AUTO)
1715                 return ad1983_parse_auto_config(codec);
1716 
1717         err = alloc_ad_spec(codec);
1718         if (err < 0)
1719                 return err;
1720         spec = codec->spec;
1721 
1722         err = snd_hda_attach_beep_device(codec, 0x10);
1723         if (err < 0) {
1724                 ad198x_free(codec);
1725                 return err;
1726         }
1727         set_beep_amp(spec, 0x10, 0, HDA_OUTPUT);
1728 
1729         spec->multiout.max_channels = 2;
1730         spec->multiout.num_dacs = ARRAY_SIZE(ad1983_dac_nids);
1731         spec->multiout.dac_nids = ad1983_dac_nids;
1732         spec->multiout.dig_out_nid = AD1983_SPDIF_OUT;
1733         spec->num_adc_nids = 1;
1734         spec->adc_nids = ad1983_adc_nids;
1735         spec->capsrc_nids = ad1983_capsrc_nids;
1736         spec->input_mux = &ad1983_capture_source;
1737         spec->num_mixers = 1;
1738         spec->mixers[0] = ad1983_mixers;
1739         spec->num_init_verbs = 1;
1740         spec->init_verbs[0] = ad1983_init_verbs;
1741         spec->spdif_route = 0;
1742 #ifdef CONFIG_PM
1743         spec->loopback.amplist = ad1983_loopbacks;
1744 #endif
1745         spec->vmaster_nid = 0x05;
1746 
1747         codec->patch_ops = ad198x_patch_ops;
1748 
1749         codec->no_trigger_sense = 1;
1750         codec->no_sticky_stream = 1;
1751 
1752         return 0;
1753 }
1754 #else /* ENABLE_AD_STATIC_QUIRKS */
1755 #define patch_ad1983    ad1983_parse_auto_config
1756 #endif /* ENABLE_AD_STATIC_QUIRKS */
1757 
1758 
1759 /*
1760  * AD1981 HD specific
1761  */
1762 
1763 #ifdef ENABLE_AD_STATIC_QUIRKS
1764 #define AD1981_SPDIF_OUT        0x02
1765 #define AD1981_DAC              0x03
1766 #define AD1981_ADC              0x04
1767 
1768 static const hda_nid_t ad1981_dac_nids[1] = { AD1981_DAC };
1769 static const hda_nid_t ad1981_adc_nids[1] = { AD1981_ADC };
1770 static const hda_nid_t ad1981_capsrc_nids[1] = { 0x15 };
1771 
1772 /* 0x0c, 0x09, 0x0e, 0x0f, 0x19, 0x05, 0x18, 0x17 */
1773 static const struct hda_input_mux ad1981_capture_source = {
1774         .num_items = 7,
1775         .items = {
1776                 { "Front Mic", 0x0 },
1777                 { "Line", 0x1 },
1778                 { "Mix", 0x2 },
1779                 { "Mix Mono", 0x3 },
1780                 { "CD", 0x4 },
1781                 { "Mic", 0x6 },
1782                 { "Aux", 0x7 },
1783         },
1784 };
1785 
1786 static const struct snd_kcontrol_new ad1981_mixers[] = {
1787         HDA_CODEC_VOLUME("Front Playback Volume", 0x05, 0x0, HDA_OUTPUT),
1788         HDA_CODEC_MUTE("Front Playback Switch", 0x05, 0x0, HDA_OUTPUT),
1789         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x06, 0x0, HDA_OUTPUT),
1790         HDA_CODEC_MUTE("Headphone Playback Switch", 0x06, 0x0, HDA_OUTPUT),
1791         HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x07, 1, 0x0, HDA_OUTPUT),
1792         HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x07, 1, 0x0, HDA_OUTPUT),
1793         HDA_CODEC_VOLUME("PCM Playback Volume", 0x11, 0x0, HDA_OUTPUT),
1794         HDA_CODEC_MUTE("PCM Playback Switch", 0x11, 0x0, HDA_OUTPUT),
1795         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x12, 0x0, HDA_OUTPUT),
1796         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x12, 0x0, HDA_OUTPUT),
1797         HDA_CODEC_VOLUME("Line Playback Volume", 0x13, 0x0, HDA_OUTPUT),
1798         HDA_CODEC_MUTE("Line Playback Switch", 0x13, 0x0, HDA_OUTPUT),
1799         HDA_CODEC_VOLUME("Aux Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
1800         HDA_CODEC_MUTE("Aux Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1801         HDA_CODEC_VOLUME("Mic Playback Volume", 0x1c, 0x0, HDA_OUTPUT),
1802         HDA_CODEC_MUTE("Mic Playback Switch", 0x1c, 0x0, HDA_OUTPUT),
1803         HDA_CODEC_VOLUME("CD Playback Volume", 0x1d, 0x0, HDA_OUTPUT),
1804         HDA_CODEC_MUTE("CD Playback Switch", 0x1d, 0x0, HDA_OUTPUT),
1805         HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x08, 0x0, HDA_INPUT),
1806         HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0x0, HDA_INPUT),
1807         HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT),
1808         HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_OUTPUT),
1809         {
1810                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1811                 .name = "Capture Source",
1812                 .info = ad198x_mux_enum_info,
1813                 .get = ad198x_mux_enum_get,
1814                 .put = ad198x_mux_enum_put,
1815         },
1816         /* identical with AD1983 */
1817         {
1818                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1819                 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
1820                 .info = ad1983_spdif_route_info,
1821                 .get = ad1983_spdif_route_get,
1822                 .put = ad1983_spdif_route_put,
1823         },
1824         { } /* end */
1825 };
1826 
1827 static const struct hda_verb ad1981_init_verbs[] = {
1828         /* Front, HP, Mono; mute as default */
1829         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1830         {0x06, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1831         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1832         /* Beep, PCM, Front Mic, Line, Rear Mic, Aux, CD-In: mute */
1833         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1834         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1835         {0x12, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1836         {0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1837         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1838         {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1839         {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1840         /* Front, HP selectors; from Mix */
1841         {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
1842         {0x06, AC_VERB_SET_CONNECT_SEL, 0x01},
1843         /* Mono selector; from Mix */
1844         {0x0b, AC_VERB_SET_CONNECT_SEL, 0x03},
1845         /* Mic Mixer; select Front Mic */
1846         {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
1847         {0x1f, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1848         /* Mic boost: 0dB */
1849         {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1850         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1851         /* Record selector: Front mic */
1852         {0x15, AC_VERB_SET_CONNECT_SEL, 0x0},
1853         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1854         /* SPDIF route: PCM */
1855         {0x02, AC_VERB_SET_CONNECT_SEL, 0x0},
1856         /* Front Pin */
1857         {0x05, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
1858         /* HP Pin */
1859         {0x06, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
1860         /* Mono Pin */
1861         {0x07, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
1862         /* Front & Rear Mic Pins */
1863         {0x08, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
1864         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
1865         /* Line Pin */
1866         {0x09, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
1867         /* Digital Beep */
1868         {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
1869         /* Line-Out as Input: disabled */
1870         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1871         { } /* end */
1872 };
1873 
1874 #ifdef CONFIG_PM
1875 static const struct hda_amp_list ad1981_loopbacks[] = {
1876         { 0x12, HDA_OUTPUT, 0 }, /* Front Mic */
1877         { 0x13, HDA_OUTPUT, 0 }, /* Line */
1878         { 0x1b, HDA_OUTPUT, 0 }, /* Aux */
1879         { 0x1c, HDA_OUTPUT, 0 }, /* Mic */
1880         { 0x1d, HDA_OUTPUT, 0 }, /* CD */
1881         { } /* end */
1882 };
1883 #endif
1884 
1885 /*
1886  * Patch for HP nx6320
1887  *
1888  * nx6320 uses EAPD in the reverse way - EAPD-on means the internal
1889  * speaker output enabled _and_ mute-LED off.
1890  */
1891 
1892 #define AD1981_HP_EVENT         0x37
1893 #define AD1981_MIC_EVENT        0x38
1894 
1895 static const struct hda_verb ad1981_hp_init_verbs[] = {
1896         {0x05, AC_VERB_SET_EAPD_BTLENABLE, 0x00 }, /* default off */
1897         /* pin sensing on HP and Mic jacks */
1898         {0x06, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1981_HP_EVENT},
1899         {0x08, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1981_MIC_EVENT},
1900         {}
1901 };
1902 
1903 /* turn on/off EAPD (+ mute HP) as a master switch */
1904 static int ad1981_hp_master_sw_put(struct snd_kcontrol *kcontrol,
1905                                    struct snd_ctl_elem_value *ucontrol)
1906 {
1907         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1908         struct ad198x_spec *spec = codec->spec;
1909 
1910         if (! ad198x_eapd_put(kcontrol, ucontrol))
1911                 return 0;
1912         /* change speaker pin appropriately */
1913         snd_hda_set_pin_ctl(codec, 0x05, spec->cur_eapd ? PIN_OUT : 0);
1914         /* toggle HP mute appropriately */
1915         snd_hda_codec_amp_stereo(codec, 0x06, HDA_OUTPUT, 0,
1916                                  HDA_AMP_MUTE,
1917                                  spec->cur_eapd ? 0 : HDA_AMP_MUTE);
1918         return 1;
1919 }
1920 
1921 /* bind volumes of both NID 0x05 and 0x06 */
1922 static const struct hda_bind_ctls ad1981_hp_bind_master_vol = {
1923         .ops = &snd_hda_bind_vol,
1924         .values = {
1925                 HDA_COMPOSE_AMP_VAL(0x05, 3, 0, HDA_OUTPUT),
1926                 HDA_COMPOSE_AMP_VAL(0x06, 3, 0, HDA_OUTPUT),
1927                 0
1928         },
1929 };
1930 
1931 /* mute internal speaker if HP is plugged */
1932 static void ad1981_hp_automute(struct hda_codec *codec)
1933 {
1934         unsigned int present;
1935 
1936         present = snd_hda_jack_detect(codec, 0x06);
1937         snd_hda_codec_amp_stereo(codec, 0x05, HDA_OUTPUT, 0,
1938                                  HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
1939 }
1940 
1941 /* toggle input of built-in and mic jack appropriately */
1942 static void ad1981_hp_automic(struct hda_codec *codec)
1943 {
1944         static const struct hda_verb mic_jack_on[] = {
1945                 {0x1f, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1946                 {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
1947                 {}
1948         };
1949         static const struct hda_verb mic_jack_off[] = {
1950                 {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1951                 {0x1f, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
1952                 {}
1953         };
1954         unsigned int present;
1955 
1956         present = snd_hda_jack_detect(codec, 0x08);
1957         if (present)
1958                 snd_hda_sequence_write(codec, mic_jack_on);
1959         else
1960                 snd_hda_sequence_write(codec, mic_jack_off);
1961 }
1962 
1963 /* unsolicited event for HP jack sensing */
1964 static void ad1981_hp_unsol_event(struct hda_codec *codec,
1965                                   unsigned int res)
1966 {
1967         res >>= 26;
1968         switch (res) {
1969         case AD1981_HP_EVENT:
1970                 ad1981_hp_automute(codec);
1971                 break;
1972         case AD1981_MIC_EVENT:
1973                 ad1981_hp_automic(codec);
1974                 break;
1975         }
1976 }
1977 
1978 static const struct hda_input_mux ad1981_hp_capture_source = {
1979         .num_items = 3,
1980         .items = {
1981                 { "Mic", 0x0 },
1982                 { "Dock Mic", 0x1 },
1983                 { "Mix", 0x2 },
1984         },
1985 };
1986 
1987 static const struct snd_kcontrol_new ad1981_hp_mixers[] = {
1988         HDA_BIND_VOL("Master Playback Volume", &ad1981_hp_bind_master_vol),
1989         {
1990                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1991                 .subdevice = HDA_SUBDEV_NID_FLAG | 0x05,
1992                 .name = "Master Playback Switch",
1993                 .info = ad198x_eapd_info,
1994                 .get = ad198x_eapd_get,
1995                 .put = ad1981_hp_master_sw_put,
1996                 .private_value = 0x05,
1997         },
1998         HDA_CODEC_VOLUME("PCM Playback Volume", 0x11, 0x0, HDA_OUTPUT),
1999         HDA_CODEC_MUTE("PCM Playback Switch", 0x11, 0x0, HDA_OUTPUT),
2000 #if 0
2001         /* FIXME: analog mic/line loopback doesn't work with my tests...
2002          *        (although recording is OK)
2003          */
2004         HDA_CODEC_VOLUME("Mic Playback Volume", 0x12, 0x0, HDA_OUTPUT),
2005         HDA_CODEC_MUTE("Mic Playback Switch", 0x12, 0x0, HDA_OUTPUT),
2006         HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT),
2007         HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x13, 0x0, HDA_OUTPUT),
2008         HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x1c, 0x0, HDA_OUTPUT),
2009         HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x1c, 0x0, HDA_OUTPUT),
2010         /* FIXME: does this laptop have analog CD connection? */
2011         HDA_CODEC_VOLUME("CD Playback Volume", 0x1d, 0x0, HDA_OUTPUT),
2012         HDA_CODEC_MUTE("CD Playback Switch", 0x1d, 0x0, HDA_OUTPUT),
2013 #endif
2014         HDA_CODEC_VOLUME("Mic Boost Volume", 0x08, 0x0, HDA_INPUT),
2015         HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x18, 0x0, HDA_INPUT),
2016         HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT),
2017         HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_OUTPUT),
2018         {
2019                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2020                 .name = "Capture Source",
2021                 .info = ad198x_mux_enum_info,
2022                 .get = ad198x_mux_enum_get,
2023                 .put = ad198x_mux_enum_put,
2024         },
2025         { } /* end */
2026 };
2027 
2028 /* initialize jack-sensing, too */
2029 static int ad1981_hp_init(struct hda_codec *codec)
2030 {
2031         ad198x_init(codec);
2032         ad1981_hp_automute(codec);
2033         ad1981_hp_automic(codec);
2034         return 0;
2035 }
2036 
2037 /* configuration for Toshiba Laptops */
2038 static const struct hda_verb ad1981_toshiba_init_verbs[] = {
2039         {0x05, AC_VERB_SET_EAPD_BTLENABLE, 0x01 }, /* default on */
2040         /* pin sensing on HP and Mic jacks */
2041         {0x06, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1981_HP_EVENT},
2042         {0x08, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1981_MIC_EVENT},
2043         {}
2044 };
2045 
2046 static const struct snd_kcontrol_new ad1981_toshiba_mixers[] = {
2047         HDA_CODEC_VOLUME("Amp Volume", 0x1a, 0x0, HDA_OUTPUT),
2048         HDA_CODEC_MUTE("Amp Switch", 0x1a, 0x0, HDA_OUTPUT),
2049         { }
2050 };
2051 
2052 /* configuration for Lenovo Thinkpad T60 */
2053 static const struct snd_kcontrol_new ad1981_thinkpad_mixers[] = {
2054         HDA_CODEC_VOLUME("Master Playback Volume", 0x05, 0x0, HDA_OUTPUT),
2055         HDA_CODEC_MUTE("Master Playback Switch", 0x05, 0x0, HDA_OUTPUT),
2056         HDA_CODEC_VOLUME("PCM Playback Volume", 0x11, 0x0, HDA_OUTPUT),
2057         HDA_CODEC_MUTE("PCM Playback Switch", 0x11, 0x0, HDA_OUTPUT),
2058         HDA_CODEC_VOLUME("Mic Playback Volume", 0x12, 0x0, HDA_OUTPUT),
2059         HDA_CODEC_MUTE("Mic Playback Switch", 0x12, 0x0, HDA_OUTPUT),
2060         HDA_CODEC_VOLUME("CD Playback Volume", 0x1d, 0x0, HDA_OUTPUT),
2061         HDA_CODEC_MUTE("CD Playback Switch", 0x1d, 0x0, HDA_OUTPUT),
2062         HDA_CODEC_VOLUME("Mic Boost Volume", 0x08, 0x0, HDA_INPUT),
2063         HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT),
2064         HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_OUTPUT),
2065         {
2066                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2067                 .name = "Capture Source",
2068                 .info = ad198x_mux_enum_info,
2069                 .get = ad198x_mux_enum_get,
2070                 .put = ad198x_mux_enum_put,
2071         },
2072         /* identical with AD1983 */
2073         {
2074                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2075                 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
2076                 .info = ad1983_spdif_route_info,
2077                 .get = ad1983_spdif_route_get,
2078                 .put = ad1983_spdif_route_put,
2079         },
2080         { } /* end */
2081 };
2082 
2083 static const struct hda_input_mux ad1981_thinkpad_capture_source = {
2084         .num_items = 3,
2085         .items = {
2086                 { "Mic", 0x0 },
2087                 { "Mix", 0x2 },
2088                 { "CD", 0x4 },
2089         },
2090 };
2091 
2092 /* models */
2093 enum {
2094         AD1981_AUTO,
2095         AD1981_BASIC,
2096         AD1981_HP,
2097         AD1981_THINKPAD,
2098         AD1981_TOSHIBA,
2099         AD1981_MODELS
2100 };
2101 
2102 static const char * const ad1981_models[AD1981_MODELS] = {
2103         [AD1981_AUTO]           = "auto",
2104         [AD1981_HP]             = "hp",
2105         [AD1981_THINKPAD]       = "thinkpad",
2106         [AD1981_BASIC]          = "basic",
2107         [AD1981_TOSHIBA]        = "toshiba"
2108 };
2109 
2110 static const struct snd_pci_quirk ad1981_cfg_tbl[] = {
2111         SND_PCI_QUIRK(0x1014, 0x0597, "Lenovo Z60", AD1981_THINKPAD),
2112         SND_PCI_QUIRK(0x1014, 0x05b7, "Lenovo Z60m", AD1981_THINKPAD),
2113         /* All HP models */
2114         SND_PCI_QUIRK_VENDOR(0x103c, "HP nx", AD1981_HP),
2115         SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba U205", AD1981_TOSHIBA),
2116         /* Lenovo Thinkpad T60/X60/Z6xx */
2117         SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo Thinkpad", AD1981_THINKPAD),
2118         /* HP nx6320 (reversed SSID, H/W bug) */
2119         SND_PCI_QUIRK(0x30b0, 0x103c, "HP nx6320", AD1981_HP),
2120         {}
2121 };
2122 #endif /* ENABLE_AD_STATIC_QUIRKS */
2123 
2124 
2125 /* follow EAPD via vmaster hook */
2126 static void ad_vmaster_eapd_hook(void *private_data, int enabled)
2127 {
2128         struct hda_codec *codec = private_data;
2129         struct ad198x_spec *spec = codec->spec;
2130 
2131         if (!spec->eapd_nid)
2132                 return;
2133         snd_hda_codec_update_cache(codec, spec->eapd_nid, 0,
2134                                    AC_VERB_SET_EAPD_BTLENABLE,
2135                                    enabled ? 0x02 : 0x00);
2136 }
2137 
2138 static void ad1981_fixup_hp_eapd(struct hda_codec *codec,
2139                                  const struct hda_fixup *fix, int action)
2140 {
2141         struct ad198x_spec *spec = codec->spec;
2142 
2143         if (action == HDA_FIXUP_ACT_PRE_PROBE) {
2144                 spec->gen.vmaster_mute.hook = ad_vmaster_eapd_hook;
2145                 spec->eapd_nid = 0x05;
2146         }
2147 }
2148 
2149 /* set the upper-limit for mixer amp to 0dB for avoiding the possible
2150  * damage by overloading
2151  */
2152 static void ad1981_fixup_amp_override(struct hda_codec *codec,
2153                                       const struct hda_fixup *fix, int action)
2154 {
2155         if (action == HDA_FIXUP_ACT_PRE_PROBE)
2156                 snd_hda_override_amp_caps(codec, 0x11, HDA_INPUT,
2157                                           (0x17 << AC_AMPCAP_OFFSET_SHIFT) |
2158                                           (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) |
2159                                           (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) |
2160                                           (1 << AC_AMPCAP_MUTE_SHIFT));
2161 }
2162 
2163 enum {
2164         AD1981_FIXUP_AMP_OVERRIDE,
2165         AD1981_FIXUP_HP_EAPD,
2166 };
2167 
2168 static const struct hda_fixup ad1981_fixups[] = {
2169         [AD1981_FIXUP_AMP_OVERRIDE] = {
2170                 .type = HDA_FIXUP_FUNC,
2171                 .v.func = ad1981_fixup_amp_override,
2172         },
2173         [AD1981_FIXUP_HP_EAPD] = {
2174                 .type = HDA_FIXUP_FUNC,
2175                 .v.func = ad1981_fixup_hp_eapd,
2176                 .chained = true,
2177                 .chain_id = AD1981_FIXUP_AMP_OVERRIDE,
2178         },
2179 };
2180 
2181 static const struct snd_pci_quirk ad1981_fixup_tbl[] = {
2182         SND_PCI_QUIRK_VENDOR(0x1014, "Lenovo", AD1981_FIXUP_AMP_OVERRIDE),
2183         SND_PCI_QUIRK_VENDOR(0x103c, "HP", AD1981_FIXUP_HP_EAPD),
2184         SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", AD1981_FIXUP_AMP_OVERRIDE),
2185         /* HP nx6320 (reversed SSID, H/W bug) */
2186         SND_PCI_QUIRK(0x30b0, 0x103c, "HP nx6320", AD1981_FIXUP_HP_EAPD),
2187         {}
2188 };
2189 
2190 static int ad1981_parse_auto_config(struct hda_codec *codec)
2191 {
2192         struct ad198x_spec *spec;
2193         int err;
2194 
2195         err = alloc_ad_spec(codec);
2196         if (err < 0)
2197                 return -ENOMEM;
2198         spec = codec->spec;
2199 
2200         spec->gen.mixer_nid = 0x0e;
2201         spec->gen.beep_nid = 0x10;
2202         set_beep_amp(spec, 0x0d, 0, HDA_OUTPUT);
2203 
2204         snd_hda_pick_fixup(codec, NULL, ad1981_fixup_tbl, ad1981_fixups);
2205         snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
2206 
2207         err = ad198x_parse_auto_config(codec);
2208         if (err < 0)
2209                 goto error;
2210         err = ad1983_add_spdif_mux_ctl(codec);
2211         if (err < 0)
2212                 goto error;
2213 
2214         snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
2215 
2216         return 0;
2217 
2218  error:
2219         snd_hda_gen_free(codec);
2220         return err;
2221 }
2222 
2223 #ifdef ENABLE_AD_STATIC_QUIRKS
2224 static int patch_ad1981(struct hda_codec *codec)
2225 {
2226         struct ad198x_spec *spec;
2227         int err, board_config;
2228 
2229         board_config = snd_hda_check_board_config(codec, AD1981_MODELS,
2230                                                   ad1981_models,
2231                                                   ad1981_cfg_tbl);
2232         if (board_config < 0) {
2233                 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
2234                        codec->chip_name);
2235                 board_config = AD1981_AUTO;
2236         }
2237 
2238         if (board_config == AD1981_AUTO)
2239                 return ad1981_parse_auto_config(codec);
2240 
2241         err = alloc_ad_spec(codec);
2242         if (err < 0)
2243                 return -ENOMEM;
2244         spec = codec->spec;
2245 
2246         err = snd_hda_attach_beep_device(codec, 0x10);
2247         if (err < 0) {
2248                 ad198x_free(codec);
2249                 return err;
2250         }
2251         set_beep_amp(spec, 0x0d, 0, HDA_OUTPUT);
2252 
2253         spec->multiout.max_channels = 2;
2254         spec->multiout.num_dacs = ARRAY_SIZE(ad1981_dac_nids);
2255         spec->multiout.dac_nids = ad1981_dac_nids;
2256         spec->multiout.dig_out_nid = AD1981_SPDIF_OUT;
2257         spec->num_adc_nids = 1;
2258         spec->adc_nids = ad1981_adc_nids;
2259         spec->capsrc_nids = ad1981_capsrc_nids;
2260         spec->input_mux = &ad1981_capture_source;
2261         spec->num_mixers = 1;
2262         spec->mixers[0] = ad1981_mixers;
2263         spec->num_init_verbs = 1;
2264         spec->init_verbs[0] = ad1981_init_verbs;
2265         spec->spdif_route = 0;
2266 #ifdef CONFIG_PM
2267         spec->loopback.amplist = ad1981_loopbacks;
2268 #endif
2269         spec->vmaster_nid = 0x05;
2270 
2271         codec->patch_ops = ad198x_patch_ops;
2272 
2273         /* override some parameters */
2274         switch (board_config) {
2275         case AD1981_HP:
2276                 spec->mixers[0] = ad1981_hp_mixers;
2277                 spec->num_init_verbs = 2;
2278                 spec->init_verbs[1] = ad1981_hp_init_verbs;
2279                 if (!is_jack_available(codec, 0x0a))
2280                         spec->multiout.dig_out_nid = 0;
2281                 spec->input_mux = &ad1981_hp_capture_source;
2282 
2283                 codec->patch_ops.init = ad1981_hp_init;
2284                 codec->patch_ops.unsol_event = ad1981_hp_unsol_event;
2285                 /* set the upper-limit for mixer amp to 0dB for avoiding the
2286                  * possible damage by overloading
2287                  */
2288                 snd_hda_override_amp_caps(codec, 0x11, HDA_INPUT,
2289                                           (0x17 << AC_AMPCAP_OFFSET_SHIFT) |
2290                                           (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) |
2291                                           (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) |
2292                                           (1 << AC_AMPCAP_MUTE_SHIFT));
2293                 break;
2294         case AD1981_THINKPAD:
2295                 spec->mixers[0] = ad1981_thinkpad_mixers;
2296                 spec->input_mux = &ad1981_thinkpad_capture_source;
2297                 /* set the upper-limit for mixer amp to 0dB for avoiding the
2298                  * possible damage by overloading
2299                  */
2300                 snd_hda_override_amp_caps(codec, 0x11, HDA_INPUT,
2301                                           (0x17 << AC_AMPCAP_OFFSET_SHIFT) |
2302                                           (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) |
2303                                           (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) |
2304                                           (1 << AC_AMPCAP_MUTE_SHIFT));
2305                 break;
2306         case AD1981_TOSHIBA:
2307                 spec->mixers[0] = ad1981_hp_mixers;
2308                 spec->mixers[1] = ad1981_toshiba_mixers;
2309                 spec->num_init_verbs = 2;
2310                 spec->init_verbs[1] = ad1981_toshiba_init_verbs;
2311                 spec->multiout.dig_out_nid = 0;
2312                 spec->input_mux = &ad1981_hp_capture_source;
2313                 codec->patch_ops.init = ad1981_hp_init;
2314                 codec->patch_ops.unsol_event = ad1981_hp_unsol_event;
2315                 break;
2316         }
2317 
2318         codec->no_trigger_sense = 1;
2319         codec->no_sticky_stream = 1;
2320 
2321         return 0;
2322 }
2323 #else /* ENABLE_AD_STATIC_QUIRKS */
2324 #define patch_ad1981    ad1981_parse_auto_config
2325 #endif /* ENABLE_AD_STATIC_QUIRKS */
2326 
2327 
2328 /*
2329  * AD1988
2330  *
2331  * Output pins and routes
2332  *
2333  *        Pin               Mix     Sel     DAC (*)
2334  * port-A 0x11 (mute/hp) <- 0x22 <- 0x37 <- 03/04/06
2335  * port-B 0x14 (mute/hp) <- 0x2b <- 0x30 <- 03/04/06
2336  * port-C 0x15 (mute)    <- 0x2c <- 0x31 <- 05/0a
2337  * port-D 0x12 (mute/hp) <- 0x29         <- 04
2338  * port-E 0x17 (mute/hp) <- 0x26 <- 0x32 <- 05/0a
2339  * port-F 0x16 (mute)    <- 0x2a         <- 06
2340  * port-G 0x24 (mute)    <- 0x27         <- 05
2341  * port-H 0x25 (mute)    <- 0x28         <- 0a
2342  * mono   0x13 (mute/amp)<- 0x1e <- 0x36 <- 03/04/06
2343  *
2344  * DAC0 = 03h, DAC1 = 04h, DAC2 = 05h, DAC3 = 06h, DAC4 = 0ah
2345  * (*) DAC2/3/4 are swapped to DAC3/4/2 on AD198A rev.2 due to a h/w bug.
2346  *
2347  * Input pins and routes
2348  *
2349  *        pin     boost   mix input # / adc input #
2350  * port-A 0x11 -> 0x38 -> mix 2, ADC 0
2351  * port-B 0x14 -> 0x39 -> mix 0, ADC 1
2352  * port-C 0x15 -> 0x3a -> 33:0 - mix 1, ADC 2
2353  * port-D 0x12 -> 0x3d -> mix 3, ADC 8
2354  * port-E 0x17 -> 0x3c -> 34:0 - mix 4, ADC 4
2355  * port-F 0x16 -> 0x3b -> mix 5, ADC 3
2356  * port-G 0x24 -> N/A  -> 33:1 - mix 1, 34:1 - mix 4, ADC 6
2357  * port-H 0x25 -> N/A  -> 33:2 - mix 1, 34:2 - mix 4, ADC 7
2358  *
2359  *
2360  * DAC assignment
2361  *   6stack - front/surr/CLFE/side/opt DACs - 04/06/05/0a/03
2362  *   3stack - front/surr/CLFE/opt DACs - 04/05/0a/03
2363  *
2364  * Inputs of Analog Mix (0x20)
2365  *   0:Port-B (front mic)
2366  *   1:Port-C/G/H (line-in)
2367  *   2:Port-A
2368  *   3:Port-D (line-in/2)
2369  *   4:Port-E/G/H (mic-in)
2370  *   5:Port-F (mic2-in)
2371  *   6:CD
2372  *   7:Beep
2373  *
2374  * ADC selection
2375  *   0:Port-A
2376  *   1:Port-B (front mic-in)
2377  *   2:Port-C (line-in)
2378  *   3:Port-F (mic2-in)
2379  *   4:Port-E (mic-in)
2380  *   5:CD
2381  *   6:Port-G
2382  *   7:Port-H
2383  *   8:Port-D (line-in/2)
2384  *   9:Mix
2385  *
2386  * Proposed pin assignments by the datasheet
2387  *
2388  * 6-stack
2389  * Port-A front headphone
2390  *      B front mic-in
2391  *      C rear line-in
2392  *      D rear front-out
2393  *      E rear mic-in
2394  *      F rear surround
2395  *      G rear CLFE
2396  *      H rear side
2397  *
2398  * 3-stack
2399  * Port-A front headphone
2400  *      B front mic
2401  *      C rear line-in/surround
2402  *      D rear front-out
2403  *      E rear mic-in/CLFE
2404  *
2405  * laptop
2406  * Port-A headphone
2407  *      B mic-in
2408  *      C docking station
2409  *      D internal speaker (with EAPD)
2410  *      E/F quad mic array
2411  */
2412 
2413 
2414 #ifdef ENABLE_AD_STATIC_QUIRKS
2415 /* models */
2416 enum {
2417         AD1988_AUTO,
2418         AD1988_6STACK,
2419         AD1988_6STACK_DIG,
2420         AD1988_3STACK,
2421         AD1988_3STACK_DIG,
2422         AD1988_LAPTOP,
2423         AD1988_LAPTOP_DIG,
2424         AD1988_MODEL_LAST,
2425 };
2426 
2427 /* reivision id to check workarounds */
2428 #define AD1988A_REV2            0x100200
2429 
2430 #define is_rev2(codec) \
2431         ((codec)->vendor_id == 0x11d41988 && \
2432          (codec)->revision_id == AD1988A_REV2)
2433 
2434 /*
2435  * mixers
2436  */
2437 
2438 static const hda_nid_t ad1988_6stack_dac_nids[4] = {
2439         0x04, 0x06, 0x05, 0x0a
2440 };
2441 
2442 static const hda_nid_t ad1988_3stack_dac_nids[3] = {
2443         0x04, 0x05, 0x0a
2444 };
2445 
2446 /* for AD1988A revision-2, DAC2-4 are swapped */
2447 static const hda_nid_t ad1988_6stack_dac_nids_rev2[4] = {
2448         0x04, 0x05, 0x0a, 0x06
2449 };
2450 
2451 static const hda_nid_t ad1988_alt_dac_nid[1] = {
2452         0x03
2453 };
2454 
2455 static const hda_nid_t ad1988_3stack_dac_nids_rev2[3] = {
2456         0x04, 0x0a, 0x06
2457 };
2458 
2459 static const hda_nid_t ad1988_adc_nids[3] = {
2460         0x08, 0x09, 0x0f
2461 };
2462 
2463 static const hda_nid_t ad1988_capsrc_nids[3] = {
2464         0x0c, 0x0d, 0x0e
2465 };
2466 
2467 #define AD1988_SPDIF_OUT                0x02
2468 #define AD1988_SPDIF_OUT_HDMI   0x0b
2469 #define AD1988_SPDIF_IN         0x07
2470 
2471 static const hda_nid_t ad1989b_slave_dig_outs[] = {
2472         AD1988_SPDIF_OUT, AD1988_SPDIF_OUT_HDMI, 0
2473 };
2474 
2475 static const struct hda_input_mux ad1988_6stack_capture_source = {
2476         .num_items = 5,
2477         .items = {
2478                 { "Front Mic", 0x1 },   /* port-B */
2479                 { "Line", 0x2 },        /* port-C */
2480                 { "Mic", 0x4 },         /* port-E */
2481                 { "CD", 0x5 },
2482                 { "Mix", 0x9 },
2483         },
2484 };
2485 
2486 static const struct hda_input_mux ad1988_laptop_capture_source = {
2487         .num_items = 3,
2488         .items = {
2489                 { "Mic/Line", 0x1 },    /* port-B */
2490                 { "CD", 0x5 },
2491                 { "Mix", 0x9 },
2492         },
2493 };
2494 
2495 /*
2496  */
2497 static int ad198x_ch_mode_info(struct snd_kcontrol *kcontrol,
2498                                struct snd_ctl_elem_info *uinfo)
2499 {
2500         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2501         struct ad198x_spec *spec = codec->spec;
2502         return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
2503                                     spec->num_channel_mode);
2504 }
2505 
2506 static int ad198x_ch_mode_get(struct snd_kcontrol *kcontrol,
2507                               struct snd_ctl_elem_value *ucontrol)
2508 {
2509         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2510         struct ad198x_spec *spec = codec->spec;
2511         return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
2512                                    spec->num_channel_mode, spec->multiout.max_channels);
2513 }
2514 
2515 static int ad198x_ch_mode_put(struct snd_kcontrol *kcontrol,
2516                               struct snd_ctl_elem_value *ucontrol)
2517 {
2518         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2519         struct ad198x_spec *spec = codec->spec;
2520         int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
2521                                       spec->num_channel_mode,
2522                                       &spec->multiout.max_channels);
2523         if (err >= 0 && spec->need_dac_fix)
2524                 spec->multiout.num_dacs = spec->multiout.max_channels / 2;
2525         return err;
2526 }
2527 
2528 /* 6-stack mode */
2529 static const struct snd_kcontrol_new ad1988_6stack_mixers1[] = {
2530         HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT),
2531         HDA_CODEC_VOLUME("Surround Playback Volume", 0x06, 0x0, HDA_OUTPUT),
2532         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x05, 1, 0x0, HDA_OUTPUT),
2533         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x05, 2, 0x0, HDA_OUTPUT),
2534         HDA_CODEC_VOLUME("Side Playback Volume", 0x0a, 0x0, HDA_OUTPUT),
2535         { } /* end */
2536 };
2537 
2538 static const struct snd_kcontrol_new ad1988_6stack_mixers1_rev2[] = {
2539         HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT),
2540         HDA_CODEC_VOLUME("Surround Playback Volume", 0x05, 0x0, HDA_OUTPUT),
2541         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
2542         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0a, 2, 0x0, HDA_OUTPUT),
2543         HDA_CODEC_VOLUME("Side Playback Volume", 0x06, 0x0, HDA_OUTPUT),
2544         { } /* end */
2545 };
2546 
2547 static const struct snd_kcontrol_new ad1988_6stack_mixers2[] = {
2548         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
2549         HDA_BIND_MUTE("Front Playback Switch", 0x29, 2, HDA_INPUT),
2550         HDA_BIND_MUTE("Surround Playback Switch", 0x2a, 2, HDA_INPUT),
2551         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x27, 1, 2, HDA_INPUT),
2552         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x27, 2, 2, HDA_INPUT),
2553         HDA_BIND_MUTE("Side Playback Switch", 0x28, 2, HDA_INPUT),
2554         HDA_BIND_MUTE("Headphone Playback Switch", 0x22, 2, HDA_INPUT),
2555         HDA_BIND_MUTE("Mono Playback Switch", 0x1e, 2, HDA_INPUT),
2556 
2557         HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x6, HDA_INPUT),
2558         HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x6, HDA_INPUT),
2559         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x0, HDA_INPUT),
2560         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x0, HDA_INPUT),
2561         HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x1, HDA_INPUT),
2562         HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x1, HDA_INPUT),
2563         HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x4, HDA_INPUT),
2564         HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x4, HDA_INPUT),
2565 
2566         HDA_CODEC_VOLUME("Analog Mix Playback Volume", 0x21, 0x0, HDA_OUTPUT),
2567         HDA_CODEC_MUTE("Analog Mix Playback Switch", 0x21, 0x0, HDA_OUTPUT),
2568 
2569         HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x39, 0x0, HDA_OUTPUT),
2570         HDA_CODEC_VOLUME("Mic Boost Volume", 0x3c, 0x0, HDA_OUTPUT),
2571         { } /* end */
2572 };
2573 
2574 /* 3-stack mode */
2575 static const struct snd_kcontrol_new ad1988_3stack_mixers1[] = {
2576         HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT),
2577         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0a, 0x0, HDA_OUTPUT),
2578         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x05, 1, 0x0, HDA_OUTPUT),
2579         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x05, 2, 0x0, HDA_OUTPUT),
2580         { } /* end */
2581 };
2582 
2583 static const struct snd_kcontrol_new ad1988_3stack_mixers1_rev2[] = {
2584         HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT),
2585         HDA_CODEC_VOLUME("Surround Playback Volume", 0x0a, 0x0, HDA_OUTPUT),
2586         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x06, 1, 0x0, HDA_OUTPUT),
2587         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x06, 2, 0x0, HDA_OUTPUT),
2588         { } /* end */
2589 };
2590 
2591 static const struct snd_kcontrol_new ad1988_3stack_mixers2[] = {
2592         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
2593         HDA_BIND_MUTE("Front Playback Switch", 0x29, 2, HDA_INPUT),
2594         HDA_BIND_MUTE("Surround Playback Switch", 0x2c, 2, HDA_INPUT),
2595         HDA_BIND_MUTE_MONO("Center Playback Switch", 0x26, 1, 2, HDA_INPUT),
2596         HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x26, 2, 2, HDA_INPUT),
2597         HDA_BIND_MUTE("Headphone Playback Switch", 0x22, 2, HDA_INPUT),
2598         HDA_BIND_MUTE("Mono Playback Switch", 0x1e, 2, HDA_INPUT),
2599 
2600         HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x6, HDA_INPUT),
2601         HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x6, HDA_INPUT),
2602         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x0, HDA_INPUT),
2603         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x0, HDA_INPUT),
2604         HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x1, HDA_INPUT),
2605         HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x1, HDA_INPUT),
2606         HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x4, HDA_INPUT),
2607         HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x4, HDA_INPUT),
2608 
2609         HDA_CODEC_VOLUME("Analog Mix Playback Volume", 0x21, 0x0, HDA_OUTPUT),
2610         HDA_CODEC_MUTE("Analog Mix Playback Switch", 0x21, 0x0, HDA_OUTPUT),
2611 
2612         HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x39, 0x0, HDA_OUTPUT),
2613         HDA_CODEC_VOLUME("Mic Boost Volume", 0x3c, 0x0, HDA_OUTPUT),
2614         {
2615                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2616                 .name = "Channel Mode",
2617                 .info = ad198x_ch_mode_info,
2618                 .get = ad198x_ch_mode_get,
2619                 .put = ad198x_ch_mode_put,
2620         },
2621 
2622         { } /* end */
2623 };
2624 
2625 /* laptop mode */
2626 static const struct snd_kcontrol_new ad1988_laptop_mixers[] = {
2627         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
2628         HDA_CODEC_VOLUME("PCM Playback Volume", 0x04, 0x0, HDA_OUTPUT),
2629         HDA_CODEC_MUTE("PCM Playback Switch", 0x29, 0x0, HDA_INPUT),
2630         HDA_BIND_MUTE("Mono Playback Switch", 0x1e, 2, HDA_INPUT),
2631 
2632         HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x6, HDA_INPUT),
2633         HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x6, HDA_INPUT),
2634         HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x0, HDA_INPUT),
2635         HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x0, HDA_INPUT),
2636         HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x1, HDA_INPUT),
2637         HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x1, HDA_INPUT),
2638 
2639         HDA_CODEC_VOLUME("Analog Mix Playback Volume", 0x21, 0x0, HDA_OUTPUT),
2640         HDA_CODEC_MUTE("Analog Mix Playback Switch", 0x21, 0x0, HDA_OUTPUT),
2641 
2642         HDA_CODEC_VOLUME("Mic Boost Volume", 0x39, 0x0, HDA_OUTPUT),
2643 
2644         {
2645                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2646                 .name = "External Amplifier",
2647                 .subdevice = HDA_SUBDEV_NID_FLAG | 0x12,
2648                 .info = ad198x_eapd_info,
2649                 .get = ad198x_eapd_get,
2650                 .put = ad198x_eapd_put,
2651                 .private_value = 0x12, /* port-D */
2652         },
2653 
2654         { } /* end */
2655 };
2656 
2657 /* capture */
2658 static const struct snd_kcontrol_new ad1988_capture_mixers[] = {
2659         HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
2660         HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
2661         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT),
2662         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x0d, 0x0, HDA_OUTPUT),
2663         HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x0e, 0x0, HDA_OUTPUT),
2664         HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x0e, 0x0, HDA_OUTPUT),
2665         {
2666                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2667                 /* The multiple "Capture Source" controls confuse alsamixer
2668                  * So call somewhat different..
2669                  */
2670                 /* .name = "Capture Source", */
2671                 .name = "Input Source",
2672                 .count = 3,
2673                 .info = ad198x_mux_enum_info,
2674                 .get = ad198x_mux_enum_get,
2675                 .put = ad198x_mux_enum_put,
2676         },
2677         { } /* end */
2678 };
2679 
2680 static int ad1988_spdif_playback_source_info(struct snd_kcontrol *kcontrol,
2681                                              struct snd_ctl_elem_info *uinfo)
2682 {
2683         static const char * const texts[] = {
2684                 "PCM", "ADC1", "ADC2", "ADC3"
2685         };
2686         uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2687         uinfo->count = 1;
2688         uinfo->value.enumerated.items = 4;
2689         if (uinfo->value.enumerated.item >= 4)
2690                 uinfo->value.enumerated.item = 3;
2691         strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2692         return 0;
2693 }
2694 
2695 static int ad1988_spdif_playback_source_get(struct snd_kcontrol *kcontrol,
2696                                             struct snd_ctl_elem_value *ucontrol)
2697 {
2698         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2699         unsigned int sel;
2700 
2701         sel = snd_hda_codec_read(codec, 0x1d, 0, AC_VERB_GET_AMP_GAIN_MUTE,
2702                                  AC_AMP_GET_INPUT);
2703         if (!(sel & 0x80))
2704                 ucontrol->value.enumerated.item[0] = 0;
2705         else {
2706                 sel = snd_hda_codec_read(codec, 0x0b, 0,
2707                                          AC_VERB_GET_CONNECT_SEL, 0);
2708                 if (sel < 3)
2709                         sel++;
2710                 else
2711                         sel = 0;
2712                 ucontrol->value.enumerated.item[0] = sel;
2713         }
2714         return 0;
2715 }
2716 
2717 static int ad1988_spdif_playback_source_put(struct snd_kcontrol *kcontrol,
2718                                             struct snd_ctl_elem_value *ucontrol)
2719 {
2720         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2721         unsigned int val, sel;
2722         int change;
2723 
2724         val = ucontrol->value.enumerated.item[0];
2725         if (val > 3)
2726                 return -EINVAL;
2727         if (!val) {
2728                 sel = snd_hda_codec_read(codec, 0x1d, 0,
2729                                          AC_VERB_GET_AMP_GAIN_MUTE,
2730                                          AC_AMP_GET_INPUT);
2731                 change = sel & 0x80;
2732                 if (change) {
2733                         snd_hda_codec_write_cache(codec, 0x1d, 0,
2734                                                   AC_VERB_SET_AMP_GAIN_MUTE,
2735                                                   AMP_IN_UNMUTE(0));
2736                         snd_hda_codec_write_cache(codec, 0x1d, 0,
2737                                                   AC_VERB_SET_AMP_GAIN_MUTE,
2738                                                   AMP_IN_MUTE(1));
2739                 }
2740         } else {
2741                 sel = snd_hda_codec_read(codec, 0x1d, 0,
2742                                          AC_VERB_GET_AMP_GAIN_MUTE,
2743                                          AC_AMP_GET_INPUT | 0x01);
2744                 change = sel & 0x80;
2745                 if (change) {
2746                         snd_hda_codec_write_cache(codec, 0x1d, 0,
2747                                                   AC_VERB_SET_AMP_GAIN_MUTE,
2748                                                   AMP_IN_MUTE(0));
2749                         snd_hda_codec_write_cache(codec, 0x1d, 0,
2750                                                   AC_VERB_SET_AMP_GAIN_MUTE,
2751                                                   AMP_IN_UNMUTE(1));
2752                 }
2753                 sel = snd_hda_codec_read(codec, 0x0b, 0,
2754                                          AC_VERB_GET_CONNECT_SEL, 0) + 1;
2755                 change |= sel != val;
2756                 if (change)
2757                         snd_hda_codec_write_cache(codec, 0x0b, 0,
2758                                                   AC_VERB_SET_CONNECT_SEL,
2759                                                   val - 1);
2760         }
2761         return change;
2762 }
2763 
2764 static const struct snd_kcontrol_new ad1988_spdif_out_mixers[] = {
2765         HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
2766         {
2767                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2768                 .name = "IEC958 Playback Source",
2769                 .subdevice = HDA_SUBDEV_NID_FLAG | 0x1b,
2770                 .info = ad1988_spdif_playback_source_info,
2771                 .get = ad1988_spdif_playback_source_get,
2772                 .put = ad1988_spdif_playback_source_put,
2773         },
2774         { } /* end */
2775 };
2776 
2777 static const struct snd_kcontrol_new ad1988_spdif_in_mixers[] = {
2778         HDA_CODEC_VOLUME("IEC958 Capture Volume", 0x1c, 0x0, HDA_INPUT),
2779         { } /* end */
2780 };
2781 
2782 static const struct snd_kcontrol_new ad1989_spdif_out_mixers[] = {
2783         HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
2784         HDA_CODEC_VOLUME("HDMI Playback Volume", 0x1d, 0x0, HDA_OUTPUT),
2785         { } /* end */
2786 };
2787 
2788 /*
2789  * initialization verbs
2790  */
2791 
2792 /*
2793  * for 6-stack (+dig)
2794  */
2795 static const struct hda_verb ad1988_6stack_init_verbs[] = {
2796         /* Front, Surround, CLFE, side DAC; unmute as default */
2797         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2798         {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2799         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2800         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2801         /* Port-A front headphon path */
2802         {0x37, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC0:03h */
2803         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2804         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2805         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2806         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2807         /* Port-D line-out path */
2808         {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2809         {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2810         {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2811         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2812         /* Port-F surround path */
2813         {0x2a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2814         {0x2a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2815         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2816         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2817         /* Port-G CLFE path */
2818         {0x27, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2819         {0x27, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2820         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2821         {0x24, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2822         /* Port-H side path */
2823         {0x28, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2824         {0x28, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2825         {0x25, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2826         {0x25, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2827         /* Mono out path */
2828         {0x36, AC_VERB_SET_CONNECT_SEL, 0x1}, /* DAC1:04h */
2829         {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2830         {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2831         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2832         {0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb01f}, /* unmute, 0dB */
2833         /* Port-B front mic-in path */
2834         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2835         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2836         {0x39, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2837         /* Port-C line-in path */
2838         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2839         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2840         {0x3a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2841         {0x33, AC_VERB_SET_CONNECT_SEL, 0x0},
2842         /* Port-E mic-in path */
2843         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2844         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2845         {0x3c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2846         {0x34, AC_VERB_SET_CONNECT_SEL, 0x0},
2847         /* Analog CD Input */
2848         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2849         /* Analog Mix output amp */
2850         {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x1f}, /* 0dB */
2851 
2852         { }
2853 };
2854 
2855 static const struct hda_verb ad1988_6stack_fp_init_verbs[] = {
2856         /* Headphone; unmute as default */
2857         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2858         /* Port-A front headphon path */
2859         {0x37, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC0:03h */
2860         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2861         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2862         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2863         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2864 
2865         { }
2866 };
2867 
2868 static const struct hda_verb ad1988_capture_init_verbs[] = {
2869         /* mute analog mix */
2870         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2871         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2872         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2873         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2874         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2875         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
2876         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2877         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2878         /* select ADCs - front-mic */
2879         {0x0c, AC_VERB_SET_CONNECT_SEL, 0x1},
2880         {0x0d, AC_VERB_SET_CONNECT_SEL, 0x1},
2881         {0x0e, AC_VERB_SET_CONNECT_SEL, 0x1},
2882 
2883         { }
2884 };
2885 
2886 static const struct hda_verb ad1988_spdif_init_verbs[] = {
2887         /* SPDIF out sel */
2888         {0x02, AC_VERB_SET_CONNECT_SEL, 0x0}, /* PCM */
2889         {0x0b, AC_VERB_SET_CONNECT_SEL, 0x0}, /* ADC1 */
2890         {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2891         {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2892         /* SPDIF out pin */
2893         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */
2894 
2895         { }
2896 };
2897 
2898 static const struct hda_verb ad1988_spdif_in_init_verbs[] = {
2899         /* unmute SPDIF input pin */
2900         {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2901         { }
2902 };
2903 
2904 /* AD1989 has no ADC -> SPDIF route */
2905 static const struct hda_verb ad1989_spdif_init_verbs[] = {
2906         /* SPDIF-1 out pin */
2907         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2908         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */
2909         /* SPDIF-2/HDMI out pin */
2910         {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2911         {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */
2912         { }
2913 };
2914 
2915 /*
2916  * verbs for 3stack (+dig)
2917  */
2918 static const struct hda_verb ad1988_3stack_ch2_init[] = {
2919         /* set port-C to line-in */
2920         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2921         { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2922         /* set port-E to mic-in */
2923         { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2924         { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2925         { } /* end */
2926 };
2927 
2928 static const struct hda_verb ad1988_3stack_ch6_init[] = {
2929         /* set port-C to surround out */
2930         { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2931         { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2932         /* set port-E to CLFE out */
2933         { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2934         { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2935         { } /* end */
2936 };
2937 
2938 static const struct hda_channel_mode ad1988_3stack_modes[2] = {
2939         { 2, ad1988_3stack_ch2_init },
2940         { 6, ad1988_3stack_ch6_init },
2941 };
2942 
2943 static const struct hda_verb ad1988_3stack_init_verbs[] = {
2944         /* Front, Surround, CLFE, side DAC; unmute as default */
2945         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2946         {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2947         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2948         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2949         /* Port-A front headphon path */
2950         {0x37, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC0:03h */
2951         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2952         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2953         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2954         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2955         /* Port-D line-out path */
2956         {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2957         {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2958         {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2959         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2960         /* Mono out path */
2961         {0x36, AC_VERB_SET_CONNECT_SEL, 0x1}, /* DAC1:04h */
2962         {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2963         {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2964         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2965         {0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb01f}, /* unmute, 0dB */
2966         /* Port-B front mic-in path */
2967         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2968         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2969         {0x39, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2970         /* Port-C line-in/surround path - 6ch mode as default */
2971         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2972         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2973         {0x3a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2974         {0x31, AC_VERB_SET_CONNECT_SEL, 0x0}, /* output sel: DAC 0x05 */
2975         {0x33, AC_VERB_SET_CONNECT_SEL, 0x0},
2976         /* Port-E mic-in/CLFE path - 6ch mode as default */
2977         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2978         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2979         {0x3c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2980         {0x32, AC_VERB_SET_CONNECT_SEL, 0x1}, /* output sel: DAC 0x0a */
2981         {0x34, AC_VERB_SET_CONNECT_SEL, 0x0},
2982         /* mute analog mix */
2983         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2984         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2985         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2986         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2987         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2988         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
2989         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2990         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2991         /* select ADCs - front-mic */
2992         {0x0c, AC_VERB_SET_CONNECT_SEL, 0x1},
2993         {0x0d, AC_VERB_SET_CONNECT_SEL, 0x1},
2994         {0x0e, AC_VERB_SET_CONNECT_SEL, 0x1},
2995         /* Analog Mix output amp */
2996         {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x1f}, /* 0dB */
2997         { }
2998 };
2999 
3000 /*
3001  * verbs for laptop mode (+dig)
3002  */
3003 static const struct hda_verb ad1988_laptop_hp_on[] = {
3004         /* unmute port-A and mute port-D */
3005         { 0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
3006         { 0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
3007         { } /* end */
3008 };
3009 static const struct hda_verb ad1988_laptop_hp_off[] = {
3010         /* mute port-A and unmute port-D */
3011         { 0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
3012         { 0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
3013         { } /* end */
3014 };
3015 
3016 #define AD1988_HP_EVENT 0x01
3017 
3018 static const struct hda_verb ad1988_laptop_init_verbs[] = {
3019         /* Front, Surround, CLFE, side DAC; unmute as default */
3020         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3021         {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3022         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3023         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3024         /* Port-A front headphon path */
3025         {0x37, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC0:03h */
3026         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3027         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3028         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3029         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3030         /* unsolicited event for pin-sense */
3031         {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1988_HP_EVENT },
3032         /* Port-D line-out path + EAPD */
3033         {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3034         {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3035         {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3036         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3037         {0x12, AC_VERB_SET_EAPD_BTLENABLE, 0x00}, /* EAPD-off */
3038         /* Mono out path */
3039         {0x36, AC_VERB_SET_CONNECT_SEL, 0x1}, /* DAC1:04h */
3040         {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3041         {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3042         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3043         {0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb01f}, /* unmute, 0dB */
3044         /* Port-B mic-in path */
3045         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3046         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3047         {0x39, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3048         /* Port-C docking station - try to output */
3049         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3050         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3051         {0x3a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3052         {0x33, AC_VERB_SET_CONNECT_SEL, 0x0},
3053         /* mute analog mix */
3054         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3055         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3056         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3057         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3058         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3059         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
3060         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
3061         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
3062         /* select ADCs - mic */
3063         {0x0c, AC_VERB_SET_CONNECT_SEL, 0x1},
3064         {0x0d, AC_VERB_SET_CONNECT_SEL, 0x1},
3065         {0x0e, AC_VERB_SET_CONNECT_SEL, 0x1},
3066         /* Analog Mix output amp */
3067         {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x1f}, /* 0dB */
3068         { }
3069 };
3070 
3071 static void ad1988_laptop_unsol_event(struct hda_codec *codec, unsigned int res)
3072 {
3073         if ((res >> 26) != AD1988_HP_EVENT)
3074                 return;
3075         if (snd_hda_jack_detect(codec, 0x11))
3076                 snd_hda_sequence_write(codec, ad1988_laptop_hp_on);
3077         else
3078                 snd_hda_sequence_write(codec, ad1988_laptop_hp_off);
3079 } 
3080 
3081 #ifdef CONFIG_PM
3082 static const struct hda_amp_list ad1988_loopbacks[] = {
3083         { 0x20, HDA_INPUT, 0 }, /* Front Mic */
3084         { 0x20, HDA_INPUT, 1 }, /* Line */
3085         { 0x20, HDA_INPUT, 4 }, /* Mic */
3086         { 0x20, HDA_INPUT, 6 }, /* CD */
3087         { } /* end */
3088 };
3089 #endif
3090 #endif /* ENABLE_AD_STATIC_QUIRKS */
3091 
3092 static int ad1988_auto_smux_enum_info(struct snd_kcontrol *kcontrol,
3093                                       struct snd_ctl_elem_info *uinfo)
3094 {
3095         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3096         static const char * const texts[] = {
3097                 "PCM", "ADC1", "ADC2", "ADC3",
3098         };
3099         int num_conns = snd_hda_get_num_conns(codec, 0x0b) + 1;
3100         if (num_conns > 4)
3101                 num_conns = 4;
3102         return snd_hda_enum_helper_info(kcontrol, uinfo, num_conns, texts);
3103 }
3104 
3105 static int ad1988_auto_smux_enum_get(struct snd_kcontrol *kcontrol,
3106                                      struct snd_ctl_elem_value *ucontrol)
3107 {
3108         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3109         struct ad198x_spec *spec = codec->spec;
3110 
3111         ucontrol->value.enumerated.item[0] = spec->cur_smux;
3112         return 0;
3113 }
3114 
3115 static int ad1988_auto_smux_enum_put(struct snd_kcontrol *kcontrol,
3116                                      struct snd_ctl_elem_value *ucontrol)
3117 {
3118         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3119         struct ad198x_spec *spec = codec->spec;
3120         unsigned int val = ucontrol->value.enumerated.item[0];
3121         struct nid_path *path;
3122         int num_conns = snd_hda_get_num_conns(codec, 0x0b) + 1;
3123 
3124         if (val >= num_conns)
3125                 return -EINVAL;
3126         if (spec->cur_smux == val)
3127                 return 0;
3128 
3129         mutex_lock(&codec->control_mutex);
3130         codec->cached_write = 1;
3131         path = snd_hda_get_path_from_idx(codec,
3132                                          spec->smux_paths[spec->cur_smux]);
3133         if (path)
3134                 snd_hda_activate_path(codec, path, false, true);
3135         path = snd_hda_get_path_from_idx(codec, spec->smux_paths[val]);
3136         if (path)
3137                 snd_hda_activate_path(codec, path, true, true);
3138         spec->cur_smux = val;
3139         codec->cached_write = 0;
3140         mutex_unlock(&codec->control_mutex);
3141         snd_hda_codec_flush_cache(codec); /* flush the updates */
3142         return 1;
3143 }
3144 
3145 static struct snd_kcontrol_new ad1988_auto_smux_mixer = {
3146         .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3147         .name = "IEC958 Playback Source",
3148         .info = ad1988_auto_smux_enum_info,
3149         .get = ad1988_auto_smux_enum_get,
3150         .put = ad1988_auto_smux_enum_put,
3151 };
3152 
3153 static int ad1988_auto_init(struct hda_codec *codec)
3154 {
3155         struct ad198x_spec *spec = codec->spec;
3156         int i, err;
3157 
3158         err = snd_hda_gen_init(codec);
3159         if (err < 0)
3160                 return err;
3161         if (!spec->gen.autocfg.dig_outs)
3162                 return 0;
3163 
3164         for (i = 0; i < 4; i++) {
3165                 struct nid_path *path;
3166                 path = snd_hda_get_path_from_idx(codec, spec->smux_paths[i]);
3167                 if (path)
3168                         snd_hda_activate_path(codec, path, path->active, false);
3169         }
3170 
3171         return 0;
3172 }
3173 
3174 static int ad1988_add_spdif_mux_ctl(struct hda_codec *codec)
3175 {
3176         struct ad198x_spec *spec = codec->spec;
3177         int i, num_conns;
3178         /* we create four static faked paths, since AD codecs have odd
3179          * widget connections regarding the SPDIF out source
3180          */
3181         static struct nid_path fake_paths[4] = {
3182                 {
3183                         .depth = 3,
3184                         .path = { 0x02, 0x1d, 0x1b },
3185                         .idx = { 0, 0, 0 },
3186                         .multi = { 0, 0, 0 },
3187                 },
3188                 {
3189                         .depth = 4,
3190                         .path = { 0x08, 0x0b, 0x1d, 0x1b },
3191                         .idx = { 0, 0, 1, 0 },
3192                         .multi = { 0, 1, 0, 0 },
3193                 },
3194                 {
3195                         .depth = 4,
3196                         .path = { 0x09, 0x0b, 0x1d, 0x1b },
3197                         .idx = { 0, 1, 1, 0 },
3198                         .multi = { 0, 1, 0, 0 },
3199                 },
3200                 {
3201                         .depth = 4,
3202                         .path = { 0x0f, 0x0b, 0x1d, 0x1b },
3203                         .idx = { 0, 2, 1, 0 },
3204                         .multi = { 0, 1, 0, 0 },
3205                 },
3206         };
3207 
3208         /* SPDIF source mux appears to be present only on AD1988A */
3209         if (!spec->gen.autocfg.dig_outs ||
3210             get_wcaps_type(get_wcaps(codec, 0x1d)) != AC_WID_AUD_MIX)
3211                 return 0;
3212 
3213         num_conns = snd_hda_get_num_conns(codec, 0x0b) + 1;
3214         if (num_conns != 3 && num_conns != 4)
3215                 return 0;
3216 
3217         for (i = 0; i < num_conns; i++) {
3218                 struct nid_path *path = snd_array_new(&spec->gen.paths);
3219                 if (!path)
3220                         return -ENOMEM;
3221                 *path = fake_paths[i];
3222                 if (!i)
3223                         path->active = 1;
3224                 spec->smux_paths[i] = snd_hda_get_path_idx(codec, path);
3225         }
3226 
3227         if (!snd_hda_gen_add_kctl(&spec->gen, NULL, &ad1988_auto_smux_mixer))
3228                 return -ENOMEM;
3229 
3230         codec->patch_ops.init = ad1988_auto_init;
3231 
3232         return 0;
3233 }
3234 
3235 /*
3236  */
3237 
3238 static int ad1988_parse_auto_config(struct hda_codec *codec)
3239 {
3240         struct ad198x_spec *spec;
3241         int err;
3242 
3243         err = alloc_ad_spec(codec);
3244         if (err < 0)
3245                 return err;
3246         spec = codec->spec;
3247 
3248         spec->gen.mixer_nid = 0x20;
3249         spec->gen.mixer_merge_nid = 0x21;
3250         spec->gen.beep_nid = 0x10;
3251         set_beep_amp(spec, 0x10, 0, HDA_OUTPUT);
3252         err = ad198x_parse_auto_config(codec);
3253         if (err < 0)
3254                 goto error;
3255         err = ad1988_add_spdif_mux_ctl(codec);
3256         if (err < 0)
3257                 goto error;
3258         return 0;
3259 
3260  error:
3261         snd_hda_gen_free(codec);
3262         return err;
3263 }
3264 
3265 /*
3266  */
3267 
3268 #ifdef ENABLE_AD_STATIC_QUIRKS
3269 static const char * const ad1988_models[AD1988_MODEL_LAST] = {
3270         [AD1988_6STACK]         = "6stack",
3271         [AD1988_6STACK_DIG]     = "6stack-dig",
3272         [AD1988_3STACK]         = "3stack",
3273         [AD1988_3STACK_DIG]     = "3stack-dig",
3274         [AD1988_LAPTOP]         = "laptop",
3275         [AD1988_LAPTOP_DIG]     = "laptop-dig",
3276         [AD1988_AUTO]           = "auto",
3277 };
3278 
3279 static const struct snd_pci_quirk ad1988_cfg_tbl[] = {
3280         SND_PCI_QUIRK(0x1043, 0x81ec, "Asus P5B-DLX", AD1988_6STACK_DIG),
3281         SND_PCI_QUIRK(0x1043, 0x81f6, "Asus M2N-SLI", AD1988_6STACK_DIG),
3282         SND_PCI_QUIRK(0x1043, 0x8277, "Asus P5K-E/WIFI-AP", AD1988_6STACK_DIG),
3283         SND_PCI_QUIRK(0x1043, 0x82c0, "Asus M3N-HT Deluxe", AD1988_6STACK_DIG),
3284         SND_PCI_QUIRK(0x1043, 0x8311, "Asus P5Q-Premium/Pro", AD1988_6STACK_DIG),
3285         {}
3286 };
3287 
3288 static int patch_ad1988(struct hda_codec *codec)
3289 {
3290         struct ad198x_spec *spec;
3291         int err, board_config;
3292 
3293         board_config = snd_hda_check_board_config(codec, AD1988_MODEL_LAST,
3294                                                   ad1988_models, ad1988_cfg_tbl);
3295         if (board_config < 0) {
3296                 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
3297                        codec->chip_name);
3298                 board_config = AD1988_AUTO;
3299         }
3300 
3301         if (board_config == AD1988_AUTO)
3302                 return ad1988_parse_auto_config(codec);
3303 
3304         err = alloc_ad_spec(codec);
3305         if (err < 0)
3306                 return err;
3307         spec = codec->spec;
3308 
3309         if (is_rev2(codec))
3310                 snd_printk(KERN_INFO "patch_analog: AD1988A rev.2 is detected, enable workarounds\n");
3311 
3312         err = snd_hda_attach_beep_device(codec, 0x10);
3313         if (err < 0) {
3314                 ad198x_free(codec);
3315                 return err;
3316         }
3317         set_beep_amp(spec, 0x10, 0, HDA_OUTPUT);
3318 
3319         if (!spec->multiout.hp_nid)
3320                 spec->multiout.hp_nid = ad1988_alt_dac_nid[0];
3321         switch (board_config) {
3322         case AD1988_6STACK:
3323         case AD1988_6STACK_DIG:
3324                 spec->multiout.max_channels = 8;
3325                 spec->multiout.num_dacs = 4;
3326                 if (is_rev2(codec))
3327                         spec->multiout.dac_nids = ad1988_6stack_dac_nids_rev2;
3328                 else
3329                         spec->multiout.dac_nids = ad1988_6stack_dac_nids;
3330                 spec->input_mux = &ad1988_6stack_capture_source;
3331                 spec->num_mixers = 2;
3332                 if (is_rev2(codec))
3333                         spec->mixers[0] = ad1988_6stack_mixers1_rev2;
3334                 else
3335                         spec->mixers[0] = ad1988_6stack_mixers1;
3336                 spec->mixers[1] = ad1988_6stack_mixers2;
3337                 spec->num_init_verbs = 1;
3338                 spec->init_verbs[0] = ad1988_6stack_init_verbs;
3339                 if (board_config == AD1988_6STACK_DIG) {
3340                         spec->multiout.dig_out_nid = AD1988_SPDIF_OUT;
3341                         spec->dig_in_nid = AD1988_SPDIF_IN;
3342                 }
3343                 break;
3344         case AD1988_3STACK:
3345         case AD1988_3STACK_DIG:
3346                 spec->multiout.max_channels = 6;
3347                 spec->multiout.num_dacs = 3;
3348                 if (is_rev2(codec))
3349                         spec->multiout.dac_nids = ad1988_3stack_dac_nids_rev2;
3350                 else
3351                         spec->multiout.dac_nids = ad1988_3stack_dac_nids;
3352                 spec->input_mux = &ad1988_6stack_capture_source;
3353                 spec->channel_mode = ad1988_3stack_modes;
3354                 spec->num_channel_mode = ARRAY_SIZE(ad1988_3stack_modes);
3355                 spec->num_mixers = 2;
3356                 if (is_rev2(codec))
3357                         spec->mixers[0] = ad1988_3stack_mixers1_rev2;
3358                 else
3359                         spec->mixers[0] = ad1988_3stack_mixers1;
3360                 spec->mixers[1] = ad1988_3stack_mixers2;
3361                 spec->num_init_verbs = 1;
3362                 spec->init_verbs[0] = ad1988_3stack_init_verbs;
3363                 if (board_config == AD1988_3STACK_DIG)
3364                         spec->multiout.dig_out_nid = AD1988_SPDIF_OUT;
3365                 break;
3366         case AD1988_LAPTOP:
3367         case AD1988_LAPTOP_DIG:
3368                 spec->multiout.max_channels = 2;
3369                 spec->multiout.num_dacs = 1;
3370                 spec->multiout.dac_nids = ad1988_3stack_dac_nids;
3371                 spec->input_mux = &ad1988_laptop_capture_source;
3372                 spec->num_mixers = 1;
3373                 spec->mixers[0] = ad1988_laptop_mixers;
3374                 codec->inv_eapd = 1; /* inverted EAPD */
3375                 spec->num_init_verbs = 1;
3376                 spec->init_verbs[0] = ad1988_laptop_init_verbs;
3377                 if (board_config == AD1988_LAPTOP_DIG)
3378                         spec->multiout.dig_out_nid = AD1988_SPDIF_OUT;
3379                 break;
3380         }
3381 
3382         spec->num_adc_nids = ARRAY_SIZE(ad1988_adc_nids);
3383         spec->adc_nids = ad1988_adc_nids;
3384         spec->capsrc_nids = ad1988_capsrc_nids;
3385         spec->mixers[spec->num_mixers++] = ad1988_capture_mixers;
3386         spec->init_verbs[spec->num_init_verbs++] = ad1988_capture_init_verbs;
3387         if (spec->multiout.dig_out_nid) {
3388                 if (codec->vendor_id >= 0x11d4989a) {
3389                         spec->mixers[spec->num_mixers++] =
3390                                 ad1989_spdif_out_mixers;
3391                         spec->init_verbs[spec->num_init_verbs++] =
3392                                 ad1989_spdif_init_verbs;
3393                         codec->slave_dig_outs = ad1989b_slave_dig_outs;
3394                 } else {
3395                         spec->mixers[spec->num_mixers++] =
3396                                 ad1988_spdif_out_mixers;
3397                         spec->init_verbs[spec->num_init_verbs++] =
3398                                 ad1988_spdif_init_verbs;
3399                 }
3400         }
3401         if (spec->dig_in_nid && codec->vendor_id < 0x11d4989a) {
3402                 spec->mixers[spec->num_mixers++] = ad1988_spdif_in_mixers;
3403                 spec->init_verbs[spec->num_init_verbs++] =
3404                         ad1988_spdif_in_init_verbs;
3405         }
3406 
3407         codec->patch_ops = ad198x_patch_ops;
3408         switch (board_config) {
3409         case AD1988_LAPTOP:
3410         case AD1988_LAPTOP_DIG:
3411                 codec->patch_ops.unsol_event = ad1988_laptop_unsol_event;
3412                 break;
3413         }
3414 #ifdef CONFIG_PM
3415         spec->loopback.amplist = ad1988_loopbacks;
3416 #endif
3417         spec->vmaster_nid = 0x04;
3418 
3419         codec->no_trigger_sense = 1;
3420         codec->no_sticky_stream = 1;
3421 
3422         return 0;
3423 }
3424 #else /* ENABLE_AD_STATIC_QUIRKS */
3425 #define patch_ad1988    ad1988_parse_auto_config
3426 #endif /* ENABLE_AD_STATIC_QUIRKS */
3427 
3428 
3429 /*
3430  * AD1884 / AD1984
3431  *
3432  * port-B - front line/mic-in
3433  * port-E - aux in/out
3434  * port-F - aux in/out
3435  * port-C - rear line/mic-in
3436  * port-D - rear line/hp-out
3437  * port-A - front line/hp-out
3438  *
3439  * AD1984 = AD1884 + two digital mic-ins
3440  *
3441  * FIXME:
3442  * For simplicity, we share the single DAC for both HP and line-outs
3443  * right now.  The inidividual playbacks could be easily implemented,
3444  * but no build-up framework is given, so far.
3445  */
3446 
3447 #ifdef ENABLE_AD_STATIC_QUIRKS
3448 static const hda_nid_t ad1884_dac_nids[1] = {
3449         0x04,
3450 };
3451 
3452 static const hda_nid_t ad1884_adc_nids[2] = {
3453         0x08, 0x09,
3454 };
3455 
3456 static const hda_nid_t ad1884_capsrc_nids[2] = {
3457         0x0c, 0x0d,
3458 };
3459 
3460 #define AD1884_SPDIF_OUT        0x02
3461 
3462 static const struct hda_input_mux ad1884_capture_source = {
3463         .num_items = 4,
3464         .items = {
3465                 { "Front Mic", 0x0 },
3466                 { "Mic", 0x1 },
3467                 { "CD", 0x2 },
3468                 { "Mix", 0x3 },
3469         },
3470 };
3471 
3472 static const struct snd_kcontrol_new ad1884_base_mixers[] = {
3473         HDA_CODEC_VOLUME("PCM Playback Volume", 0x04, 0x0, HDA_OUTPUT),
3474         /* HDA_CODEC_VOLUME_IDX("PCM Playback Volume", 1, 0x03, 0x0, HDA_OUTPUT), */
3475         HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT),
3476         HDA_CODEC_MUTE("Front Playback Switch", 0x12, 0x0, HDA_OUTPUT),
3477         HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x13, 1, 0x0, HDA_OUTPUT),
3478         HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x13, 1, 0x0, HDA_OUTPUT),
3479         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
3480         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
3481         HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x01, HDA_INPUT),
3482         HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x01, HDA_INPUT),
3483         HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x02, HDA_INPUT),
3484         HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x02, HDA_INPUT),
3485         HDA_CODEC_VOLUME("Mic Boost Volume", 0x15, 0x0, HDA_INPUT),
3486         HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x14, 0x0, HDA_INPUT),
3487         HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
3488         HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
3489         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT),
3490         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x0d, 0x0, HDA_OUTPUT),
3491         {
3492                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3493                 /* The multiple "Capture Source" controls confuse alsamixer
3494                  * So call somewhat different..
3495                  */
3496                 /* .name = "Capture Source", */
3497                 .name = "Input Source",
3498                 .count = 2,
3499                 .info = ad198x_mux_enum_info,
3500                 .get = ad198x_mux_enum_get,
3501                 .put = ad198x_mux_enum_put,
3502         },
3503         /* SPDIF controls */
3504         HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
3505         {
3506                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3507                 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
3508                 /* identical with ad1983 */
3509                 .info = ad1983_spdif_route_info,
3510                 .get = ad1983_spdif_route_get,
3511                 .put = ad1983_spdif_route_put,
3512         },
3513         { } /* end */
3514 };
3515 
3516 static const struct snd_kcontrol_new ad1984_dmic_mixers[] = {
3517         HDA_CODEC_VOLUME("Digital Mic Capture Volume", 0x05, 0x0, HDA_INPUT),
3518         HDA_CODEC_MUTE("Digital Mic Capture Switch", 0x05, 0x0, HDA_INPUT),
3519         HDA_CODEC_VOLUME_IDX("Digital Mic Capture Volume", 1, 0x06, 0x0,
3520                              HDA_INPUT),
3521         HDA_CODEC_MUTE_IDX("Digital Mic Capture Switch", 1, 0x06, 0x0,
3522                            HDA_INPUT),
3523         { } /* end */
3524 };
3525 
3526 /*
3527  * initialization verbs
3528  */
3529 static const struct hda_verb ad1884_init_verbs[] = {
3530         /* DACs; mute as default */
3531         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3532         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3533         /* Port-A (HP) mixer */
3534         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3535         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3536         /* Port-A pin */
3537         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3538         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3539         /* HP selector - select DAC2 */
3540         {0x22, AC_VERB_SET_CONNECT_SEL, 0x1},
3541         /* Port-D (Line-out) mixer */
3542         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3543         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3544         /* Port-D pin */
3545         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3546         {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3547         /* Mono-out mixer */
3548         {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3549         {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3550         /* Mono-out pin */
3551         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3552         {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3553         /* Mono selector */
3554         {0x0e, AC_VERB_SET_CONNECT_SEL, 0x1},
3555         /* Port-B (front mic) pin */
3556         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3557         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3558         /* Port-C (rear mic) pin */
3559         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3560         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3561         /* Analog mixer; mute as default */
3562         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3563         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3564         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3565         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3566         /* Analog Mix output amp */
3567         {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x1f}, /* 0dB */
3568         /* SPDIF output selector */
3569         {0x02, AC_VERB_SET_CONNECT_SEL, 0x0}, /* PCM */
3570         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */
3571         { } /* end */
3572 };
3573 
3574 #ifdef CONFIG_PM
3575 static const struct hda_amp_list ad1884_loopbacks[] = {
3576         { 0x20, HDA_INPUT, 0 }, /* Front Mic */
3577         { 0x20, HDA_INPUT, 1 }, /* Mic */
3578         { 0x20, HDA_INPUT, 2 }, /* CD */
3579         { 0x20, HDA_INPUT, 4 }, /* Docking */
3580         { } /* end */
3581 };
3582 #endif
3583 
3584 static const char * const ad1884_slave_vols[] = {
3585         "PCM", "Mic", "Mono", "Front Mic", "Mic", "CD",
3586         "Internal Mic", "Dock Mic", /* "Beep", */ "IEC958",
3587         NULL
3588 };
3589 
3590 enum {
3591         AD1884_AUTO,
3592         AD1884_BASIC,
3593         AD1884_MODELS
3594 };
3595 
3596 static const char * const ad1884_models[AD1884_MODELS] = {
3597         [AD1884_AUTO]           = "auto",
3598         [AD1884_BASIC]          = "basic",
3599 };
3600 #endif /* ENABLE_AD_STATIC_QUIRKS */
3601 
3602 
3603 /* set the upper-limit for mixer amp to 0dB for avoiding the possible
3604  * damage by overloading
3605  */
3606 static void ad1884_fixup_amp_override(struct hda_codec *codec,
3607                                       const struct hda_fixup *fix, int action)
3608 {
3609         if (action == HDA_FIXUP_ACT_PRE_PROBE)
3610                 snd_hda_override_amp_caps(codec, 0x20, HDA_INPUT,
3611                                           (0x17 << AC_AMPCAP_OFFSET_SHIFT) |
3612                                           (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) |
3613                                           (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) |
3614                                           (1 << AC_AMPCAP_MUTE_SHIFT));
3615 }
3616 
3617 static void ad1884_fixup_hp_eapd(struct hda_codec *codec,
3618                                  const struct hda_fixup *fix, int action)
3619 {
3620         struct ad198x_spec *spec = codec->spec;
3621 
3622         switch (action) {
3623         case HDA_FIXUP_ACT_PRE_PROBE:
3624                 spec->gen.vmaster_mute.hook = ad_vmaster_eapd_hook;
3625                 break;
3626         case HDA_FIXUP_ACT_PROBE:
3627                 if (spec->gen.autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT)
3628                         spec->eapd_nid = spec->gen.autocfg.line_out_pins[0];
3629                 else
3630                         spec->eapd_nid = spec->gen.autocfg.speaker_pins[0];
3631                 break;
3632         }
3633 }
3634 
3635 enum {
3636         AD1884_FIXUP_AMP_OVERRIDE,
3637         AD1884_FIXUP_HP_EAPD,
3638 };
3639 
3640 static const struct hda_fixup ad1884_fixups[] = {
3641         [AD1884_FIXUP_AMP_OVERRIDE] = {
3642                 .type = HDA_FIXUP_FUNC,
3643                 .v.func = ad1884_fixup_amp_override,
3644         },
3645         [AD1884_FIXUP_HP_EAPD] = {
3646                 .type = HDA_FIXUP_FUNC,
3647                 .v.func = ad1884_fixup_hp_eapd,
3648                 .chained = true,
3649                 .chain_id = AD1884_FIXUP_AMP_OVERRIDE,
3650         },
3651 };
3652 
3653 static const struct snd_pci_quirk ad1884_fixup_tbl[] = {
3654         SND_PCI_QUIRK_VENDOR(0x103c, "HP", AD1884_FIXUP_HP_EAPD),
3655         {}
3656 };
3657 
3658 
3659 static int ad1884_parse_auto_config(struct hda_codec *codec)
3660 {
3661         struct ad198x_spec *spec;
3662         int err;
3663 
3664         err = alloc_ad_spec(codec);
3665         if (err < 0)
3666                 return err;
3667         spec = codec->spec;
3668 
3669         spec->gen.mixer_nid = 0x20;
3670         spec->gen.mixer_merge_nid = 0x21;
3671         spec->gen.beep_nid = 0x10;
3672         set_beep_amp(spec, 0x10, 0, HDA_OUTPUT);
3673 
3674         snd_hda_pick_fixup(codec, NULL, ad1884_fixup_tbl, ad1884_fixups);
3675         snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
3676 
3677         err = ad198x_parse_auto_config(codec);
3678         if (err < 0)
3679                 goto error;
3680         err = ad1983_add_spdif_mux_ctl(codec);
3681         if (err < 0)
3682                 goto error;
3683 
3684         snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
3685 
3686         return 0;
3687 
3688  error:
3689         snd_hda_gen_free(codec);
3690         return err;
3691 }
3692 
3693 #ifdef ENABLE_AD_STATIC_QUIRKS
3694 static int patch_ad1884_basic(struct hda_codec *codec)
3695 {
3696         struct ad198x_spec *spec;
3697         int err;
3698 
3699         err = alloc_ad_spec(codec);
3700         if (err < 0)
3701                 return err;
3702         spec = codec->spec;
3703 
3704         err = snd_hda_attach_beep_device(codec, 0x10);
3705         if (err < 0) {
3706                 ad198x_free(codec);
3707                 return err;
3708         }
3709         set_beep_amp(spec, 0x10, 0, HDA_OUTPUT);
3710 
3711         spec->multiout.max_channels = 2;
3712         spec->multiout.num_dacs = ARRAY_SIZE(ad1884_dac_nids);
3713         spec->multiout.dac_nids = ad1884_dac_nids;
3714         spec->multiout.dig_out_nid = AD1884_SPDIF_OUT;
3715         spec->num_adc_nids = ARRAY_SIZE(ad1884_adc_nids);
3716         spec->adc_nids = ad1884_adc_nids;
3717         spec->capsrc_nids = ad1884_capsrc_nids;
3718         spec->input_mux = &ad1884_capture_source;
3719         spec->num_mixers = 1;
3720         spec->mixers[0] = ad1884_base_mixers;
3721         spec->num_init_verbs = 1;
3722         spec->init_verbs[0] = ad1884_init_verbs;
3723         spec->spdif_route = 0;
3724 #ifdef CONFIG_PM
3725         spec->loopback.amplist = ad1884_loopbacks;
3726 #endif
3727         spec->vmaster_nid = 0x04;
3728         /* we need to cover all playback volumes */
3729         spec->slave_vols = ad1884_slave_vols;
3730         /* slaves may contain input volumes, so we can't raise to 0dB blindly */
3731         spec->avoid_init_slave_vol = 1;
3732 
3733         codec->patch_ops = ad198x_patch_ops;
3734 
3735         codec->no_trigger_sense = 1;
3736         codec->no_sticky_stream = 1;
3737 
3738         return 0;
3739 }
3740 
3741 static int patch_ad1884(struct hda_codec *codec)
3742 {
3743         int board_config;
3744 
3745         board_config = snd_hda_check_board_config(codec, AD1884_MODELS,
3746                                                   ad1884_models, NULL);
3747         if (board_config < 0) {
3748                 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
3749                        codec->chip_name);
3750                 board_config = AD1884_AUTO;
3751         }
3752 
3753         if (board_config == AD1884_AUTO)
3754                 return ad1884_parse_auto_config(codec);
3755         else
3756                 return patch_ad1884_basic(codec);
3757 }
3758 #else /* ENABLE_AD_STATIC_QUIRKS */
3759 #define patch_ad1884    ad1884_parse_auto_config
3760 #endif /* ENABLE_AD_STATIC_QUIRKS */
3761 
3762 
3763 #ifdef ENABLE_AD_STATIC_QUIRKS
3764 /*
3765  * Lenovo Thinkpad T61/X61
3766  */
3767 static const struct hda_input_mux ad1984_thinkpad_capture_source = {
3768         .num_items = 4,
3769         .items = {
3770                 { "Mic", 0x0 },
3771                 { "Internal Mic", 0x1 },
3772                 { "Mix", 0x3 },
3773                 { "Dock Mic", 0x4 },
3774         },
3775 };
3776 
3777 
3778 /*
3779  * Dell Precision T3400
3780  */
3781 static const struct hda_input_mux ad1984_dell_desktop_capture_source = {
3782         .num_items = 3,
3783         .items = {
3784                 { "Front Mic", 0x0 },
3785                 { "Line-In", 0x1 },
3786                 { "Mix", 0x3 },
3787         },
3788 };
3789 
3790 
3791 static const struct snd_kcontrol_new ad1984_thinkpad_mixers[] = {
3792         HDA_CODEC_VOLUME("PCM Playback Volume", 0x04, 0x0, HDA_OUTPUT),
3793         /* HDA_CODEC_VOLUME_IDX("PCM Playback Volume", 1, 0x03, 0x0, HDA_OUTPUT), */
3794         HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT),
3795         HDA_CODEC_MUTE("Speaker Playback Switch", 0x12, 0x0, HDA_OUTPUT),
3796         HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
3797         HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
3798         HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x20, 0x01, HDA_INPUT),
3799         HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x20, 0x01, HDA_INPUT),
3800         HDA_CODEC_VOLUME("Beep Playback Volume", 0x20, 0x03, HDA_INPUT),
3801         HDA_CODEC_MUTE("Beep Playback Switch", 0x20, 0x03, HDA_INPUT),
3802         HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x20, 0x04, HDA_INPUT),
3803         HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x20, 0x04, HDA_INPUT),
3804         HDA_CODEC_VOLUME("Mic Boost Volume", 0x14, 0x0, HDA_INPUT),
3805         HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x15, 0x0, HDA_INPUT),
3806         HDA_CODEC_VOLUME("Dock Mic Boost Volume", 0x25, 0x0, HDA_OUTPUT),
3807         HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
3808         HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
3809         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT),
3810         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x0d, 0x0, HDA_OUTPUT),
3811         {
3812                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3813                 /* The multiple "Capture Source" controls confuse alsamixer
3814                  * So call somewhat different..
3815                  */
3816                 /* .name = "Capture Source", */
3817                 .name = "Input Source",
3818                 .count = 2,
3819                 .info = ad198x_mux_enum_info,
3820                 .get = ad198x_mux_enum_get,
3821                 .put = ad198x_mux_enum_put,
3822         },
3823         /* SPDIF controls */
3824         HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
3825         {
3826                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3827                 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
3828                 /* identical with ad1983 */
3829                 .info = ad1983_spdif_route_info,
3830                 .get = ad1983_spdif_route_get,
3831                 .put = ad1983_spdif_route_put,
3832         },
3833         { } /* end */
3834 };
3835 
3836 /* additional verbs */
3837 static const struct hda_verb ad1984_thinkpad_init_verbs[] = {
3838         /* Port-E (docking station mic) pin */
3839         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3840         {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3841         /* docking mic boost */
3842         {0x25, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3843         /* Analog PC Beeper - allow firmware/ACPI beeps */
3844         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3) | 0x1a},
3845         /* Analog mixer - docking mic; mute as default */
3846         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3847         /* enable EAPD bit */
3848         {0x12, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
3849         { } /* end */
3850 };
3851 
3852 /*
3853  * Dell Precision T3400
3854  */
3855 static const struct snd_kcontrol_new ad1984_dell_desktop_mixers[] = {
3856         HDA_CODEC_VOLUME("PCM Playback Volume", 0x04, 0x0, HDA_OUTPUT),
3857         HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT),
3858         HDA_CODEC_MUTE("Speaker Playback Switch", 0x12, 0x0, HDA_OUTPUT),
3859         HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x13, 1, 0x0, HDA_OUTPUT),
3860         HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x13, 1, 0x0, HDA_OUTPUT),
3861         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
3862         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
3863         HDA_CODEC_VOLUME("Line-In Playback Volume", 0x20, 0x01, HDA_INPUT),
3864         HDA_CODEC_MUTE("Line-In Playback Switch", 0x20, 0x01, HDA_INPUT),
3865         HDA_CODEC_VOLUME("Line-In Boost Volume", 0x15, 0x0, HDA_INPUT),
3866         HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x14, 0x0, HDA_INPUT),
3867         HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
3868         HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
3869         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT),
3870         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x0d, 0x0, HDA_OUTPUT),
3871         {
3872                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3873                 /* The multiple "Capture Source" controls confuse alsamixer
3874                  * So call somewhat different..
3875                  */
3876                 /* .name = "Capture Source", */
3877                 .name = "Input Source",
3878                 .count = 2,
3879                 .info = ad198x_mux_enum_info,
3880                 .get = ad198x_mux_enum_get,
3881                 .put = ad198x_mux_enum_put,
3882         },
3883         { } /* end */
3884 };
3885 
3886 /* Digial MIC ADC NID 0x05 + 0x06 */
3887 static int ad1984_pcm_dmic_prepare(struct hda_pcm_stream *hinfo,
3888                                    struct hda_codec *codec,
3889                                    unsigned int stream_tag,
3890                                    unsigned int format,
3891                                    struct snd_pcm_substream *substream)
3892 {
3893         snd_hda_codec_setup_stream(codec, 0x05 + substream->number,
3894                                    stream_tag, 0, format);
3895         return 0;
3896 }
3897 
3898 static int ad1984_pcm_dmic_cleanup(struct hda_pcm_stream *hinfo,
3899                                    struct hda_codec *codec,
3900                                    struct snd_pcm_substream *substream)
3901 {
3902         snd_hda_codec_cleanup_stream(codec, 0x05 + substream->number);
3903         return 0;
3904 }
3905 
3906 static const struct hda_pcm_stream ad1984_pcm_dmic_capture = {
3907         .substreams = 2,
3908         .channels_min = 2,
3909         .channels_max = 2,
3910         .nid = 0x05,
3911         .ops = {
3912                 .prepare = ad1984_pcm_dmic_prepare,
3913                 .cleanup = ad1984_pcm_dmic_cleanup
3914         },
3915 };
3916 
3917 static int ad1984_build_pcms(struct hda_codec *codec)
3918 {
3919         struct ad198x_spec *spec = codec->spec;
3920         struct hda_pcm *info;
3921         int err;
3922 
3923         err = ad198x_build_pcms(codec);
3924         if (err < 0)
3925                 return err;
3926 
3927         info = spec->pcm_rec + codec->num_pcms;
3928         codec->num_pcms++;
3929         info->name = "AD1984 Digital Mic";
3930         info->stream[SNDRV_PCM_STREAM_CAPTURE] = ad1984_pcm_dmic_capture;
3931         return 0;
3932 }
3933 
3934 /* models */
3935 enum {
3936         AD1984_AUTO,
3937         AD1984_BASIC,
3938         AD1984_THINKPAD,
3939         AD1984_DELL_DESKTOP,
3940         AD1984_MODELS
3941 };
3942 
3943 static const char * const ad1984_models[AD1984_MODELS] = {
3944         [AD1984_AUTO]           = "auto",
3945         [AD1984_BASIC]          = "basic",
3946         [AD1984_THINKPAD]       = "thinkpad",
3947         [AD1984_DELL_DESKTOP]   = "dell_desktop",
3948 };
3949 
3950 static const struct snd_pci_quirk ad1984_cfg_tbl[] = {
3951         /* Lenovo Thinkpad T61/X61 */
3952         SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo Thinkpad", AD1984_THINKPAD),
3953         SND_PCI_QUIRK(0x1028, 0x0214, "Dell T3400", AD1984_DELL_DESKTOP),
3954         SND_PCI_QUIRK(0x1028, 0x0233, "Dell Latitude E6400", AD1984_DELL_DESKTOP),
3955         {}
3956 };
3957 
3958 static int patch_ad1984(struct hda_codec *codec)
3959 {
3960         struct ad198x_spec *spec;
3961         int board_config, err;
3962 
3963         board_config = snd_hda_check_board_config(codec, AD1984_MODELS,
3964                                                   ad1984_models, ad1984_cfg_tbl);
3965         if (board_config < 0) {
3966                 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
3967                        codec->chip_name);
3968                 board_config = AD1984_AUTO;
3969         }
3970 
3971         if (board_config == AD1984_AUTO)
3972                 return ad1884_parse_auto_config(codec);
3973 
3974         err = patch_ad1884_basic(codec);
3975         if (err < 0)
3976                 return err;
3977         spec = codec->spec;
3978 
3979         switch (board_config) {
3980         case AD1984_BASIC:
3981                 /* additional digital mics */
3982                 spec->mixers[spec->num_mixers++] = ad1984_dmic_mixers;
3983                 codec->patch_ops.build_pcms = ad1984_build_pcms;
3984                 break;
3985         case AD1984_THINKPAD:
3986                 if (codec->subsystem_id == 0x17aa20fb) {
3987                         /* Thinpad X300 does not have the ability to do SPDIF,
3988                            or attach to docking station to use SPDIF */
3989                         spec->multiout.dig_out_nid = 0;
3990                 } else
3991                         spec->multiout.dig_out_nid = AD1884_SPDIF_OUT;
3992                 spec->input_mux = &ad1984_thinkpad_capture_source;
3993                 spec->mixers[0] = ad1984_thinkpad_mixers;
3994                 spec->init_verbs[spec->num_init_verbs++] = ad1984_thinkpad_init_verbs;
3995                 spec->analog_beep = 1;
3996                 break;
3997         case AD1984_DELL_DESKTOP:
3998                 spec->multiout.dig_out_nid = 0;
3999                 spec->input_mux = &ad1984_dell_desktop_capture_source;
4000                 spec->mixers[0] = ad1984_dell_desktop_mixers;
4001                 break;
4002         }
4003         return 0;
4004 }
4005 #else /* ENABLE_AD_STATIC_QUIRKS */
4006 #define patch_ad1984    ad1884_parse_auto_config
4007 #endif /* ENABLE_AD_STATIC_QUIRKS */
4008 
4009 
4010 /*
4011  * AD1883 / AD1884A / AD1984A / AD1984B
4012  *
4013  * port-B (0x14) - front mic-in
4014  * port-E (0x1c) - rear mic-in
4015  * port-F (0x16) - CD / ext out
4016  * port-C (0x15) - rear line-in
4017  * port-D (0x12) - rear line-out
4018  * port-A (0x11) - front hp-out
4019  *
4020  * AD1984A = AD1884A + digital-mic
4021  * AD1883 = equivalent with AD1984A
4022  * AD1984B = AD1984A + extra SPDIF-out
4023  *
4024  * FIXME:
4025  * We share the single DAC for both HP and line-outs (see AD1884/1984).
4026  */
4027 
4028 #ifdef ENABLE_AD_STATIC_QUIRKS
4029 static const hda_nid_t ad1884a_dac_nids[1] = {
4030         0x03,
4031 };
4032 
4033 #define ad1884a_adc_nids        ad1884_adc_nids
4034 #define ad1884a_capsrc_nids     ad1884_capsrc_nids
4035 
4036 #define AD1884A_SPDIF_OUT       0x02
4037 
4038 static const struct hda_input_mux ad1884a_capture_source = {
4039         .num_items = 5,
4040         .items = {
4041                 { "Front Mic", 0x0 },
4042                 { "Mic", 0x4 },
4043                 { "Line", 0x1 },
4044                 { "CD", 0x2 },
4045                 { "Mix", 0x3 },
4046         },
4047 };
4048 
4049 static const struct snd_kcontrol_new ad1884a_base_mixers[] = {
4050         HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT),
4051         HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT),
4052         HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT),
4053         HDA_CODEC_MUTE("Front Playback Switch", 0x12, 0x0, HDA_OUTPUT),
4054         HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x13, 1, 0x0, HDA_OUTPUT),
4055         HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x13, 1, 0x0, HDA_OUTPUT),
4056         HDA_CODEC_VOLUME("PCM Playback Volume", 0x20, 0x5, HDA_INPUT),
4057         HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT),
4058         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
4059         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
4060         HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x01, HDA_INPUT),
4061         HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x01, HDA_INPUT),
4062         HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x04, HDA_INPUT),
4063         HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x04, HDA_INPUT),
4064         HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x02, HDA_INPUT),
4065         HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x02, HDA_INPUT),
4066         HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x14, 0x0, HDA_INPUT),
4067         HDA_CODEC_VOLUME("Line Boost Volume", 0x15, 0x0, HDA_INPUT),
4068         HDA_CODEC_VOLUME("Mic Boost Volume", 0x25, 0x0, HDA_OUTPUT),
4069         HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
4070         HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
4071         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT),
4072         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x0d, 0x0, HDA_OUTPUT),
4073         {
4074                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4075                 /* The multiple "Capture Source" controls confuse alsamixer
4076                  * So call somewhat different..
4077                  */
4078                 /* .name = "Capture Source", */
4079                 .name = "Input Source",
4080                 .count = 2,
4081                 .info = ad198x_mux_enum_info,
4082                 .get = ad198x_mux_enum_get,
4083                 .put = ad198x_mux_enum_put,
4084         },
4085         /* SPDIF controls */
4086         HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
4087         {
4088                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4089                 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
4090                 /* identical with ad1983 */
4091                 .info = ad1983_spdif_route_info,
4092                 .get = ad1983_spdif_route_get,
4093                 .put = ad1983_spdif_route_put,
4094         },
4095         { } /* end */
4096 };
4097 
4098 /*
4099  * initialization verbs
4100  */
4101 static const struct hda_verb ad1884a_init_verbs[] = {
4102         /* DACs; unmute as default */
4103         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */
4104         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */
4105         /* Port-A (HP) mixer - route only from analog mixer */
4106         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4107         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4108         /* Port-A pin */
4109         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4110         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4111         /* Port-D (Line-out) mixer - route only from analog mixer */
4112         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4113         {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4114         /* Port-D pin */
4115         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4116         {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4117         /* Mono-out mixer - route only from analog mixer */
4118         {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4119         {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4120         /* Mono-out pin */
4121         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4122         {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4123         /* Port-B (front mic) pin */
4124         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4125         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4126         /* Port-C (rear line-in) pin */
4127         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4128         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4129         /* Port-E (rear mic) pin */
4130         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4131         {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4132         {0x25, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, /* no boost */
4133         /* Port-F (CD) pin */
4134         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4135         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4136         /* Analog mixer; mute as default */
4137         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4138         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4139         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4140         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4141         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, /* aux */
4142         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
4143         /* Analog Mix output amp */
4144         {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4145         /* capture sources */
4146         {0x0c, AC_VERB_SET_CONNECT_SEL, 0x0},
4147         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4148         {0x0d, AC_VERB_SET_CONNECT_SEL, 0x0},
4149         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4150         /* SPDIF output amp */
4151         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */
4152         { } /* end */
4153 };
4154 
4155 #ifdef CONFIG_PM
4156 static const struct hda_amp_list ad1884a_loopbacks[] = {
4157         { 0x20, HDA_INPUT, 0 }, /* Front Mic */
4158         { 0x20, HDA_INPUT, 1 }, /* Mic */
4159         { 0x20, HDA_INPUT, 2 }, /* CD */
4160         { 0x20, HDA_INPUT, 4 }, /* Docking */
4161         { } /* end */
4162 };
4163 #endif
4164 
4165 /*
4166  * Laptop model
4167  *
4168  * Port A: Headphone jack
4169  * Port B: MIC jack
4170  * Port C: Internal MIC
4171  * Port D: Dock Line Out (if enabled)
4172  * Port E: Dock Line In (if enabled)
4173  * Port F: Internal speakers
4174  */
4175 
4176 static int ad1884a_mobile_master_sw_put(struct snd_kcontrol *kcontrol,
4177                                         struct snd_ctl_elem_value *ucontrol)
4178 {
4179         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4180         int ret = snd_hda_mixer_amp_switch_put(kcontrol, ucontrol);
4181         int mute = (!ucontrol->value.integer.value[0] &&
4182                     !ucontrol->value.integer.value[1]);
4183         /* toggle GPIO1 according to the mute state */
4184         snd_hda_codec_write_cache(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA,
4185                             mute ? 0x02 : 0x0);
4186         return ret;
4187 }
4188 
4189 static const struct snd_kcontrol_new ad1884a_laptop_mixers[] = {
4190         HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT),
4191         {
4192                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4193                 .name = "Master Playback Switch",
4194                 .subdevice = HDA_SUBDEV_AMP_FLAG,
4195                 .info = snd_hda_mixer_amp_switch_info,
4196                 .get = snd_hda_mixer_amp_switch_get,
4197                 .put = ad1884a_mobile_master_sw_put,
4198                 .private_value = HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
4199         },
4200         HDA_CODEC_MUTE("Dock Playback Switch", 0x12, 0x0, HDA_OUTPUT),
4201         HDA_CODEC_VOLUME("PCM Playback Volume", 0x20, 0x5, HDA_INPUT),
4202         HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT),
4203         HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
4204         HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
4205         HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x20, 0x01, HDA_INPUT),
4206         HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x20, 0x01, HDA_INPUT),
4207         HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x20, 0x04, HDA_INPUT),
4208         HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x20, 0x04, HDA_INPUT),
4209         HDA_CODEC_VOLUME("Mic Boost Volume", 0x14, 0x0, HDA_INPUT),
4210         HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x15, 0x0, HDA_INPUT),
4211         HDA_CODEC_VOLUME("Dock Mic Boost Volume", 0x25, 0x0, HDA_OUTPUT),
4212         HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
4213         HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
4214         { } /* end */
4215 };
4216 
4217 static const struct snd_kcontrol_new ad1884a_mobile_mixers[] = {
4218         HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT),
4219         /*HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT),*/
4220         {
4221                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4222                 .name = "Master Playback Switch",
4223                 .subdevice = HDA_SUBDEV_AMP_FLAG,
4224                 .info = snd_hda_mixer_amp_switch_info,
4225                 .get = snd_hda_mixer_amp_switch_get,
4226                 .put = ad1884a_mobile_master_sw_put,
4227                 .private_value = HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
4228         },
4229         HDA_CODEC_VOLUME("PCM Playback Volume", 0x20, 0x5, HDA_INPUT),
4230         HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT),
4231         HDA_CODEC_VOLUME("Mic Capture Volume", 0x14, 0x0, HDA_INPUT),
4232         HDA_CODEC_VOLUME("Internal Mic Capture Volume", 0x15, 0x0, HDA_INPUT),
4233         HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
4234         HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
4235         { } /* end */
4236 };
4237 
4238 /* mute internal speaker if HP is plugged */
4239 static void ad1884a_hp_automute(struct hda_codec *codec)
4240 {
4241         unsigned int present;
4242 
4243         present = snd_hda_jack_detect(codec, 0x11);
4244         snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
4245                                  HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
4246         snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_EAPD_BTLENABLE,
4247                             present ? 0x00 : 0x02);
4248 }
4249 
4250 /* switch to external mic if plugged */
4251 static void ad1884a_hp_automic(struct hda_codec *codec)
4252 {
4253         unsigned int present;
4254 
4255         present = snd_hda_jack_detect(codec, 0x14);
4256         snd_hda_codec_write(codec, 0x0c, 0, AC_VERB_SET_CONNECT_SEL,
4257                             present ? 0 : 1);
4258 }
4259 
4260 #define AD1884A_HP_EVENT                0x37
4261 #define AD1884A_MIC_EVENT               0x36
4262 
4263 /* unsolicited event for HP jack sensing */
4264 static void ad1884a_hp_unsol_event(struct hda_codec *codec, unsigned int res)
4265 {
4266         switch (res >> 26) {
4267         case AD1884A_HP_EVENT:
4268                 ad1884a_hp_automute(codec);
4269                 break;
4270         case AD1884A_MIC_EVENT:
4271                 ad1884a_hp_automic(codec);
4272                 break;
4273         }
4274 }
4275 
4276 /* initialize jack-sensing, too */
4277 static int ad1884a_hp_init(struct hda_codec *codec)
4278 {
4279         ad198x_init(codec);
4280         ad1884a_hp_automute(codec);
4281         ad1884a_hp_automic(codec);
4282         return 0;
4283 }
4284 
4285 /* mute internal speaker if HP or docking HP is plugged */
4286 static void ad1884a_laptop_automute(struct hda_codec *codec)
4287 {
4288         unsigned int present;
4289 
4290         present = snd_hda_jack_detect(codec, 0x11);
4291         if (!present)
4292                 present = snd_hda_jack_detect(codec, 0x12);
4293         snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
4294                                  HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
4295         snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_EAPD_BTLENABLE,
4296                             present ? 0x00 : 0x02);
4297 }
4298 
4299 /* switch to external mic if plugged */
4300 static void ad1884a_laptop_automic(struct hda_codec *codec)
4301 {
4302         unsigned int idx;
4303 
4304         if (snd_hda_jack_detect(codec, 0x14))
4305                 idx = 0;
4306         else if (snd_hda_jack_detect(codec, 0x1c))
4307                 idx = 4;
4308         else
4309                 idx = 1;
4310         snd_hda_codec_write(codec, 0x0c, 0, AC_VERB_SET_CONNECT_SEL, idx);
4311 }
4312 
4313 /* unsolicited event for HP jack sensing */
4314 static void ad1884a_laptop_unsol_event(struct hda_codec *codec,
4315                                        unsigned int res)
4316 {
4317         switch (res >> 26) {
4318         case AD1884A_HP_EVENT:
4319                 ad1884a_laptop_automute(codec);
4320                 break;
4321         case AD1884A_MIC_EVENT:
4322                 ad1884a_laptop_automic(codec);
4323                 break;
4324         }
4325 }
4326 
4327 /* initialize jack-sensing, too */
4328 static int ad1884a_laptop_init(struct hda_codec *codec)
4329 {
4330         ad198x_init(codec);
4331         ad1884a_laptop_automute(codec);
4332         ad1884a_laptop_automic(codec);
4333         return 0;
4334 }
4335 
4336 /* additional verbs for laptop model */
4337 static const struct hda_verb ad1884a_laptop_verbs[] = {
4338         /* Port-A (HP) pin - always unmuted */
4339         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4340         /* Port-F (int speaker) mixer - route only from analog mixer */
4341         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4342         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4343         /* Port-F (int speaker) pin */
4344         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4345         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4346         /* required for compaq 6530s/6531s speaker output */
4347         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4348         /* Port-C pin - internal mic-in */
4349         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4350         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7002}, /* raise mic as default */
4351         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x7002}, /* raise mic as default */
4352         /* Port-D (docking line-out) pin - default unmuted */
4353         {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4354         /* analog mix */
4355         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4356         /* unsolicited event for pin-sense */
4357         {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_HP_EVENT},
4358         {0x12, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_HP_EVENT},
4359         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_MIC_EVENT},
4360         {0x1c, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_MIC_EVENT},
4361         /* allow to touch GPIO1 (for mute control) */
4362         {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
4363         {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
4364         {0x01, AC_VERB_SET_GPIO_DATA, 0x02}, /* first muted */
4365         { } /* end */
4366 };
4367 
4368 static const struct hda_verb ad1884a_mobile_verbs[] = {
4369         /* DACs; unmute as default */
4370         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */
4371         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */
4372         /* Port-A (HP) mixer - route only from analog mixer */
4373         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4374         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4375         /* Port-A pin */
4376         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4377         /* Port-A (HP) pin - always unmuted */
4378         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4379         /* Port-B (mic jack) pin */
4380         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4381         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7002}, /* raise mic as default */
4382         /* Port-C (int mic) pin */
4383         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4384         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x7002}, /* raise mic as default */
4385         /* Port-F (int speaker) mixer - route only from analog mixer */
4386         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4387         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4388         /* Port-F pin */
4389         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4390         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4391         /* Analog mixer; mute as default */
4392         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4393         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4394         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4395         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4396         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4397         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
4398         /* Analog Mix output amp */
4399         {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4400         /* capture sources */
4401         /* {0x0c, AC_VERB_SET_CONNECT_SEL, 0x0}, */ /* set via unsol */
4402         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4403         {0x0d, AC_VERB_SET_CONNECT_SEL, 0x0},
4404         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4405         /* unsolicited event for pin-sense */
4406         {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_HP_EVENT},
4407         {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_MIC_EVENT},
4408         /* allow to touch GPIO1 (for mute control) */
4409         {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
4410         {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
4411         {0x01, AC_VERB_SET_GPIO_DATA, 0x02}, /* first muted */
4412         { } /* end */
4413 };
4414 
4415 /*
4416  * Thinkpad X300
4417  * 0x11 - HP
4418  * 0x12 - speaker
4419  * 0x14 - mic-in
4420  * 0x17 - built-in mic
4421  */
4422 
4423 static const struct hda_verb ad1984a_thinkpad_verbs[] = {
4424         /* HP unmute */
4425         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4426         /* analog mix */
4427         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4428         /* turn on EAPD */
4429         {0x12, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
4430         /* unsolicited event for pin-sense */
4431         {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_HP_EVENT},
4432         /* internal mic - dmic */
4433         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4434         /* set magic COEFs for dmic */
4435         {0x01, AC_VERB_SET_COEF_INDEX, 0x13f7},
4436         {0x01, AC_VERB_SET_PROC_COEF, 0x08},
4437         { } /* end */
4438 };
4439 
4440 static const struct snd_kcontrol_new ad1984a_thinkpad_mixers[] = {
4441         HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT),
4442         HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT),
4443         HDA_CODEC_VOLUME("PCM Playback Volume", 0x20, 0x5, HDA_INPUT),
4444         HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT),
4445         HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
4446         HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
4447         HDA_CODEC_VOLUME("Mic Boost Volume", 0x14, 0x0, HDA_INPUT),
4448         HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x17, 0x0, HDA_INPUT),
4449         HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
4450         HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
4451         {
4452                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4453                 .name = "Capture Source",
4454                 .info = ad198x_mux_enum_info,
4455                 .get = ad198x_mux_enum_get,
4456                 .put = ad198x_mux_enum_put,
4457         },
4458         { } /* end */
4459 };
4460 
4461 static const struct hda_input_mux ad1984a_thinkpad_capture_source = {
4462         .num_items = 3,
4463         .items = {
4464                 { "Mic", 0x0 },
4465                 { "Internal Mic", 0x5 },
4466                 { "Mix", 0x3 },
4467         },
4468 };
4469 
4470 /* mute internal speaker if HP is plugged */
4471 static void ad1984a_thinkpad_automute(struct hda_codec *codec)
4472 {
4473         unsigned int present;
4474 
4475         present = snd_hda_jack_detect(codec, 0x11);
4476         snd_hda_codec_amp_stereo(codec, 0x12, HDA_OUTPUT, 0,
4477                                  HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
4478 }
4479 
4480 /* unsolicited event for HP jack sensing */
4481 static void ad1984a_thinkpad_unsol_event(struct hda_codec *codec,
4482                                          unsigned int res)
4483 {
4484         if ((res >> 26) != AD1884A_HP_EVENT)
4485                 return;
4486         ad1984a_thinkpad_automute(codec);
4487 }
4488 
4489 /* initialize jack-sensing, too */
4490 static int ad1984a_thinkpad_init(struct hda_codec *codec)
4491 {
4492         ad198x_init(codec);
4493         ad1984a_thinkpad_automute(codec);
4494         return 0;
4495 }
4496 
4497 /*
4498  * Precision R5500
4499  * 0x12 - HP/line-out
4500  * 0x13 - speaker (mono)
4501  * 0x15 - mic-in
4502  */
4503 
4504 static const struct hda_verb ad1984a_precision_verbs[] = {
4505         /* Unmute main output path */
4506         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */
4507         {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE + 0x1f}, /* 0dB */
4508         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) + 0x17}, /* 0dB */
4509         /* Analog mixer; mute as default */
4510         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4511         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4512         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4513         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4514         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4515         /* Select mic as input */
4516         {0x0c, AC_VERB_SET_CONNECT_SEL, 0x1},
4517         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE + 0x27}, /* 0dB */
4518         /* Configure as mic */
4519         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4520         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x7002}, /* raise mic as default */
4521         /* HP unmute */
4522         {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4523         /* turn on EAPD */
4524         {0x13, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
4525         /* unsolicited event for pin-sense */
4526         {0x12, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_HP_EVENT},
4527         { } /* end */
4528 };
4529 
4530 static const struct snd_kcontrol_new ad1984a_precision_mixers[] = {
4531         HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT),
4532         HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT),
4533         HDA_CODEC_VOLUME("PCM Playback Volume", 0x20, 0x5, HDA_INPUT),
4534         HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT),
4535         HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x01, HDA_INPUT),
4536         HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x01, HDA_INPUT),
4537         HDA_CODEC_VOLUME("Mic Boost Volume", 0x15, 0x0, HDA_INPUT),
4538         HDA_CODEC_MUTE("Front Playback Switch", 0x12, 0x0, HDA_OUTPUT),
4539         HDA_CODEC_VOLUME("Speaker Playback Volume", 0x13, 0x0, HDA_OUTPUT),
4540         HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
4541         HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
4542         { } /* end */
4543 };
4544 
4545 
4546 /* mute internal speaker if HP is plugged */
4547 static void ad1984a_precision_automute(struct hda_codec *codec)
4548 {
4549         unsigned int present;
4550 
4551         present = snd_hda_jack_detect(codec, 0x12);
4552         snd_hda_codec_amp_stereo(codec, 0x13, HDA_OUTPUT, 0,
4553                                  HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
4554 }
4555 
4556 
4557 /* unsolicited event for HP jack sensing */
4558 static void ad1984a_precision_unsol_event(struct hda_codec *codec,
4559                                          unsigned int res)
4560 {
4561         if ((res >> 26) != AD1884A_HP_EVENT)
4562                 return;
4563         ad1984a_precision_automute(codec);
4564 }
4565 
4566 /* initialize jack-sensing, too */
4567 static int ad1984a_precision_init(struct hda_codec *codec)
4568 {
4569         ad198x_init(codec);
4570         ad1984a_precision_automute(codec);
4571         return 0;
4572 }
4573 
4574 
4575 /*
4576  * HP Touchsmart
4577  * port-A (0x11)      - front hp-out
4578  * port-B (0x14)      - unused
4579  * port-C (0x15)      - unused
4580  * port-D (0x12)      - rear line out
4581  * port-E (0x1c)      - front mic-in
4582  * port-F (0x16)      - Internal speakers
4583  * digital-mic (0x17) - Internal mic
4584  */
4585 
4586 static const struct hda_verb ad1984a_touchsmart_verbs[] = {
4587         /* DACs; unmute as default */
4588         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */
4589         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */
4590         /* Port-A (HP) mixer - route only from analog mixer */
4591         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4592         {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4593         /* Port-A pin */
4594         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4595         /* Port-A (HP) pin - always unmuted */
4596         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4597         /* Port-E (int speaker) mixer - route only from analog mixer */
4598         {0x25, AC_VERB_SET_AMP_GAIN_MUTE, 0x03},
4599         /* Port-E pin */
4600         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4601         {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4602         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4603         /* Port-F (int speaker) mixer - route only from analog mixer */
4604         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4605         {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4606         /* Port-F pin */
4607         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4608         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4609         /* Analog mixer; mute as default */
4610         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4611         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4612         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4613         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4614         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4615         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
4616         /* Analog Mix output amp */
4617         {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4618         /* capture sources */
4619         /* {0x0c, AC_VERB_SET_CONNECT_SEL, 0x0}, */ /* set via unsol */
4620         {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4621         {0x0d, AC_VERB_SET_CONNECT_SEL, 0x0},
4622         {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4623         /* unsolicited event for pin-sense */
4624         {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_HP_EVENT},
4625         {0x1c, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_MIC_EVENT},
4626         /* allow to touch GPIO1 (for mute control) */
4627         {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
4628         {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
4629         {0x01, AC_VERB_SET_GPIO_DATA, 0x02}, /* first muted */
4630         /* internal mic - dmic */
4631         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4632         /* set magic COEFs for dmic */
4633         {0x01, AC_VERB_SET_COEF_INDEX, 0x13f7},
4634         {0x01, AC_VERB_SET_PROC_COEF, 0x08},
4635         { } /* end */
4636 };
4637 
4638 static const struct snd_kcontrol_new ad1984a_touchsmart_mixers[] = {
4639         HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT),
4640 /*      HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT),*/
4641         {
4642                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4643                 .subdevice = HDA_SUBDEV_AMP_FLAG,
4644                 .name = "Master Playback Switch",
4645                 .info = snd_hda_mixer_amp_switch_info,
4646                 .get = snd_hda_mixer_amp_switch_get,
4647                 .put = ad1884a_mobile_master_sw_put,
4648                 .private_value = HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
4649         },
4650         HDA_CODEC_VOLUME("PCM Playback Volume", 0x20, 0x5, HDA_INPUT),
4651         HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT),
4652         HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
4653         HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
4654         HDA_CODEC_VOLUME("Mic Boost Volume", 0x25, 0x0, HDA_OUTPUT),
4655         HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x17, 0x0, HDA_INPUT),
4656         { } /* end */
4657 };
4658 
4659 /* switch to external mic if plugged */
4660 static void ad1984a_touchsmart_automic(struct hda_codec *codec)
4661 {
4662         if (snd_hda_jack_detect(codec, 0x1c))
4663                 snd_hda_codec_write(codec, 0x0c, 0,
4664                                      AC_VERB_SET_CONNECT_SEL, 0x4);
4665         else
4666                 snd_hda_codec_write(codec, 0x0c, 0,
4667                                      AC_VERB_SET_CONNECT_SEL, 0x5);
4668 }
4669 
4670 
4671 /* unsolicited event for HP jack sensing */
4672 static void ad1984a_touchsmart_unsol_event(struct hda_codec *codec,
4673         unsigned int res)
4674 {
4675         switch (res >> 26) {
4676         case AD1884A_HP_EVENT:
4677                 ad1884a_hp_automute(codec);
4678                 break;
4679         case AD1884A_MIC_EVENT:
4680                 ad1984a_touchsmart_automic(codec);
4681                 break;
4682         }
4683 }
4684 
4685 /* initialize jack-sensing, too */
4686 static int ad1984a_touchsmart_init(struct hda_codec *codec)
4687 {
4688         ad198x_init(codec);
4689         ad1884a_hp_automute(codec);
4690         ad1984a_touchsmart_automic(codec);
4691         return 0;
4692 }
4693 
4694 
4695 /*
4696  */
4697 
4698 enum {
4699         AD1884A_AUTO,
4700         AD1884A_DESKTOP,
4701         AD1884A_LAPTOP,
4702         AD1884A_MOBILE,
4703         AD1884A_THINKPAD,
4704         AD1984A_TOUCHSMART,
4705         AD1984A_PRECISION,
4706         AD1884A_MODELS
4707 };
4708 
4709 static const char * const ad1884a_models[AD1884A_MODELS] = {
4710         [AD1884A_AUTO]          = "auto",
4711         [AD1884A_DESKTOP]       = "desktop",
4712         [AD1884A_LAPTOP]        = "laptop",
4713         [AD1884A_MOBILE]        = "mobile",
4714         [AD1884A_THINKPAD]      = "thinkpad",
4715         [AD1984A_TOUCHSMART]    = "touchsmart",
4716         [AD1984A_PRECISION]     = "precision",
4717 };
4718 
4719 static const struct snd_pci_quirk ad1884a_cfg_tbl[] = {
4720         SND_PCI_QUIRK(0x1028, 0x04ac, "Precision R5500", AD1984A_PRECISION),
4721         SND_PCI_QUIRK(0x103c, 0x3030, "HP", AD1884A_MOBILE),
4722         SND_PCI_QUIRK(0x103c, 0x3037, "HP 2230s", AD1884A_LAPTOP),
4723         SND_PCI_QUIRK(0x103c, 0x3056, "HP", AD1884A_MOBILE),
4724         SND_PCI_QUIRK_MASK(0x103c, 0xfff0, 0x3070, "HP", AD1884A_MOBILE),
4725         SND_PCI_QUIRK_MASK(0x103c, 0xfff0, 0x30d0, "HP laptop", AD1884A_LAPTOP),
4726         SND_PCI_QUIRK_MASK(0x103c, 0xfff0, 0x30e0, "HP laptop", AD1884A_LAPTOP),
4727         SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3600, "HP laptop", AD1884A_LAPTOP),
4728         SND_PCI_QUIRK_MASK(0x103c, 0xfff0, 0x7010, "HP laptop", AD1884A_MOBILE),
4729         SND_PCI_QUIRK(0x17aa, 0x20ac, "Thinkpad X300", AD1884A_THINKPAD),
4730         SND_PCI_QUIRK(0x103c, 0x2a82, "Touchsmart", AD1984A_TOUCHSMART),
4731         {}
4732 };
4733 
4734 static int patch_ad1884a(struct hda_codec *codec)
4735 {
4736         struct ad198x_spec *spec;
4737         int err, board_config;
4738 
4739         board_config = snd_hda_check_board_config(codec, AD1884A_MODELS,
4740                                                   ad1884a_models,
4741                                                   ad1884a_cfg_tbl);
4742         if (board_config < 0) {
4743                 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
4744                        codec->chip_name);
4745                 board_config = AD1884A_AUTO;
4746         }
4747 
4748         if (board_config == AD1884A_AUTO)
4749                 return ad1884_parse_auto_config(codec);
4750 
4751         err = alloc_ad_spec(codec);
4752         if (err < 0)
4753                 return err;
4754         spec = codec->spec;
4755 
4756         err = snd_hda_attach_beep_device(codec, 0x10);
4757         if (err < 0) {
4758                 ad198x_free(codec);
4759                 return err;
4760         }
4761         set_beep_amp(spec, 0x10, 0, HDA_OUTPUT);
4762 
4763         spec->multiout.max_channels = 2;
4764         spec->multiout.num_dacs = ARRAY_SIZE(ad1884a_dac_nids);
4765         spec->multiout.dac_nids = ad1884a_dac_nids;
4766         spec->multiout.dig_out_nid = AD1884A_SPDIF_OUT;
4767         spec->num_adc_nids = ARRAY_SIZE(ad1884a_adc_nids);
4768         spec->adc_nids = ad1884a_adc_nids;
4769         spec->capsrc_nids = ad1884a_capsrc_nids;
4770         spec->input_mux = &ad1884a_capture_source;
4771         spec->num_mixers = 1;
4772         spec->mixers[0] = ad1884a_base_mixers;
4773         spec->num_init_verbs = 1;
4774         spec->init_verbs[0] = ad1884a_init_verbs;
4775         spec->spdif_route = 0;
4776 #ifdef CONFIG_PM
4777         spec->loopback.amplist = ad1884a_loopbacks;
4778 #endif
4779         codec->patch_ops = ad198x_patch_ops;
4780 
4781         /* override some parameters */
4782         switch (board_config) {
4783         case AD1884A_LAPTOP:
4784                 spec->mixers[0] = ad1884a_laptop_mixers;
4785                 spec->init_verbs[spec->num_init_verbs++] = ad1884a_laptop_verbs;
4786                 spec->multiout.dig_out_nid = 0;
4787                 codec->patch_ops.unsol_event = ad1884a_laptop_unsol_event;
4788                 codec->patch_ops.init = ad1884a_laptop_init;
4789                 /* set the upper-limit for mixer amp to 0dB for avoiding the
4790                  * possible damage by overloading
4791                  */
4792                 snd_hda_override_amp_caps(codec, 0x20, HDA_INPUT,
4793                                           (0x17 << AC_AMPCAP_OFFSET_SHIFT) |
4794                                           (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) |
4795                                           (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) |
4796                                           (1 << AC_AMPCAP_MUTE_SHIFT));
4797                 break;
4798         case AD1884A_MOBILE:
4799                 spec->mixers[0] = ad1884a_mobile_mixers;
4800                 spec->init_verbs[0] = ad1884a_mobile_verbs;
4801                 spec->multiout.dig_out_nid = 0;
4802                 codec->patch_ops.unsol_event = ad1884a_hp_unsol_event;
4803                 codec->patch_ops.init = ad1884a_hp_init;
4804                 /* set the upper-limit for mixer amp to 0dB for avoiding the
4805                  * possible damage by overloading
4806                  */
4807                 snd_hda_override_amp_caps(codec, 0x20, HDA_INPUT,
4808                                           (0x17 << AC_AMPCAP_OFFSET_SHIFT) |
4809                                           (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) |
4810                                           (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) |
4811                                           (1 << AC_AMPCAP_MUTE_SHIFT));
4812                 break;
4813         case AD1884A_THINKPAD:
4814                 spec->mixers[0] = ad1984a_thinkpad_mixers;
4815                 spec->init_verbs[spec->num_init_verbs++] =
4816                         ad1984a_thinkpad_verbs;
4817                 spec->multiout.dig_out_nid = 0;
4818                 spec->input_mux = &ad1984a_thinkpad_capture_source;
4819                 codec->patch_ops.unsol_event = ad1984a_thinkpad_unsol_event;
4820                 codec->patch_ops.init = ad1984a_thinkpad_init;
4821                 break;
4822         case AD1984A_PRECISION:
4823                 spec->mixers[0] = ad1984a_precision_mixers;
4824                 spec->init_verbs[spec->num_init_verbs++] =
4825                         ad1984a_precision_verbs;
4826                 spec->multiout.dig_out_nid = 0;
4827                 codec->patch_ops.unsol_event = ad1984a_precision_unsol_event;
4828                 codec->patch_ops.init = ad1984a_precision_init;
4829                 break;
4830         case AD1984A_TOUCHSMART:
4831                 spec->mixers[0] = ad1984a_touchsmart_mixers;
4832                 spec->init_verbs[0] = ad1984a_touchsmart_verbs;
4833                 spec->multiout.dig_out_nid = 0;
4834                 codec->patch_ops.unsol_event = ad1984a_touchsmart_unsol_event;
4835                 codec->patch_ops.init = ad1984a_touchsmart_init;
4836                 /* set the upper-limit for mixer amp to 0dB for avoiding the
4837                  * possible damage by overloading
4838                  */
4839                 snd_hda_override_amp_caps(codec, 0x20, HDA_INPUT,
4840                                           (0x17 << AC_AMPCAP_OFFSET_SHIFT) |
4841                                           (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) |
4842                                           (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) |
4843                                           (1 << AC_AMPCAP_MUTE_SHIFT));
4844                 break;
4845         }
4846 
4847         codec->no_trigger_sense = 1;
4848         codec->no_sticky_stream = 1;
4849 
4850         return 0;
4851 }
4852 #else /* ENABLE_AD_STATIC_QUIRKS */
4853 #define patch_ad1884a   ad1884_parse_auto_config
4854 #endif /* ENABLE_AD_STATIC_QUIRKS */
4855 
4856 
4857 /*
4858  * AD1882 / AD1882A
4859  *
4860  * port-A - front hp-out
4861  * port-B - front mic-in
4862  * port-C - rear line-in, shared surr-out (3stack)
4863  * port-D - rear line-out
4864  * port-E - rear mic-in, shared clfe-out (3stack)
4865  * port-F - rear surr-out (6stack)
4866  * port-G - rear clfe-out (6stack)
4867  */
4868 
4869 #ifdef ENABLE_AD_STATIC_QUIRKS
4870 static const hda_nid_t ad1882_dac_nids[3] = {
4871         0x04, 0x03, 0x05
4872 };
4873 
4874 static const hda_nid_t ad1882_adc_nids[2] = {
4875         0x08, 0x09,
4876 };
4877 
4878 static const hda_nid_t ad1882_capsrc_nids[2] = {
4879         0x0c, 0x0d,
4880 };
4881 
4882 #define AD1882_SPDIF_OUT        0x02
4883 
4884 /* list: 0x11, 0x39, 0x3a, 0x18, 0x3c, 0x3b, 0x12, 0x20 */
4885 static const struct hda_input_mux ad1882_capture_source = {
4886         .num_items = 5,
4887         .items = {
4888                 { "Front Mic", 0x1 },
4889                 { "Mic", 0x4 },
4890                 { "Line", 0x2 },
4891                 { "CD", 0x3 },
4892                 { "Mix", 0x7 },
4893         },
4894 };
4895 
4896 /* list: 0x11, 0x39, 0x3a, 0x3c, 0x18, 0x1f, 0x12, 0x20 */
4897 static const struct hda_input_mux ad1882a_capture_source = {
4898         .num_items = 5,
4899         .items = {
4900                 { "Front Mic", 0x1 },
4901                 { "Mic", 0x4},
4902                 { "Line", 0x2 },
4903                 { "Digital Mic", 0x06 },
4904                 { "Mix", 0x7 },
4905         },
4906 };
4907 
4908 static const struct snd_kcontrol_new ad1882_base_mixers[] = {
4909         HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT),
4910         HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
4911         HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x05, 1, 0x0, HDA_OUTPUT),
4912         HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x05, 2, 0x0, HDA_OUTPUT),
4913         HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT),
4914         HDA_CODEC_MUTE("Front Playback Switch", 0x12, 0x0, HDA_OUTPUT),
4915         HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x13, 1, 0x0, HDA_OUTPUT),
4916         HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x13, 1, 0x0, HDA_OUTPUT),
4917 
4918         HDA_CODEC_VOLUME("Mic Boost Volume", 0x3c, 0x0, HDA_OUTPUT),
4919         HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x39, 0x0, HDA_OUTPUT),
4920         HDA_CODEC_VOLUME("Line-In Boost Volume", 0x3a, 0x0, HDA_OUTPUT),
4921         HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
4922         HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
4923         HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT),
4924         HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x0d, 0x0, HDA_OUTPUT),
4925         {
4926                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4927                 /* The multiple "Capture Source" controls confuse alsamixer
4928                  * So call somewhat different..
4929                  */
4930                 /* .name = "Capture Source", */
4931                 .name = "Input Source",
4932                 .count = 2,
4933                 .info = ad198x_mux_enum_info,
4934                 .get = ad198x_mux_enum_get,
4935                 .put = ad198x_mux_enum_put,
4936         },
4937         /* SPDIF controls */
4938         HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
4939         {
4940                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4941                 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
4942                 /* identical with ad1983 */
4943                 .info = ad1983_spdif_route_info,
4944                 .get = ad1983_spdif_route_get,
4945                 .put = ad1983_spdif_route_put,
4946         },
4947         { } /* end */
4948 };
4949 
4950 static const struct snd_kcontrol_new ad1882_loopback_mixers[] = {
4951         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
4952         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
4953         HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x01, HDA_INPUT),
4954         HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x01, HDA_INPUT),
4955         HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x04, HDA_INPUT),
4956         HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x04, HDA_INPUT),
4957         HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x06, HDA_INPUT),
4958         HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x06, HDA_INPUT),
4959         { } /* end */
4960 };
4961 
4962 static const struct snd_kcontrol_new ad1882a_loopback_mixers[] = {
4963         HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
4964         HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
4965         HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x04, HDA_INPUT),
4966         HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x04, HDA_INPUT),
4967         HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x01, HDA_INPUT),
4968         HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x01, HDA_INPUT),
4969         HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x06, HDA_INPUT),
4970         HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x06, HDA_INPUT),
4971         HDA_CODEC_VOLUME("Digital Mic Boost Volume", 0x1f, 0x0, HDA_INPUT),
4972         { } /* end */
4973 };
4974 
4975 static const struct snd_kcontrol_new ad1882_3stack_mixers[] = {
4976         HDA_CODEC_MUTE("Surround Playback Switch", 0x15, 0x0, HDA_OUTPUT),
4977         HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x17, 1, 0x0, HDA_OUTPUT),
4978         HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x17, 2, 0x0, HDA_OUTPUT),
4979         {
4980                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4981                 .name = "Channel Mode",
4982                 .info = ad198x_ch_mode_info,
4983                 .get = ad198x_ch_mode_get,
4984                 .put = ad198x_ch_mode_put,
4985         },
4986         { } /* end */
4987 };
4988 
4989 /* simple auto-mute control for AD1882 3-stack board */
4990 #define AD1882_HP_EVENT 0x01
4991 
4992 static void ad1882_3stack_automute(struct hda_codec *codec)
4993 {
4994         bool mute = snd_hda_jack_detect(codec, 0x11);
4995         snd_hda_codec_write(codec, 0x12, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4996                             mute ? 0 : PIN_OUT);
4997 }
4998 
4999 static int ad1882_3stack_automute_init(struct hda_codec *codec)
5000 {
5001         ad198x_init(codec);
5002         ad1882_3stack_automute(codec);
5003         return 0;
5004 }
5005 
5006 static void ad1882_3stack_unsol_event(struct hda_codec *codec, unsigned int res)
5007 {
5008         switch (res >> 26) {
5009         case AD1882_HP_EVENT:
5010                 ad1882_3stack_automute(codec);
5011                 break;
5012         }
5013 }
5014 
5015 static const struct snd_kcontrol_new ad1882_6stack_mixers[] = {
5016         HDA_CODEC_MUTE("Surround Playback Switch", 0x16, 0x0, HDA_OUTPUT),
5017         HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x24, 1, 0x0, HDA_OUTPUT),
5018         HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x24, 2, 0x0, HDA_OUTPUT),
5019         { } /* end */
5020 };
5021 
5022 static const struct hda_verb ad1882_ch2_init[] = {
5023         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5024         {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5025         {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5026         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5027         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5028         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5029         { } /* end */
5030 };
5031 
5032 static const struct hda_verb ad1882_ch4_init[] = {
5033         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5034         {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5035         {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5036         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5037         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5038         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5039         { } /* end */
5040 };
5041 
5042 static const struct hda_verb ad1882_ch6_init[] = {
5043         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5044         {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5045         {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5046         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5047         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5048         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5049         { } /* end */
5050 };
5051 
5052 static const struct hda_channel_mode ad1882_modes[3] = {
5053         { 2, ad1882_ch2_init },
5054         { 4, ad1882_ch4_init },
5055         { 6, ad1882_ch6_init },
5056 };
5057 
5058 /*
5059  * initialization verbs
5060  */
5061 static const struct hda_verb ad1882_init_verbs[] = {
5062         /* DACs; mute as default */
5063         {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5064         {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5065         {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5066         /* Port-A (HP) mixer */
5067         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5068         {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5069         /* Port-A pin */
5070         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5071         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5072         /* HP selector - select DAC2 */
5073         {0x37, AC_VERB_SET_CONNECT_SEL, 0x1},
5074         /* Port-D (Line-out) mixer */
5075         {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5076         {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5077         /* Port-D pin */
5078         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5079         {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5080         /* Mono-out mixer */
5081         {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5082         {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5083         /* Mono-out pin */
5084         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5085         {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5086         /* Port-B (front mic) pin */
5087         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5088         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5089         {0x39, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, /* boost */
5090         /* Port-C (line-in) pin */
5091         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5092         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5093         {0x3a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, /* boost */
5094         /* Port-C mixer - mute as input */
5095         {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5096         {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5097         /* Port-E (mic-in) pin */
5098         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5099         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5100         {0x3c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, /* boost */
5101         /* Port-E mixer - mute as input */
5102         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5103         {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5104         /* Port-F (surround) */
5105         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5106         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5107         /* Port-G (CLFE) */
5108         {0x24, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5109         {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5110         /* Analog mixer; mute as default */
5111         /* list: 0x39, 0x3a, 0x11, 0x12, 0x3c, 0x3b, 0x18, 0x1a */
5112         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5113         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5114         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5115         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5116         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5117         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
5118         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
5119         {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
5120         /* Analog Mix output amp */
5121         {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x1f}, /* 0dB */
5122         /* SPDIF output selector */
5123         {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */
5124         {0x02, AC_VERB_SET_CONNECT_SEL, 0x0}, /* PCM */
5125         {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */
5126         { } /* end */
5127 };
5128 
5129 static const struct hda_verb ad1882_3stack_automute_verbs[] = {
5130         {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1882_HP_EVENT},
5131         { } /* end */
5132 };
5133 
5134 #ifdef CONFIG_PM
5135 static const struct hda_amp_list ad1882_loopbacks[] = {
5136         { 0x20, HDA_INPUT, 0 }, /* Front Mic */
5137         { 0x20, HDA_INPUT, 1 }, /* Mic */
5138         { 0x20, HDA_INPUT, 4 }, /* Line */
5139         { 0x20, HDA_INPUT, 6 }, /* CD */
5140         { } /* end */
5141 };
5142 #endif
5143 
5144 /* models */
5145 enum {
5146         AD1882_AUTO,
5147         AD1882_3STACK,
5148         AD1882_6STACK,
5149         AD1882_3STACK_AUTOMUTE,
5150         AD1882_MODELS
5151 };
5152 
5153 static const char * const ad1882_models[AD1986A_MODELS] = {
5154         [AD1882_AUTO]           = "auto",
5155         [AD1882_3STACK]         = "3stack",
5156         [AD1882_6STACK]         = "6stack",
5157         [AD1882_3STACK_AUTOMUTE] = "3stack-automute",
5158 };
5159 #endif /* ENABLE_AD_STATIC_QUIRKS */
5160 
5161 static int ad1882_parse_auto_config(struct hda_codec *codec)
5162 {
5163         struct ad198x_spec *spec;
5164         int err;
5165 
5166         err = alloc_ad_spec(codec);
5167         if (err < 0)
5168                 return err;
5169         spec = codec->spec;
5170 
5171         spec->gen.mixer_nid = 0x20;
5172         spec->gen.mixer_merge_nid = 0x21;
5173         spec->gen.beep_nid = 0x10;
5174         set_beep_amp(spec, 0x10, 0, HDA_OUTPUT);
5175         err = ad198x_parse_auto_config(codec);
5176         if (err < 0)
5177                 goto error;
5178         err = ad1988_add_spdif_mux_ctl(codec);
5179         if (err < 0)
5180                 goto error;
5181         return 0;
5182 
5183  error:
5184         snd_hda_gen_free(codec);
5185         return err;
5186 }
5187 
5188 #ifdef ENABLE_AD_STATIC_QUIRKS
5189 static int patch_ad1882(struct hda_codec *codec)
5190 {
5191         struct ad198x_spec *spec;
5192         int err, board_config;
5193 
5194         board_config = snd_hda_check_board_config(codec, AD1882_MODELS,
5195                                                   ad1882_models, NULL);
5196         if (board_config < 0) {
5197                 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
5198                        codec->chip_name);
5199                 board_config = AD1882_AUTO;
5200         }
5201 
5202         if (board_config == AD1882_AUTO)
5203                 return ad1882_parse_auto_config(codec);
5204 
5205         err = alloc_ad_spec(codec);
5206         if (err < 0)
5207                 return err;
5208         spec = codec->spec;
5209 
5210         err = snd_hda_attach_beep_device(codec, 0x10);
5211         if (err < 0) {
5212                 ad198x_free(codec);
5213                 return err;
5214         }
5215         set_beep_amp(spec, 0x10, 0, HDA_OUTPUT);
5216 
5217         spec->multiout.max_channels = 6;
5218         spec->multiout.num_dacs = 3;
5219         spec->multiout.dac_nids = ad1882_dac_nids;
5220         spec->multiout.dig_out_nid = AD1882_SPDIF_OUT;
5221         spec->num_adc_nids = ARRAY_SIZE(ad1882_adc_nids);
5222         spec->adc_nids = ad1882_adc_nids;
5223         spec->capsrc_nids = ad1882_capsrc_nids;
5224         if (codec->vendor_id == 0x11d41882)
5225                 spec->input_mux = &ad1882_capture_source;
5226         else
5227                 spec->input_mux = &ad1882a_capture_source;
5228         spec->num_mixers = 2;
5229         spec->mixers[0] = ad1882_base_mixers;
5230         if (codec->vendor_id == 0x11d41882)
5231                 spec->mixers[1] = ad1882_loopback_mixers;
5232         else
5233                 spec->mixers[1] = ad1882a_loopback_mixers;
5234         spec->num_init_verbs = 1;
5235         spec->init_verbs[0] = ad1882_init_verbs;
5236         spec->spdif_route = 0;
5237 #ifdef CONFIG_PM
5238         spec->loopback.amplist = ad1882_loopbacks;
5239 #endif
5240         spec->vmaster_nid = 0x04;
5241 
5242         codec->patch_ops = ad198x_patch_ops;
5243 
5244         /* override some parameters */
5245         switch (board_config) {
5246         default:
5247         case AD1882_3STACK:
5248         case AD1882_3STACK_AUTOMUTE:
5249                 spec->num_mixers = 3;
5250                 spec->mixers[2] = ad1882_3stack_mixers;
5251                 spec->channel_mode = ad1882_modes;
5252                 spec->num_channel_mode = ARRAY_SIZE(ad1882_modes);
5253                 spec->need_dac_fix = 1;
5254                 spec->multiout.max_channels = 2;
5255                 spec->multiout.num_dacs = 1;
5256                 if (board_config != AD1882_3STACK) {
5257                         spec->init_verbs[spec->num_init_verbs++] =
5258                                 ad1882_3stack_automute_verbs;
5259                         codec->patch_ops.unsol_event = ad1882_3stack_unsol_event;
5260                         codec->patch_ops.init = ad1882_3stack_automute_init;
5261                 }
5262                 break;
5263         case AD1882_6STACK:
5264                 spec->num_mixers = 3;
5265                 spec->mixers[2] = ad1882_6stack_mixers;
5266                 break;
5267         }
5268 
5269         codec->no_trigger_sense = 1;
5270         codec->no_sticky_stream = 1;
5271 
5272         return 0;
5273 }
5274 #else /* ENABLE_AD_STATIC_QUIRKS */
5275 #define patch_ad1882    ad1882_parse_auto_config
5276 #endif /* ENABLE_AD_STATIC_QUIRKS */
5277 
5278 
5279 /*
5280  * patch entries
5281  */
5282 static const struct hda_codec_preset snd_hda_preset_analog[] = {
5283         { .id = 0x11d4184a, .name = "AD1884A", .patch = patch_ad1884a },
5284         { .id = 0x11d41882, .name = "AD1882", .patch = patch_ad1882 },
5285         { .id = 0x11d41883, .name = "AD1883", .patch = patch_ad1884a },
5286         { .id = 0x11d41884, .name = "AD1884", .patch = patch_ad1884 },
5287         { .id = 0x11d4194a, .name = "AD1984A", .patch = patch_ad1884a },
5288         { .id = 0x11d4194b, .name = "AD1984B", .patch = patch_ad1884a },
5289         { .id = 0x11d41981, .name = "AD1981", .patch = patch_ad1981 },
5290         { .id = 0x11d41983, .name = "AD1983", .patch = patch_ad1983 },
5291         { .id = 0x11d41984, .name = "AD1984", .patch = patch_ad1984 },
5292         { .id = 0x11d41986, .name = "AD1986A", .patch = patch_ad1986a },
5293         { .id = 0x11d41988, .name = "AD1988", .patch = patch_ad1988 },
5294         { .id = 0x11d4198b, .name = "AD1988B", .patch = patch_ad1988 },
5295         { .id = 0x11d4882a, .name = "AD1882A", .patch = patch_ad1882 },
5296         { .id = 0x11d4989a, .name = "AD1989A", .patch = patch_ad1988 },
5297         { .id = 0x11d4989b, .name = "AD1989B", .patch = patch_ad1988 },
5298         {} /* terminator */
5299 };
5300 
5301 MODULE_ALIAS("snd-hda-codec-id:11d4*");
5302 
5303 MODULE_LICENSE("GPL");
5304 MODULE_DESCRIPTION("Analog Devices HD-audio codec");
5305 
5306 static struct hda_codec_preset_list analog_list = {
5307         .preset = snd_hda_preset_analog,
5308         .owner = THIS_MODULE,
5309 };
5310 
5311 static int __init patch_analog_init(void)
5312 {
5313         return snd_hda_add_codec_preset(&analog_list);
5314 }
5315 
5316 static void __exit patch_analog_exit(void)
5317 {
5318         snd_hda_delete_codec_preset(&analog_list);
5319 }
5320 
5321 module_init(patch_analog_init)
5322 module_exit(patch_analog_exit)
5323 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp