]> git.karo-electronics.de Git - karo-tx-linux.git/blob - sound/pci/hda/patch_conexant.c
ALSA: hda - Add auto-parser support to cxt5051 / CX20561 Hermosa
[karo-tx-linux.git] / sound / pci / hda / patch_conexant.c
1 /*
2  * HD audio interface patch for Conexant HDA audio codec
3  *
4  * Copyright (c) 2006 Pototskiy Akex <alex.pototskiy@gmail.com>
5  *                    Takashi Iwai <tiwai@suse.de>
6  *                    Tobin Davis  <tdavis@dsl-only.net>
7  *
8  *  This driver is free software; you can redistribute it and/or modify
9  *  it under the terms of the GNU General Public License as published by
10  *  the Free Software Foundation; either version 2 of the License, or
11  *  (at your option) any later version.
12  *
13  *  This driver is distributed in the hope that it will be useful,
14  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  *  GNU General Public License for more details.
17  *
18  *  You should have received a copy of the GNU General Public License
19  *  along with this program; if not, write to the Free Software
20  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
21  */
22
23 #include <linux/init.h>
24 #include <linux/delay.h>
25 #include <linux/slab.h>
26 #include <linux/pci.h>
27 #include <sound/core.h>
28 #include <sound/jack.h>
29
30 #include "hda_codec.h"
31 #include "hda_local.h"
32 #include "hda_beep.h"
33
34 #define CXT_PIN_DIR_IN              0x00
35 #define CXT_PIN_DIR_OUT             0x01
36 #define CXT_PIN_DIR_INOUT           0x02
37 #define CXT_PIN_DIR_IN_NOMICBIAS    0x03
38 #define CXT_PIN_DIR_INOUT_NOMICBIAS 0x04
39
40 #define CONEXANT_HP_EVENT       0x37
41 #define CONEXANT_MIC_EVENT      0x38
42
43 /* Conexant 5051 specific */
44
45 #define CXT5051_SPDIF_OUT       0x12
46 #define CXT5051_PORTB_EVENT     0x38
47 #define CXT5051_PORTC_EVENT     0x39
48
49 #define AUTO_MIC_PORTB          (1 << 1)
50 #define AUTO_MIC_PORTC          (1 << 2)
51
52 struct pin_dac_pair {
53         hda_nid_t pin;
54         hda_nid_t dac;
55         int type;
56 };
57
58 struct conexant_spec {
59
60         const struct snd_kcontrol_new *mixers[5];
61         int num_mixers;
62         hda_nid_t vmaster_nid;
63
64         const struct hda_verb *init_verbs[5];   /* initialization verbs
65                                                  * don't forget NULL
66                                                  * termination!
67                                                  */
68         unsigned int num_init_verbs;
69
70         /* playback */
71         struct hda_multi_out multiout;  /* playback set-up
72                                          * max_channels, dacs must be set
73                                          * dig_out_nid and hp_nid are optional
74                                          */
75         unsigned int cur_eapd;
76         unsigned int hp_present;
77         unsigned int auto_mic;
78         int auto_mic_ext;               /* autocfg.inputs[] index for ext mic */
79         unsigned int need_dac_fix;
80         hda_nid_t slave_dig_outs[2];
81
82         /* capture */
83         unsigned int num_adc_nids;
84         const hda_nid_t *adc_nids;
85         hda_nid_t dig_in_nid;           /* digital-in NID; optional */
86
87         unsigned int cur_adc_idx;
88         hda_nid_t cur_adc;
89         unsigned int cur_adc_stream_tag;
90         unsigned int cur_adc_format;
91
92         const struct hda_pcm_stream *capture_stream;
93
94         /* capture source */
95         const struct hda_input_mux *input_mux;
96         const hda_nid_t *capsrc_nids;
97         unsigned int cur_mux[3];
98
99         /* channel model */
100         const struct hda_channel_mode *channel_mode;
101         int num_channel_mode;
102
103         /* PCM information */
104         struct hda_pcm pcm_rec[2];      /* used in build_pcms() */
105
106         unsigned int spdif_route;
107
108         /* dynamic controls, init_verbs and input_mux */
109         struct auto_pin_cfg autocfg;
110         struct hda_input_mux private_imux;
111         hda_nid_t imux_adcs[HDA_MAX_NUM_INPUTS];
112         hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
113         struct pin_dac_pair dac_info[8];
114         int dac_info_filled;
115
116         unsigned int port_d_mode;
117         unsigned int auto_mute:1;       /* used in auto-parser */
118         unsigned int dell_automute:1;
119         unsigned int dell_vostro:1;
120         unsigned int ideapad:1;
121         unsigned int thinkpad:1;
122         unsigned int hp_laptop:1;
123         unsigned int asus:1;
124
125         unsigned int adc_switching:1;
126
127         unsigned int ext_mic_present;
128         unsigned int recording;
129         void (*capture_prepare)(struct hda_codec *codec);
130         void (*capture_cleanup)(struct hda_codec *codec);
131
132         /* OLPC XO-1.5 supports DC input mode (e.g. for use with analog sensors)
133          * through the microphone jack.
134          * When the user enables this through a mixer switch, both internal and
135          * external microphones are disabled. Gain is fixed at 0dB. In this mode,
136          * we also allow the bias to be configured through a separate mixer
137          * control. */
138         unsigned int dc_enable;
139         unsigned int dc_input_bias; /* offset into cxt5066_olpc_dc_bias */
140         unsigned int mic_boost; /* offset into cxt5066_analog_mic_boost */
141
142         unsigned int beep_amp;
143 };
144
145 static int conexant_playback_pcm_open(struct hda_pcm_stream *hinfo,
146                                       struct hda_codec *codec,
147                                       struct snd_pcm_substream *substream)
148 {
149         struct conexant_spec *spec = codec->spec;
150         return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
151                                              hinfo);
152 }
153
154 static int conexant_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
155                                          struct hda_codec *codec,
156                                          unsigned int stream_tag,
157                                          unsigned int format,
158                                          struct snd_pcm_substream *substream)
159 {
160         struct conexant_spec *spec = codec->spec;
161         return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
162                                                 stream_tag,
163                                                 format, substream);
164 }
165
166 static int conexant_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
167                                          struct hda_codec *codec,
168                                          struct snd_pcm_substream *substream)
169 {
170         struct conexant_spec *spec = codec->spec;
171         return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
172 }
173
174 /*
175  * Digital out
176  */
177 static int conexant_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
178                                           struct hda_codec *codec,
179                                           struct snd_pcm_substream *substream)
180 {
181         struct conexant_spec *spec = codec->spec;
182         return snd_hda_multi_out_dig_open(codec, &spec->multiout);
183 }
184
185 static int conexant_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
186                                          struct hda_codec *codec,
187                                          struct snd_pcm_substream *substream)
188 {
189         struct conexant_spec *spec = codec->spec;
190         return snd_hda_multi_out_dig_close(codec, &spec->multiout);
191 }
192
193 static int conexant_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
194                                          struct hda_codec *codec,
195                                          unsigned int stream_tag,
196                                          unsigned int format,
197                                          struct snd_pcm_substream *substream)
198 {
199         struct conexant_spec *spec = codec->spec;
200         return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
201                                              stream_tag,
202                                              format, substream);
203 }
204
205 /*
206  * Analog capture
207  */
208 static int conexant_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
209                                       struct hda_codec *codec,
210                                       unsigned int stream_tag,
211                                       unsigned int format,
212                                       struct snd_pcm_substream *substream)
213 {
214         struct conexant_spec *spec = codec->spec;
215         if (spec->capture_prepare)
216                 spec->capture_prepare(codec);
217         snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
218                                    stream_tag, 0, format);
219         return 0;
220 }
221
222 static int conexant_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
223                                       struct hda_codec *codec,
224                                       struct snd_pcm_substream *substream)
225 {
226         struct conexant_spec *spec = codec->spec;
227         snd_hda_codec_cleanup_stream(codec, spec->adc_nids[substream->number]);
228         if (spec->capture_cleanup)
229                 spec->capture_cleanup(codec);
230         return 0;
231 }
232
233
234
235 static const struct hda_pcm_stream conexant_pcm_analog_playback = {
236         .substreams = 1,
237         .channels_min = 2,
238         .channels_max = 2,
239         .nid = 0, /* fill later */
240         .ops = {
241                 .open = conexant_playback_pcm_open,
242                 .prepare = conexant_playback_pcm_prepare,
243                 .cleanup = conexant_playback_pcm_cleanup
244         },
245 };
246
247 static const struct hda_pcm_stream conexant_pcm_analog_capture = {
248         .substreams = 1,
249         .channels_min = 2,
250         .channels_max = 2,
251         .nid = 0, /* fill later */
252         .ops = {
253                 .prepare = conexant_capture_pcm_prepare,
254                 .cleanup = conexant_capture_pcm_cleanup
255         },
256 };
257
258
259 static const struct hda_pcm_stream conexant_pcm_digital_playback = {
260         .substreams = 1,
261         .channels_min = 2,
262         .channels_max = 2,
263         .nid = 0, /* fill later */
264         .ops = {
265                 .open = conexant_dig_playback_pcm_open,
266                 .close = conexant_dig_playback_pcm_close,
267                 .prepare = conexant_dig_playback_pcm_prepare
268         },
269 };
270
271 static const struct hda_pcm_stream conexant_pcm_digital_capture = {
272         .substreams = 1,
273         .channels_min = 2,
274         .channels_max = 2,
275         /* NID is set in alc_build_pcms */
276 };
277
278 static int cx5051_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
279                                       struct hda_codec *codec,
280                                       unsigned int stream_tag,
281                                       unsigned int format,
282                                       struct snd_pcm_substream *substream)
283 {
284         struct conexant_spec *spec = codec->spec;
285         spec->cur_adc = spec->adc_nids[spec->cur_adc_idx];
286         spec->cur_adc_stream_tag = stream_tag;
287         spec->cur_adc_format = format;
288         snd_hda_codec_setup_stream(codec, spec->cur_adc, stream_tag, 0, format);
289         return 0;
290 }
291
292 static int cx5051_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
293                                       struct hda_codec *codec,
294                                       struct snd_pcm_substream *substream)
295 {
296         struct conexant_spec *spec = codec->spec;
297         snd_hda_codec_cleanup_stream(codec, spec->cur_adc);
298         spec->cur_adc = 0;
299         return 0;
300 }
301
302 static const struct hda_pcm_stream cx5051_pcm_analog_capture = {
303         .substreams = 1,
304         .channels_min = 2,
305         .channels_max = 2,
306         .nid = 0, /* fill later */
307         .ops = {
308                 .prepare = cx5051_capture_pcm_prepare,
309                 .cleanup = cx5051_capture_pcm_cleanup
310         },
311 };
312
313 static int conexant_build_pcms(struct hda_codec *codec)
314 {
315         struct conexant_spec *spec = codec->spec;
316         struct hda_pcm *info = spec->pcm_rec;
317
318         codec->num_pcms = 1;
319         codec->pcm_info = info;
320
321         info->name = "CONEXANT Analog";
322         info->stream[SNDRV_PCM_STREAM_PLAYBACK] = conexant_pcm_analog_playback;
323         info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max =
324                 spec->multiout.max_channels;
325         info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
326                 spec->multiout.dac_nids[0];
327         if (spec->capture_stream)
328                 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *spec->capture_stream;
329         else {
330                 if (codec->vendor_id == 0x14f15051)
331                         info->stream[SNDRV_PCM_STREAM_CAPTURE] =
332                                 cx5051_pcm_analog_capture;
333                 else {
334                         info->stream[SNDRV_PCM_STREAM_CAPTURE] =
335                                 conexant_pcm_analog_capture;
336                         info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
337                                 spec->num_adc_nids;
338                 }
339         }
340         info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
341
342         if (spec->multiout.dig_out_nid) {
343                 info++;
344                 codec->num_pcms++;
345                 info->name = "Conexant Digital";
346                 info->pcm_type = HDA_PCM_TYPE_SPDIF;
347                 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
348                         conexant_pcm_digital_playback;
349                 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
350                         spec->multiout.dig_out_nid;
351                 if (spec->dig_in_nid) {
352                         info->stream[SNDRV_PCM_STREAM_CAPTURE] =
353                                 conexant_pcm_digital_capture;
354                         info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
355                                 spec->dig_in_nid;
356                 }
357                 if (spec->slave_dig_outs[0])
358                         codec->slave_dig_outs = spec->slave_dig_outs;
359         }
360
361         return 0;
362 }
363
364 static int conexant_mux_enum_info(struct snd_kcontrol *kcontrol,
365                                   struct snd_ctl_elem_info *uinfo)
366 {
367         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
368         struct conexant_spec *spec = codec->spec;
369
370         return snd_hda_input_mux_info(spec->input_mux, uinfo);
371 }
372
373 static int conexant_mux_enum_get(struct snd_kcontrol *kcontrol,
374                                  struct snd_ctl_elem_value *ucontrol)
375 {
376         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
377         struct conexant_spec *spec = codec->spec;
378         unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
379
380         ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
381         return 0;
382 }
383
384 static int conexant_mux_enum_put(struct snd_kcontrol *kcontrol,
385                                  struct snd_ctl_elem_value *ucontrol)
386 {
387         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
388         struct conexant_spec *spec = codec->spec;
389         unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
390
391         return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol,
392                                      spec->capsrc_nids[adc_idx],
393                                      &spec->cur_mux[adc_idx]);
394 }
395
396 static int conexant_init_jacks(struct hda_codec *codec)
397 {
398 #ifdef CONFIG_SND_HDA_INPUT_JACK
399         struct conexant_spec *spec = codec->spec;
400         int i;
401
402         for (i = 0; i < spec->num_init_verbs; i++) {
403                 const struct hda_verb *hv;
404
405                 hv = spec->init_verbs[i];
406                 while (hv->nid) {
407                         int err = 0;
408                         switch (hv->param ^ AC_USRSP_EN) {
409                         case CONEXANT_HP_EVENT:
410                                 err = snd_hda_input_jack_add(codec, hv->nid,
411                                                 SND_JACK_HEADPHONE, NULL);
412                                 snd_hda_input_jack_report(codec, hv->nid);
413                                 break;
414                         case CXT5051_PORTC_EVENT:
415                         case CONEXANT_MIC_EVENT:
416                                 err = snd_hda_input_jack_add(codec, hv->nid,
417                                                 SND_JACK_MICROPHONE, NULL);
418                                 snd_hda_input_jack_report(codec, hv->nid);
419                                 break;
420                         }
421                         if (err < 0)
422                                 return err;
423                         ++hv;
424                 }
425         }
426 #endif /* CONFIG_SND_HDA_INPUT_JACK */
427         return 0;
428 }
429
430 static int conexant_init(struct hda_codec *codec)
431 {
432         struct conexant_spec *spec = codec->spec;
433         int i;
434
435         for (i = 0; i < spec->num_init_verbs; i++)
436                 snd_hda_sequence_write(codec, spec->init_verbs[i]);
437         return 0;
438 }
439
440 static void conexant_free(struct hda_codec *codec)
441 {
442         snd_hda_input_jack_free(codec);
443         snd_hda_detach_beep_device(codec);
444         kfree(codec->spec);
445 }
446
447 static const struct snd_kcontrol_new cxt_capture_mixers[] = {
448         {
449                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
450                 .name = "Capture Source",
451                 .info = conexant_mux_enum_info,
452                 .get = conexant_mux_enum_get,
453                 .put = conexant_mux_enum_put
454         },
455         {}
456 };
457
458 #ifdef CONFIG_SND_HDA_INPUT_BEEP
459 /* additional beep mixers; the actual parameters are overwritten at build */
460 static const struct snd_kcontrol_new cxt_beep_mixer[] = {
461         HDA_CODEC_VOLUME_MONO("Beep Playback Volume", 0, 1, 0, HDA_OUTPUT),
462         HDA_CODEC_MUTE_BEEP_MONO("Beep Playback Switch", 0, 1, 0, HDA_OUTPUT),
463         { } /* end */
464 };
465 #endif
466
467 static const char * const slave_vols[] = {
468         "Headphone Playback Volume",
469         "Speaker Playback Volume",
470         NULL
471 };
472
473 static const char * const slave_sws[] = {
474         "Headphone Playback Switch",
475         "Speaker Playback Switch",
476         NULL
477 };
478
479 static int conexant_build_controls(struct hda_codec *codec)
480 {
481         struct conexant_spec *spec = codec->spec;
482         unsigned int i;
483         int err;
484
485         for (i = 0; i < spec->num_mixers; i++) {
486                 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
487                 if (err < 0)
488                         return err;
489         }
490         if (spec->multiout.dig_out_nid) {
491                 err = snd_hda_create_spdif_out_ctls(codec,
492                                                     spec->multiout.dig_out_nid);
493                 if (err < 0)
494                         return err;
495                 err = snd_hda_create_spdif_share_sw(codec,
496                                                     &spec->multiout);
497                 if (err < 0)
498                         return err;
499                 spec->multiout.share_spdif = 1;
500         } 
501         if (spec->dig_in_nid) {
502                 err = snd_hda_create_spdif_in_ctls(codec,spec->dig_in_nid);
503                 if (err < 0)
504                         return err;
505         }
506
507         /* if we have no master control, let's create it */
508         if (spec->vmaster_nid &&
509             !snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
510                 unsigned int vmaster_tlv[4];
511                 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
512                                         HDA_OUTPUT, vmaster_tlv);
513                 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
514                                           vmaster_tlv, slave_vols);
515                 if (err < 0)
516                         return err;
517         }
518         if (spec->vmaster_nid &&
519             !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
520                 err = snd_hda_add_vmaster(codec, "Master Playback Switch",
521                                           NULL, slave_sws);
522                 if (err < 0)
523                         return err;
524         }
525
526         if (spec->input_mux) {
527                 err = snd_hda_add_new_ctls(codec, cxt_capture_mixers);
528                 if (err < 0)
529                         return err;
530         }
531
532 #ifdef CONFIG_SND_HDA_INPUT_BEEP
533         /* create beep controls if needed */
534         if (spec->beep_amp) {
535                 const struct snd_kcontrol_new *knew;
536                 for (knew = cxt_beep_mixer; knew->name; knew++) {
537                         struct snd_kcontrol *kctl;
538                         kctl = snd_ctl_new1(knew, codec);
539                         if (!kctl)
540                                 return -ENOMEM;
541                         kctl->private_value = spec->beep_amp;
542                         err = snd_hda_ctl_add(codec, 0, kctl);
543                         if (err < 0)
544                                 return err;
545                 }
546         }
547 #endif
548
549         return 0;
550 }
551
552 #ifdef CONFIG_SND_HDA_POWER_SAVE
553 static int conexant_suspend(struct hda_codec *codec, pm_message_t state)
554 {
555         snd_hda_shutup_pins(codec);
556         return 0;
557 }
558 #endif
559
560 static const struct hda_codec_ops conexant_patch_ops = {
561         .build_controls = conexant_build_controls,
562         .build_pcms = conexant_build_pcms,
563         .init = conexant_init,
564         .free = conexant_free,
565 #ifdef CONFIG_SND_HDA_POWER_SAVE
566         .suspend = conexant_suspend,
567 #endif
568         .reboot_notify = snd_hda_shutup_pins,
569 };
570
571 #ifdef CONFIG_SND_HDA_INPUT_BEEP
572 #define set_beep_amp(spec, nid, idx, dir) \
573         ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 1, idx, dir))
574 #else
575 #define set_beep_amp(spec, nid, idx, dir) /* NOP */
576 #endif
577
578 static int patch_conexant_auto(struct hda_codec *codec);
579 /*
580  * EAPD control
581  * the private value = nid | (invert << 8)
582  */
583
584 #define cxt_eapd_info           snd_ctl_boolean_mono_info
585
586 static int cxt_eapd_get(struct snd_kcontrol *kcontrol,
587                              struct snd_ctl_elem_value *ucontrol)
588 {
589         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
590         struct conexant_spec *spec = codec->spec;
591         int invert = (kcontrol->private_value >> 8) & 1;
592         if (invert)
593                 ucontrol->value.integer.value[0] = !spec->cur_eapd;
594         else
595                 ucontrol->value.integer.value[0] = spec->cur_eapd;
596         return 0;
597
598 }
599
600 static int cxt_eapd_put(struct snd_kcontrol *kcontrol,
601                              struct snd_ctl_elem_value *ucontrol)
602 {
603         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
604         struct conexant_spec *spec = codec->spec;
605         int invert = (kcontrol->private_value >> 8) & 1;
606         hda_nid_t nid = kcontrol->private_value & 0xff;
607         unsigned int eapd;
608
609         eapd = !!ucontrol->value.integer.value[0];
610         if (invert)
611                 eapd = !eapd;
612         if (eapd == spec->cur_eapd)
613                 return 0;
614         
615         spec->cur_eapd = eapd;
616         snd_hda_codec_write_cache(codec, nid,
617                                   0, AC_VERB_SET_EAPD_BTLENABLE,
618                                   eapd ? 0x02 : 0x00);
619         return 1;
620 }
621
622 /* controls for test mode */
623 #ifdef CONFIG_SND_DEBUG
624
625 #define CXT_EAPD_SWITCH(xname, nid, mask) \
626         { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
627           .info = cxt_eapd_info, \
628           .get = cxt_eapd_get, \
629           .put = cxt_eapd_put, \
630           .private_value = nid | (mask<<16) }
631
632
633
634 static int conexant_ch_mode_info(struct snd_kcontrol *kcontrol,
635                                  struct snd_ctl_elem_info *uinfo)
636 {
637         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
638         struct conexant_spec *spec = codec->spec;
639         return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
640                                     spec->num_channel_mode);
641 }
642
643 static int conexant_ch_mode_get(struct snd_kcontrol *kcontrol,
644                                 struct snd_ctl_elem_value *ucontrol)
645 {
646         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
647         struct conexant_spec *spec = codec->spec;
648         return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
649                                    spec->num_channel_mode,
650                                    spec->multiout.max_channels);
651 }
652
653 static int conexant_ch_mode_put(struct snd_kcontrol *kcontrol,
654                                 struct snd_ctl_elem_value *ucontrol)
655 {
656         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
657         struct conexant_spec *spec = codec->spec;
658         int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
659                                       spec->num_channel_mode,
660                                       &spec->multiout.max_channels);
661         if (err >= 0 && spec->need_dac_fix)
662                 spec->multiout.num_dacs = spec->multiout.max_channels / 2;
663         return err;
664 }
665
666 #define CXT_PIN_MODE(xname, nid, dir) \
667         { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
668           .info = conexant_ch_mode_info, \
669           .get = conexant_ch_mode_get, \
670           .put = conexant_ch_mode_put, \
671           .private_value = nid | (dir<<16) }
672
673 #endif /* CONFIG_SND_DEBUG */
674
675 /* Conexant 5045 specific */
676
677 static const hda_nid_t cxt5045_dac_nids[1] = { 0x19 };
678 static const hda_nid_t cxt5045_adc_nids[1] = { 0x1a };
679 static const hda_nid_t cxt5045_capsrc_nids[1] = { 0x1a };
680 #define CXT5045_SPDIF_OUT       0x18
681
682 static const struct hda_channel_mode cxt5045_modes[1] = {
683         { 2, NULL },
684 };
685
686 static const struct hda_input_mux cxt5045_capture_source = {
687         .num_items = 2,
688         .items = {
689                 { "IntMic", 0x1 },
690                 { "ExtMic", 0x2 },
691         }
692 };
693
694 static const struct hda_input_mux cxt5045_capture_source_benq = {
695         .num_items = 5,
696         .items = {
697                 { "IntMic", 0x1 },
698                 { "ExtMic", 0x2 },
699                 { "LineIn", 0x3 },
700                 { "CD",     0x4 },
701                 { "Mixer",  0x0 },
702         }
703 };
704
705 static const struct hda_input_mux cxt5045_capture_source_hp530 = {
706         .num_items = 2,
707         .items = {
708                 { "ExtMic", 0x1 },
709                 { "IntMic", 0x2 },
710         }
711 };
712
713 /* turn on/off EAPD (+ mute HP) as a master switch */
714 static int cxt5045_hp_master_sw_put(struct snd_kcontrol *kcontrol,
715                                     struct snd_ctl_elem_value *ucontrol)
716 {
717         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
718         struct conexant_spec *spec = codec->spec;
719         unsigned int bits;
720
721         if (!cxt_eapd_put(kcontrol, ucontrol))
722                 return 0;
723
724         /* toggle internal speakers mute depending of presence of
725          * the headphone jack
726          */
727         bits = (!spec->hp_present && spec->cur_eapd) ? 0 : HDA_AMP_MUTE;
728         snd_hda_codec_amp_stereo(codec, 0x10, HDA_OUTPUT, 0,
729                                  HDA_AMP_MUTE, bits);
730
731         bits = spec->cur_eapd ? 0 : HDA_AMP_MUTE;
732         snd_hda_codec_amp_stereo(codec, 0x11, HDA_OUTPUT, 0,
733                                  HDA_AMP_MUTE, bits);
734         return 1;
735 }
736
737 /* bind volumes of both NID 0x10 and 0x11 */
738 static const struct hda_bind_ctls cxt5045_hp_bind_master_vol = {
739         .ops = &snd_hda_bind_vol,
740         .values = {
741                 HDA_COMPOSE_AMP_VAL(0x10, 3, 0, HDA_OUTPUT),
742                 HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT),
743                 0
744         },
745 };
746
747 /* toggle input of built-in and mic jack appropriately */
748 static void cxt5045_hp_automic(struct hda_codec *codec)
749 {
750         static const struct hda_verb mic_jack_on[] = {
751                 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
752                 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
753                 {}
754         };
755         static const struct hda_verb mic_jack_off[] = {
756                 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
757                 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
758                 {}
759         };
760         unsigned int present;
761
762         present = snd_hda_jack_detect(codec, 0x12);
763         if (present)
764                 snd_hda_sequence_write(codec, mic_jack_on);
765         else
766                 snd_hda_sequence_write(codec, mic_jack_off);
767 }
768
769
770 /* mute internal speaker if HP is plugged */
771 static void cxt5045_hp_automute(struct hda_codec *codec)
772 {
773         struct conexant_spec *spec = codec->spec;
774         unsigned int bits;
775
776         spec->hp_present = snd_hda_jack_detect(codec, 0x11);
777
778         bits = (spec->hp_present || !spec->cur_eapd) ? HDA_AMP_MUTE : 0; 
779         snd_hda_codec_amp_stereo(codec, 0x10, HDA_OUTPUT, 0,
780                                  HDA_AMP_MUTE, bits);
781 }
782
783 /* unsolicited event for HP jack sensing */
784 static void cxt5045_hp_unsol_event(struct hda_codec *codec,
785                                    unsigned int res)
786 {
787         res >>= 26;
788         switch (res) {
789         case CONEXANT_HP_EVENT:
790                 cxt5045_hp_automute(codec);
791                 break;
792         case CONEXANT_MIC_EVENT:
793                 cxt5045_hp_automic(codec);
794                 break;
795
796         }
797 }
798
799 static const struct snd_kcontrol_new cxt5045_mixers[] = {
800         HDA_CODEC_VOLUME("Internal Mic Capture Volume", 0x1a, 0x01, HDA_INPUT),
801         HDA_CODEC_MUTE("Internal Mic Capture Switch", 0x1a, 0x01, HDA_INPUT),
802         HDA_CODEC_VOLUME("Mic Capture Volume", 0x1a, 0x02, HDA_INPUT),
803         HDA_CODEC_MUTE("Mic Capture Switch", 0x1a, 0x02, HDA_INPUT),
804         HDA_CODEC_VOLUME("PCM Playback Volume", 0x17, 0x0, HDA_INPUT),
805         HDA_CODEC_MUTE("PCM Playback Switch", 0x17, 0x0, HDA_INPUT),
806         HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x17, 0x1, HDA_INPUT),
807         HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x17, 0x1, HDA_INPUT),
808         HDA_CODEC_VOLUME("Mic Playback Volume", 0x17, 0x2, HDA_INPUT),
809         HDA_CODEC_MUTE("Mic Playback Switch", 0x17, 0x2, HDA_INPUT),
810         HDA_BIND_VOL("Master Playback Volume", &cxt5045_hp_bind_master_vol),
811         {
812                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
813                 .name = "Master Playback Switch",
814                 .info = cxt_eapd_info,
815                 .get = cxt_eapd_get,
816                 .put = cxt5045_hp_master_sw_put,
817                 .private_value = 0x10,
818         },
819
820         {}
821 };
822
823 static const struct snd_kcontrol_new cxt5045_benq_mixers[] = {
824         HDA_CODEC_VOLUME("CD Capture Volume", 0x1a, 0x04, HDA_INPUT),
825         HDA_CODEC_MUTE("CD Capture Switch", 0x1a, 0x04, HDA_INPUT),
826         HDA_CODEC_VOLUME("CD Playback Volume", 0x17, 0x4, HDA_INPUT),
827         HDA_CODEC_MUTE("CD Playback Switch", 0x17, 0x4, HDA_INPUT),
828
829         HDA_CODEC_VOLUME("Line In Capture Volume", 0x1a, 0x03, HDA_INPUT),
830         HDA_CODEC_MUTE("Line In Capture Switch", 0x1a, 0x03, HDA_INPUT),
831         HDA_CODEC_VOLUME("Line In Playback Volume", 0x17, 0x3, HDA_INPUT),
832         HDA_CODEC_MUTE("Line In Playback Switch", 0x17, 0x3, HDA_INPUT),
833
834         HDA_CODEC_VOLUME("Mixer Capture Volume", 0x1a, 0x0, HDA_INPUT),
835         HDA_CODEC_MUTE("Mixer Capture Switch", 0x1a, 0x0, HDA_INPUT),
836
837         {}
838 };
839
840 static const struct snd_kcontrol_new cxt5045_mixers_hp530[] = {
841         HDA_CODEC_VOLUME("Internal Mic Capture Volume", 0x1a, 0x02, HDA_INPUT),
842         HDA_CODEC_MUTE("Internal Mic Capture Switch", 0x1a, 0x02, HDA_INPUT),
843         HDA_CODEC_VOLUME("Mic Capture Volume", 0x1a, 0x01, HDA_INPUT),
844         HDA_CODEC_MUTE("Mic Capture Switch", 0x1a, 0x01, HDA_INPUT),
845         HDA_CODEC_VOLUME("PCM Playback Volume", 0x17, 0x0, HDA_INPUT),
846         HDA_CODEC_MUTE("PCM Playback Switch", 0x17, 0x0, HDA_INPUT),
847         HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x17, 0x2, HDA_INPUT),
848         HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x17, 0x2, HDA_INPUT),
849         HDA_CODEC_VOLUME("Mic Playback Volume", 0x17, 0x1, HDA_INPUT),
850         HDA_CODEC_MUTE("Mic Playback Switch", 0x17, 0x1, HDA_INPUT),
851         HDA_BIND_VOL("Master Playback Volume", &cxt5045_hp_bind_master_vol),
852         {
853                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
854                 .name = "Master Playback Switch",
855                 .info = cxt_eapd_info,
856                 .get = cxt_eapd_get,
857                 .put = cxt5045_hp_master_sw_put,
858                 .private_value = 0x10,
859         },
860
861         {}
862 };
863
864 static const struct hda_verb cxt5045_init_verbs[] = {
865         /* Line in, Mic */
866         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_80 },
867         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_80 },
868         /* HP, Amp  */
869         {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
870         {0x10, AC_VERB_SET_CONNECT_SEL, 0x1},
871         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
872         {0x11, AC_VERB_SET_CONNECT_SEL, 0x1},
873         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
874         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
875         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
876         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
877         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
878         /* Record selector: Internal mic */
879         {0x1a, AC_VERB_SET_CONNECT_SEL,0x1},
880         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE,
881          AC_AMP_SET_INPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x17},
882         /* SPDIF route: PCM */
883         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
884         { 0x13, AC_VERB_SET_CONNECT_SEL, 0x0 },
885         /* EAPD */
886         {0x10, AC_VERB_SET_EAPD_BTLENABLE, 0x2 }, /* default on */ 
887         { } /* end */
888 };
889
890 static const struct hda_verb cxt5045_benq_init_verbs[] = {
891         /* Internal Mic, Mic */
892         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_80 },
893         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_80 },
894         /* Line In,HP, Amp  */
895         {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
896         {0x10, AC_VERB_SET_CONNECT_SEL, 0x1},
897         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
898         {0x11, AC_VERB_SET_CONNECT_SEL, 0x1},
899         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
900         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
901         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
902         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
903         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
904         /* Record selector: Internal mic */
905         {0x1a, AC_VERB_SET_CONNECT_SEL, 0x1},
906         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE,
907          AC_AMP_SET_INPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x17},
908         /* SPDIF route: PCM */
909         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
910         {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
911         /* EAPD */
912         {0x10, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
913         { } /* end */
914 };
915
916 static const struct hda_verb cxt5045_hp_sense_init_verbs[] = {
917         /* pin sensing on HP jack */
918         {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT},
919         { } /* end */
920 };
921
922 static const struct hda_verb cxt5045_mic_sense_init_verbs[] = {
923         /* pin sensing on HP jack */
924         {0x12, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT},
925         { } /* end */
926 };
927
928 #ifdef CONFIG_SND_DEBUG
929 /* Test configuration for debugging, modelled after the ALC260 test
930  * configuration.
931  */
932 static const struct hda_input_mux cxt5045_test_capture_source = {
933         .num_items = 5,
934         .items = {
935                 { "MIXER", 0x0 },
936                 { "MIC1 pin", 0x1 },
937                 { "LINE1 pin", 0x2 },
938                 { "HP-OUT pin", 0x3 },
939                 { "CD pin", 0x4 },
940         },
941 };
942
943 static const struct snd_kcontrol_new cxt5045_test_mixer[] = {
944
945         /* Output controls */
946         HDA_CODEC_VOLUME("Speaker Playback Volume", 0x10, 0x0, HDA_OUTPUT),
947         HDA_CODEC_MUTE("Speaker Playback Switch", 0x10, 0x0, HDA_OUTPUT),
948         HDA_CODEC_VOLUME("Node 11 Playback Volume", 0x11, 0x0, HDA_OUTPUT),
949         HDA_CODEC_MUTE("Node 11 Playback Switch", 0x11, 0x0, HDA_OUTPUT),
950         HDA_CODEC_VOLUME("Node 12 Playback Volume", 0x12, 0x0, HDA_OUTPUT),
951         HDA_CODEC_MUTE("Node 12 Playback Switch", 0x12, 0x0, HDA_OUTPUT),
952         
953         /* Modes for retasking pin widgets */
954         CXT_PIN_MODE("HP-OUT pin mode", 0x11, CXT_PIN_DIR_INOUT),
955         CXT_PIN_MODE("LINE1 pin mode", 0x12, CXT_PIN_DIR_INOUT),
956
957         /* EAPD Switch Control */
958         CXT_EAPD_SWITCH("External Amplifier", 0x10, 0x0),
959
960         /* Loopback mixer controls */
961
962         HDA_CODEC_VOLUME("Mixer-1 Volume", 0x17, 0x0, HDA_INPUT),
963         HDA_CODEC_MUTE("Mixer-1 Switch", 0x17, 0x0, HDA_INPUT),
964         HDA_CODEC_VOLUME("Mixer-2 Volume", 0x17, 0x1, HDA_INPUT),
965         HDA_CODEC_MUTE("Mixer-2 Switch", 0x17, 0x1, HDA_INPUT),
966         HDA_CODEC_VOLUME("Mixer-3 Volume", 0x17, 0x2, HDA_INPUT),
967         HDA_CODEC_MUTE("Mixer-3 Switch", 0x17, 0x2, HDA_INPUT),
968         HDA_CODEC_VOLUME("Mixer-4 Volume", 0x17, 0x3, HDA_INPUT),
969         HDA_CODEC_MUTE("Mixer-4 Switch", 0x17, 0x3, HDA_INPUT),
970         HDA_CODEC_VOLUME("Mixer-5 Volume", 0x17, 0x4, HDA_INPUT),
971         HDA_CODEC_MUTE("Mixer-5 Switch", 0x17, 0x4, HDA_INPUT),
972         {
973                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
974                 .name = "Input Source",
975                 .info = conexant_mux_enum_info,
976                 .get = conexant_mux_enum_get,
977                 .put = conexant_mux_enum_put,
978         },
979         /* Audio input controls */
980         HDA_CODEC_VOLUME("Input-1 Volume", 0x1a, 0x0, HDA_INPUT),
981         HDA_CODEC_MUTE("Input-1 Switch", 0x1a, 0x0, HDA_INPUT),
982         HDA_CODEC_VOLUME("Input-2 Volume", 0x1a, 0x1, HDA_INPUT),
983         HDA_CODEC_MUTE("Input-2 Switch", 0x1a, 0x1, HDA_INPUT),
984         HDA_CODEC_VOLUME("Input-3 Volume", 0x1a, 0x2, HDA_INPUT),
985         HDA_CODEC_MUTE("Input-3 Switch", 0x1a, 0x2, HDA_INPUT),
986         HDA_CODEC_VOLUME("Input-4 Volume", 0x1a, 0x3, HDA_INPUT),
987         HDA_CODEC_MUTE("Input-4 Switch", 0x1a, 0x3, HDA_INPUT),
988         HDA_CODEC_VOLUME("Input-5 Volume", 0x1a, 0x4, HDA_INPUT),
989         HDA_CODEC_MUTE("Input-5 Switch", 0x1a, 0x4, HDA_INPUT),
990         { } /* end */
991 };
992
993 static const struct hda_verb cxt5045_test_init_verbs[] = {
994         /* Set connections */
995         { 0x10, AC_VERB_SET_CONNECT_SEL, 0x0 },
996         { 0x11, AC_VERB_SET_CONNECT_SEL, 0x0 },
997         { 0x12, AC_VERB_SET_CONNECT_SEL, 0x0 },
998         /* Enable retasking pins as output, initially without power amp */
999         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1000         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1001
1002         /* Disable digital (SPDIF) pins initially, but users can enable
1003          * them via a mixer switch.  In the case of SPDIF-out, this initverb
1004          * payload also sets the generation to 0, output to be in "consumer"
1005          * PCM format, copyright asserted, no pre-emphasis and no validity
1006          * control.
1007          */
1008         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1009         {0x18, AC_VERB_SET_DIGI_CONVERT_1, 0},
1010
1011         /* Start with output sum widgets muted and their output gains at min */
1012         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1013         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1014
1015         /* Unmute retasking pin widget output buffers since the default
1016          * state appears to be output.  As the pin mode is changed by the
1017          * user the pin mode control will take care of enabling the pin's
1018          * input/output buffers as needed.
1019          */
1020         {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1021         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1022
1023         /* Mute capture amp left and right */
1024         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1025
1026         /* Set ADC connection select to match default mixer setting (mic1
1027          * pin)
1028          */
1029         {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
1030         {0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
1031
1032         /* Mute all inputs to mixer widget (even unconnected ones) */
1033         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* Mixer pin */
1034         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* Mic1 pin */
1035         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* Line pin */
1036         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* HP pin */
1037         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
1038
1039         { }
1040 };
1041 #endif
1042
1043
1044 /* initialize jack-sensing, too */
1045 static int cxt5045_init(struct hda_codec *codec)
1046 {
1047         conexant_init(codec);
1048         cxt5045_hp_automute(codec);
1049         return 0;
1050 }
1051
1052
1053 enum {
1054         CXT5045_LAPTOP_HPSENSE,
1055         CXT5045_LAPTOP_MICSENSE,
1056         CXT5045_LAPTOP_HPMICSENSE,
1057         CXT5045_BENQ,
1058         CXT5045_LAPTOP_HP530,
1059 #ifdef CONFIG_SND_DEBUG
1060         CXT5045_TEST,
1061 #endif
1062         CXT5045_MODELS
1063 };
1064
1065 static const char * const cxt5045_models[CXT5045_MODELS] = {
1066         [CXT5045_LAPTOP_HPSENSE]        = "laptop-hpsense",
1067         [CXT5045_LAPTOP_MICSENSE]       = "laptop-micsense",
1068         [CXT5045_LAPTOP_HPMICSENSE]     = "laptop-hpmicsense",
1069         [CXT5045_BENQ]                  = "benq",
1070         [CXT5045_LAPTOP_HP530]          = "laptop-hp530",
1071 #ifdef CONFIG_SND_DEBUG
1072         [CXT5045_TEST]          = "test",
1073 #endif
1074 };
1075
1076 static const struct snd_pci_quirk cxt5045_cfg_tbl[] = {
1077         SND_PCI_QUIRK(0x103c, 0x30d5, "HP 530", CXT5045_LAPTOP_HP530),
1078         SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3000, "HP DV Series",
1079                            CXT5045_LAPTOP_HPSENSE),
1080         SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba P105", CXT5045_LAPTOP_MICSENSE),
1081         SND_PCI_QUIRK(0x152d, 0x0753, "Benq R55E", CXT5045_BENQ),
1082         SND_PCI_QUIRK(0x1734, 0x10ad, "Fujitsu Si1520", CXT5045_LAPTOP_MICSENSE),
1083         SND_PCI_QUIRK(0x1734, 0x10cb, "Fujitsu Si3515", CXT5045_LAPTOP_HPMICSENSE),
1084         SND_PCI_QUIRK(0x1734, 0x110e, "Fujitsu V5505",
1085                       CXT5045_LAPTOP_HPMICSENSE),
1086         SND_PCI_QUIRK(0x1509, 0x1e40, "FIC", CXT5045_LAPTOP_HPMICSENSE),
1087         SND_PCI_QUIRK(0x1509, 0x2f05, "FIC", CXT5045_LAPTOP_HPMICSENSE),
1088         SND_PCI_QUIRK(0x1509, 0x2f06, "FIC", CXT5045_LAPTOP_HPMICSENSE),
1089         SND_PCI_QUIRK_MASK(0x1631, 0xff00, 0xc100, "Packard Bell",
1090                            CXT5045_LAPTOP_HPMICSENSE),
1091         SND_PCI_QUIRK(0x8086, 0x2111, "Conexant Reference board", CXT5045_LAPTOP_HPSENSE),
1092         {}
1093 };
1094
1095 static int patch_cxt5045(struct hda_codec *codec)
1096 {
1097         struct conexant_spec *spec;
1098         int board_config;
1099
1100         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1101         if (!spec)
1102                 return -ENOMEM;
1103         codec->spec = spec;
1104         codec->pin_amp_workaround = 1;
1105
1106         spec->multiout.max_channels = 2;
1107         spec->multiout.num_dacs = ARRAY_SIZE(cxt5045_dac_nids);
1108         spec->multiout.dac_nids = cxt5045_dac_nids;
1109         spec->multiout.dig_out_nid = CXT5045_SPDIF_OUT;
1110         spec->num_adc_nids = 1;
1111         spec->adc_nids = cxt5045_adc_nids;
1112         spec->capsrc_nids = cxt5045_capsrc_nids;
1113         spec->input_mux = &cxt5045_capture_source;
1114         spec->num_mixers = 1;
1115         spec->mixers[0] = cxt5045_mixers;
1116         spec->num_init_verbs = 1;
1117         spec->init_verbs[0] = cxt5045_init_verbs;
1118         spec->spdif_route = 0;
1119         spec->num_channel_mode = ARRAY_SIZE(cxt5045_modes);
1120         spec->channel_mode = cxt5045_modes;
1121
1122         set_beep_amp(spec, 0x16, 0, 1);
1123
1124         codec->patch_ops = conexant_patch_ops;
1125
1126         board_config = snd_hda_check_board_config(codec, CXT5045_MODELS,
1127                                                   cxt5045_models,
1128                                                   cxt5045_cfg_tbl);
1129         switch (board_config) {
1130         case CXT5045_LAPTOP_HPSENSE:
1131                 codec->patch_ops.unsol_event = cxt5045_hp_unsol_event;
1132                 spec->input_mux = &cxt5045_capture_source;
1133                 spec->num_init_verbs = 2;
1134                 spec->init_verbs[1] = cxt5045_hp_sense_init_verbs;
1135                 spec->mixers[0] = cxt5045_mixers;
1136                 codec->patch_ops.init = cxt5045_init;
1137                 break;
1138         case CXT5045_LAPTOP_MICSENSE:
1139                 codec->patch_ops.unsol_event = cxt5045_hp_unsol_event;
1140                 spec->input_mux = &cxt5045_capture_source;
1141                 spec->num_init_verbs = 2;
1142                 spec->init_verbs[1] = cxt5045_mic_sense_init_verbs;
1143                 spec->mixers[0] = cxt5045_mixers;
1144                 codec->patch_ops.init = cxt5045_init;
1145                 break;
1146         default:
1147         case CXT5045_LAPTOP_HPMICSENSE:
1148                 codec->patch_ops.unsol_event = cxt5045_hp_unsol_event;
1149                 spec->input_mux = &cxt5045_capture_source;
1150                 spec->num_init_verbs = 3;
1151                 spec->init_verbs[1] = cxt5045_hp_sense_init_verbs;
1152                 spec->init_verbs[2] = cxt5045_mic_sense_init_verbs;
1153                 spec->mixers[0] = cxt5045_mixers;
1154                 codec->patch_ops.init = cxt5045_init;
1155                 break;
1156         case CXT5045_BENQ:
1157                 codec->patch_ops.unsol_event = cxt5045_hp_unsol_event;
1158                 spec->input_mux = &cxt5045_capture_source_benq;
1159                 spec->num_init_verbs = 1;
1160                 spec->init_verbs[0] = cxt5045_benq_init_verbs;
1161                 spec->mixers[0] = cxt5045_mixers;
1162                 spec->mixers[1] = cxt5045_benq_mixers;
1163                 spec->num_mixers = 2;
1164                 codec->patch_ops.init = cxt5045_init;
1165                 break;
1166         case CXT5045_LAPTOP_HP530:
1167                 codec->patch_ops.unsol_event = cxt5045_hp_unsol_event;
1168                 spec->input_mux = &cxt5045_capture_source_hp530;
1169                 spec->num_init_verbs = 2;
1170                 spec->init_verbs[1] = cxt5045_hp_sense_init_verbs;
1171                 spec->mixers[0] = cxt5045_mixers_hp530;
1172                 codec->patch_ops.init = cxt5045_init;
1173                 break;
1174 #ifdef CONFIG_SND_DEBUG
1175         case CXT5045_TEST:
1176                 spec->input_mux = &cxt5045_test_capture_source;
1177                 spec->mixers[0] = cxt5045_test_mixer;
1178                 spec->init_verbs[0] = cxt5045_test_init_verbs;
1179                 break;
1180                 
1181 #endif  
1182         }
1183
1184         switch (codec->subsystem_id >> 16) {
1185         case 0x103c:
1186         case 0x1631:
1187         case 0x1734:
1188         case 0x17aa:
1189                 /* HP, Packard Bell, Fujitsu-Siemens & Lenovo laptops have
1190                  * really bad sound over 0dB on NID 0x17. Fix max PCM level to
1191                  * 0 dB (originally it has 0x2b steps with 0dB offset 0x14)
1192                  */
1193                 snd_hda_override_amp_caps(codec, 0x17, HDA_INPUT,
1194                                           (0x14 << AC_AMPCAP_OFFSET_SHIFT) |
1195                                           (0x14 << AC_AMPCAP_NUM_STEPS_SHIFT) |
1196                                           (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) |
1197                                           (1 << AC_AMPCAP_MUTE_SHIFT));
1198                 break;
1199         }
1200
1201         if (spec->beep_amp)
1202                 snd_hda_attach_beep_device(codec, spec->beep_amp);
1203
1204         return 0;
1205 }
1206
1207
1208 /* Conexant 5047 specific */
1209 #define CXT5047_SPDIF_OUT       0x11
1210
1211 static const hda_nid_t cxt5047_dac_nids[1] = { 0x10 }; /* 0x1c */
1212 static const hda_nid_t cxt5047_adc_nids[1] = { 0x12 };
1213 static const hda_nid_t cxt5047_capsrc_nids[1] = { 0x1a };
1214
1215 static const struct hda_channel_mode cxt5047_modes[1] = {
1216         { 2, NULL },
1217 };
1218
1219 static const struct hda_input_mux cxt5047_toshiba_capture_source = {
1220         .num_items = 2,
1221         .items = {
1222                 { "ExtMic", 0x2 },
1223                 { "Line-In", 0x1 },
1224         }
1225 };
1226
1227 /* turn on/off EAPD (+ mute HP) as a master switch */
1228 static int cxt5047_hp_master_sw_put(struct snd_kcontrol *kcontrol,
1229                                     struct snd_ctl_elem_value *ucontrol)
1230 {
1231         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1232         struct conexant_spec *spec = codec->spec;
1233         unsigned int bits;
1234
1235         if (!cxt_eapd_put(kcontrol, ucontrol))
1236                 return 0;
1237
1238         /* toggle internal speakers mute depending of presence of
1239          * the headphone jack
1240          */
1241         bits = (!spec->hp_present && spec->cur_eapd) ? 0 : HDA_AMP_MUTE;
1242         /* NOTE: Conexat codec needs the index for *OUTPUT* amp of
1243          * pin widgets unlike other codecs.  In this case, we need to
1244          * set index 0x01 for the volume from the mixer amp 0x19.
1245          */
1246         snd_hda_codec_amp_stereo(codec, 0x1d, HDA_OUTPUT, 0x01,
1247                                  HDA_AMP_MUTE, bits);
1248         bits = spec->cur_eapd ? 0 : HDA_AMP_MUTE;
1249         snd_hda_codec_amp_stereo(codec, 0x13, HDA_OUTPUT, 0,
1250                                  HDA_AMP_MUTE, bits);
1251         return 1;
1252 }
1253
1254 /* mute internal speaker if HP is plugged */
1255 static void cxt5047_hp_automute(struct hda_codec *codec)
1256 {
1257         struct conexant_spec *spec = codec->spec;
1258         unsigned int bits;
1259
1260         spec->hp_present = snd_hda_jack_detect(codec, 0x13);
1261
1262         bits = (spec->hp_present || !spec->cur_eapd) ? HDA_AMP_MUTE : 0;
1263         /* See the note in cxt5047_hp_master_sw_put */
1264         snd_hda_codec_amp_stereo(codec, 0x1d, HDA_OUTPUT, 0x01,
1265                                  HDA_AMP_MUTE, bits);
1266 }
1267
1268 /* toggle input of built-in and mic jack appropriately */
1269 static void cxt5047_hp_automic(struct hda_codec *codec)
1270 {
1271         static const struct hda_verb mic_jack_on[] = {
1272                 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1273                 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1274                 {}
1275         };
1276         static const struct hda_verb mic_jack_off[] = {
1277                 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1278                 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1279                 {}
1280         };
1281         unsigned int present;
1282
1283         present = snd_hda_jack_detect(codec, 0x15);
1284         if (present)
1285                 snd_hda_sequence_write(codec, mic_jack_on);
1286         else
1287                 snd_hda_sequence_write(codec, mic_jack_off);
1288 }
1289
1290 /* unsolicited event for HP jack sensing */
1291 static void cxt5047_hp_unsol_event(struct hda_codec *codec,
1292                                   unsigned int res)
1293 {
1294         switch (res >> 26) {
1295         case CONEXANT_HP_EVENT:
1296                 cxt5047_hp_automute(codec);
1297                 break;
1298         case CONEXANT_MIC_EVENT:
1299                 cxt5047_hp_automic(codec);
1300                 break;
1301         }
1302 }
1303
1304 static const struct snd_kcontrol_new cxt5047_base_mixers[] = {
1305         HDA_CODEC_VOLUME("Mic Playback Volume", 0x19, 0x02, HDA_INPUT),
1306         HDA_CODEC_MUTE("Mic Playback Switch", 0x19, 0x02, HDA_INPUT),
1307         HDA_CODEC_VOLUME("Mic Boost Volume", 0x1a, 0x0, HDA_OUTPUT),
1308         HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x03, HDA_INPUT),
1309         HDA_CODEC_MUTE("Capture Switch", 0x12, 0x03, HDA_INPUT),
1310         HDA_CODEC_VOLUME("PCM Volume", 0x10, 0x00, HDA_OUTPUT),
1311         HDA_CODEC_MUTE("PCM Switch", 0x10, 0x00, HDA_OUTPUT),
1312         {
1313                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1314                 .name = "Master Playback Switch",
1315                 .info = cxt_eapd_info,
1316                 .get = cxt_eapd_get,
1317                 .put = cxt5047_hp_master_sw_put,
1318                 .private_value = 0x13,
1319         },
1320
1321         {}
1322 };
1323
1324 static const struct snd_kcontrol_new cxt5047_hp_spk_mixers[] = {
1325         /* See the note in cxt5047_hp_master_sw_put */
1326         HDA_CODEC_VOLUME("Speaker Playback Volume", 0x1d, 0x01, HDA_OUTPUT),
1327         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x13, 0x00, HDA_OUTPUT),
1328         {}
1329 };
1330
1331 static const struct snd_kcontrol_new cxt5047_hp_only_mixers[] = {
1332         HDA_CODEC_VOLUME("Master Playback Volume", 0x13, 0x00, HDA_OUTPUT),
1333         { } /* end */
1334 };
1335
1336 static const struct hda_verb cxt5047_init_verbs[] = {
1337         /* Line in, Mic, Built-in Mic */
1338         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1339         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_50 },
1340         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_50 },
1341         /* HP, Speaker  */
1342         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
1343         {0x13, AC_VERB_SET_CONNECT_SEL, 0x0}, /* mixer(0x19) */
1344         {0x1d, AC_VERB_SET_CONNECT_SEL, 0x1}, /* mixer(0x19) */
1345         /* Record selector: Mic */
1346         {0x12, AC_VERB_SET_CONNECT_SEL,0x03},
1347         {0x19, AC_VERB_SET_AMP_GAIN_MUTE,
1348          AC_AMP_SET_INPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x17},
1349         {0x1A, AC_VERB_SET_CONNECT_SEL,0x02},
1350         {0x1A, AC_VERB_SET_AMP_GAIN_MUTE,
1351          AC_AMP_SET_OUTPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x00},
1352         {0x1A, AC_VERB_SET_AMP_GAIN_MUTE,
1353          AC_AMP_SET_OUTPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x03},
1354         /* SPDIF route: PCM */
1355         { 0x18, AC_VERB_SET_CONNECT_SEL, 0x0 },
1356         /* Enable unsolicited events */
1357         {0x13, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT},
1358         {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT},
1359         { } /* end */
1360 };
1361
1362 /* configuration for Toshiba Laptops */
1363 static const struct hda_verb cxt5047_toshiba_init_verbs[] = {
1364         {0x13, AC_VERB_SET_EAPD_BTLENABLE, 0x0}, /* default off */
1365         {}
1366 };
1367
1368 /* Test configuration for debugging, modelled after the ALC260 test
1369  * configuration.
1370  */
1371 #ifdef CONFIG_SND_DEBUG
1372 static const struct hda_input_mux cxt5047_test_capture_source = {
1373         .num_items = 4,
1374         .items = {
1375                 { "LINE1 pin", 0x0 },
1376                 { "MIC1 pin", 0x1 },
1377                 { "MIC2 pin", 0x2 },
1378                 { "CD pin", 0x3 },
1379         },
1380 };
1381
1382 static const struct snd_kcontrol_new cxt5047_test_mixer[] = {
1383
1384         /* Output only controls */
1385         HDA_CODEC_VOLUME("OutAmp-1 Volume", 0x10, 0x0, HDA_OUTPUT),
1386         HDA_CODEC_MUTE("OutAmp-1 Switch", 0x10,0x0, HDA_OUTPUT),
1387         HDA_CODEC_VOLUME("OutAmp-2 Volume", 0x1c, 0x0, HDA_OUTPUT),
1388         HDA_CODEC_MUTE("OutAmp-2 Switch", 0x1c, 0x0, HDA_OUTPUT),
1389         HDA_CODEC_VOLUME("Speaker Playback Volume", 0x1d, 0x0, HDA_OUTPUT),
1390         HDA_CODEC_MUTE("Speaker Playback Switch", 0x1d, 0x0, HDA_OUTPUT),
1391         HDA_CODEC_VOLUME("HeadPhone Playback Volume", 0x13, 0x0, HDA_OUTPUT),
1392         HDA_CODEC_MUTE("HeadPhone Playback Switch", 0x13, 0x0, HDA_OUTPUT),
1393         HDA_CODEC_VOLUME("Line1-Out Playback Volume", 0x14, 0x0, HDA_OUTPUT),
1394         HDA_CODEC_MUTE("Line1-Out Playback Switch", 0x14, 0x0, HDA_OUTPUT),
1395         HDA_CODEC_VOLUME("Line2-Out Playback Volume", 0x15, 0x0, HDA_OUTPUT),
1396         HDA_CODEC_MUTE("Line2-Out Playback Switch", 0x15, 0x0, HDA_OUTPUT),
1397
1398         /* Modes for retasking pin widgets */
1399         CXT_PIN_MODE("LINE1 pin mode", 0x14, CXT_PIN_DIR_INOUT),
1400         CXT_PIN_MODE("MIC1 pin mode", 0x15, CXT_PIN_DIR_INOUT),
1401
1402         /* EAPD Switch Control */
1403         CXT_EAPD_SWITCH("External Amplifier", 0x13, 0x0),
1404
1405         /* Loopback mixer controls */
1406         HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x12, 0x01, HDA_INPUT),
1407         HDA_CODEC_MUTE("MIC1 Playback Switch", 0x12, 0x01, HDA_INPUT),
1408         HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x12, 0x02, HDA_INPUT),
1409         HDA_CODEC_MUTE("MIC2 Playback Switch", 0x12, 0x02, HDA_INPUT),
1410         HDA_CODEC_VOLUME("LINE Playback Volume", 0x12, 0x0, HDA_INPUT),
1411         HDA_CODEC_MUTE("LINE Playback Switch", 0x12, 0x0, HDA_INPUT),
1412         HDA_CODEC_VOLUME("CD Playback Volume", 0x12, 0x04, HDA_INPUT),
1413         HDA_CODEC_MUTE("CD Playback Switch", 0x12, 0x04, HDA_INPUT),
1414
1415         HDA_CODEC_VOLUME("Capture-1 Volume", 0x19, 0x0, HDA_INPUT),
1416         HDA_CODEC_MUTE("Capture-1 Switch", 0x19, 0x0, HDA_INPUT),
1417         HDA_CODEC_VOLUME("Capture-2 Volume", 0x19, 0x1, HDA_INPUT),
1418         HDA_CODEC_MUTE("Capture-2 Switch", 0x19, 0x1, HDA_INPUT),
1419         HDA_CODEC_VOLUME("Capture-3 Volume", 0x19, 0x2, HDA_INPUT),
1420         HDA_CODEC_MUTE("Capture-3 Switch", 0x19, 0x2, HDA_INPUT),
1421         HDA_CODEC_VOLUME("Capture-4 Volume", 0x19, 0x3, HDA_INPUT),
1422         HDA_CODEC_MUTE("Capture-4 Switch", 0x19, 0x3, HDA_INPUT),
1423         {
1424                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1425                 .name = "Input Source",
1426                 .info = conexant_mux_enum_info,
1427                 .get = conexant_mux_enum_get,
1428                 .put = conexant_mux_enum_put,
1429         },
1430         HDA_CODEC_VOLUME("Mic Boost Volume", 0x1a, 0x0, HDA_OUTPUT),
1431
1432         { } /* end */
1433 };
1434
1435 static const struct hda_verb cxt5047_test_init_verbs[] = {
1436         /* Enable retasking pins as output, initially without power amp */
1437         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1438         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1439         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1440
1441         /* Disable digital (SPDIF) pins initially, but users can enable
1442          * them via a mixer switch.  In the case of SPDIF-out, this initverb
1443          * payload also sets the generation to 0, output to be in "consumer"
1444          * PCM format, copyright asserted, no pre-emphasis and no validity
1445          * control.
1446          */
1447         {0x18, AC_VERB_SET_DIGI_CONVERT_1, 0},
1448
1449         /* Ensure mic1, mic2, line1 pin widgets take input from the 
1450          * OUT1 sum bus when acting as an output.
1451          */
1452         {0x1a, AC_VERB_SET_CONNECT_SEL, 0},
1453         {0x1b, AC_VERB_SET_CONNECT_SEL, 0},
1454
1455         /* Start with output sum widgets muted and their output gains at min */
1456         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1457         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1458
1459         /* Unmute retasking pin widget output buffers since the default
1460          * state appears to be output.  As the pin mode is changed by the
1461          * user the pin mode control will take care of enabling the pin's
1462          * input/output buffers as needed.
1463          */
1464         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1465         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1466         {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1467
1468         /* Mute capture amp left and right */
1469         {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1470
1471         /* Set ADC connection select to match default mixer setting (mic1
1472          * pin)
1473          */
1474         {0x12, AC_VERB_SET_CONNECT_SEL, 0x00},
1475
1476         /* Mute all inputs to mixer widget (even unconnected ones) */
1477         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
1478         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
1479         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
1480         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
1481         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
1482         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
1483         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
1484         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
1485
1486         { }
1487 };
1488 #endif
1489
1490
1491 /* initialize jack-sensing, too */
1492 static int cxt5047_hp_init(struct hda_codec *codec)
1493 {
1494         conexant_init(codec);
1495         cxt5047_hp_automute(codec);
1496         return 0;
1497 }
1498
1499
1500 enum {
1501         CXT5047_LAPTOP,         /* Laptops w/o EAPD support */
1502         CXT5047_LAPTOP_HP,      /* Some HP laptops */
1503         CXT5047_LAPTOP_EAPD,    /* Laptops with EAPD support */
1504 #ifdef CONFIG_SND_DEBUG
1505         CXT5047_TEST,
1506 #endif
1507         CXT5047_MODELS
1508 };
1509
1510 static const char * const cxt5047_models[CXT5047_MODELS] = {
1511         [CXT5047_LAPTOP]        = "laptop",
1512         [CXT5047_LAPTOP_HP]     = "laptop-hp",
1513         [CXT5047_LAPTOP_EAPD]   = "laptop-eapd",
1514 #ifdef CONFIG_SND_DEBUG
1515         [CXT5047_TEST]          = "test",
1516 #endif
1517 };
1518
1519 static const struct snd_pci_quirk cxt5047_cfg_tbl[] = {
1520         SND_PCI_QUIRK(0x103c, 0x30a5, "HP DV5200T/DV8000T", CXT5047_LAPTOP_HP),
1521         SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3000, "HP DV Series",
1522                            CXT5047_LAPTOP),
1523         SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba P100", CXT5047_LAPTOP_EAPD),
1524         {}
1525 };
1526
1527 static int patch_cxt5047(struct hda_codec *codec)
1528 {
1529         struct conexant_spec *spec;
1530         int board_config;
1531
1532         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1533         if (!spec)
1534                 return -ENOMEM;
1535         codec->spec = spec;
1536         codec->pin_amp_workaround = 1;
1537
1538         spec->multiout.max_channels = 2;
1539         spec->multiout.num_dacs = ARRAY_SIZE(cxt5047_dac_nids);
1540         spec->multiout.dac_nids = cxt5047_dac_nids;
1541         spec->multiout.dig_out_nid = CXT5047_SPDIF_OUT;
1542         spec->num_adc_nids = 1;
1543         spec->adc_nids = cxt5047_adc_nids;
1544         spec->capsrc_nids = cxt5047_capsrc_nids;
1545         spec->num_mixers = 1;
1546         spec->mixers[0] = cxt5047_base_mixers;
1547         spec->num_init_verbs = 1;
1548         spec->init_verbs[0] = cxt5047_init_verbs;
1549         spec->spdif_route = 0;
1550         spec->num_channel_mode = ARRAY_SIZE(cxt5047_modes),
1551         spec->channel_mode = cxt5047_modes,
1552
1553         codec->patch_ops = conexant_patch_ops;
1554
1555         board_config = snd_hda_check_board_config(codec, CXT5047_MODELS,
1556                                                   cxt5047_models,
1557                                                   cxt5047_cfg_tbl);
1558         switch (board_config) {
1559         case CXT5047_LAPTOP:
1560                 spec->num_mixers = 2;
1561                 spec->mixers[1] = cxt5047_hp_spk_mixers;
1562                 codec->patch_ops.unsol_event = cxt5047_hp_unsol_event;
1563                 break;
1564         case CXT5047_LAPTOP_HP:
1565                 spec->num_mixers = 2;
1566                 spec->mixers[1] = cxt5047_hp_only_mixers;
1567                 codec->patch_ops.unsol_event = cxt5047_hp_unsol_event;
1568                 codec->patch_ops.init = cxt5047_hp_init;
1569                 break;
1570         case CXT5047_LAPTOP_EAPD:
1571                 spec->input_mux = &cxt5047_toshiba_capture_source;
1572                 spec->num_mixers = 2;
1573                 spec->mixers[1] = cxt5047_hp_spk_mixers;
1574                 spec->num_init_verbs = 2;
1575                 spec->init_verbs[1] = cxt5047_toshiba_init_verbs;
1576                 codec->patch_ops.unsol_event = cxt5047_hp_unsol_event;
1577                 break;
1578 #ifdef CONFIG_SND_DEBUG
1579         case CXT5047_TEST:
1580                 spec->input_mux = &cxt5047_test_capture_source;
1581                 spec->mixers[0] = cxt5047_test_mixer;
1582                 spec->init_verbs[0] = cxt5047_test_init_verbs;
1583                 codec->patch_ops.unsol_event = cxt5047_hp_unsol_event;
1584 #endif  
1585         }
1586         spec->vmaster_nid = 0x13;
1587
1588         switch (codec->subsystem_id >> 16) {
1589         case 0x103c:
1590                 /* HP laptops have really bad sound over 0 dB on NID 0x10.
1591                  * Fix max PCM level to 0 dB (originally it has 0x1e steps
1592                  * with 0 dB offset 0x17)
1593                  */
1594                 snd_hda_override_amp_caps(codec, 0x10, HDA_INPUT,
1595                                           (0x17 << AC_AMPCAP_OFFSET_SHIFT) |
1596                                           (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) |
1597                                           (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) |
1598                                           (1 << AC_AMPCAP_MUTE_SHIFT));
1599                 break;
1600         }
1601
1602         return 0;
1603 }
1604
1605 /* Conexant 5051 specific */
1606 static const hda_nid_t cxt5051_dac_nids[1] = { 0x10 };
1607 static const hda_nid_t cxt5051_adc_nids[2] = { 0x14, 0x15 };
1608
1609 static const struct hda_channel_mode cxt5051_modes[1] = {
1610         { 2, NULL },
1611 };
1612
1613 static void cxt5051_update_speaker(struct hda_codec *codec)
1614 {
1615         struct conexant_spec *spec = codec->spec;
1616         unsigned int pinctl;
1617         /* headphone pin */
1618         pinctl = (spec->hp_present && spec->cur_eapd) ? PIN_HP : 0;
1619         snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
1620                             pinctl);
1621         /* speaker pin */
1622         pinctl = (!spec->hp_present && spec->cur_eapd) ? PIN_OUT : 0;
1623         snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
1624                             pinctl);
1625         /* on ideapad there is an aditional speaker (subwoofer) to mute */
1626         if (spec->ideapad)
1627                 snd_hda_codec_write(codec, 0x1b, 0,
1628                                     AC_VERB_SET_PIN_WIDGET_CONTROL,
1629                                     pinctl);
1630 }
1631
1632 /* turn on/off EAPD (+ mute HP) as a master switch */
1633 static int cxt5051_hp_master_sw_put(struct snd_kcontrol *kcontrol,
1634                                     struct snd_ctl_elem_value *ucontrol)
1635 {
1636         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1637
1638         if (!cxt_eapd_put(kcontrol, ucontrol))
1639                 return 0;
1640         cxt5051_update_speaker(codec);
1641         return 1;
1642 }
1643
1644 /* toggle input of built-in and mic jack appropriately */
1645 static void cxt5051_portb_automic(struct hda_codec *codec)
1646 {
1647         struct conexant_spec *spec = codec->spec;
1648         unsigned int present;
1649
1650         if (!(spec->auto_mic & AUTO_MIC_PORTB))
1651                 return;
1652         present = snd_hda_jack_detect(codec, 0x17);
1653         snd_hda_codec_write(codec, 0x14, 0,
1654                             AC_VERB_SET_CONNECT_SEL,
1655                             present ? 0x01 : 0x00);
1656 }
1657
1658 /* switch the current ADC according to the jack state */
1659 static void cxt5051_portc_automic(struct hda_codec *codec)
1660 {
1661         struct conexant_spec *spec = codec->spec;
1662         unsigned int present;
1663         hda_nid_t new_adc;
1664
1665         if (!(spec->auto_mic & AUTO_MIC_PORTC))
1666                 return;
1667         present = snd_hda_jack_detect(codec, 0x18);
1668         if (present)
1669                 spec->cur_adc_idx = 1;
1670         else
1671                 spec->cur_adc_idx = 0;
1672         new_adc = spec->adc_nids[spec->cur_adc_idx];
1673         if (spec->cur_adc && spec->cur_adc != new_adc) {
1674                 /* stream is running, let's swap the current ADC */
1675                 __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1);
1676                 spec->cur_adc = new_adc;
1677                 snd_hda_codec_setup_stream(codec, new_adc,
1678                                            spec->cur_adc_stream_tag, 0,
1679                                            spec->cur_adc_format);
1680         }
1681 }
1682
1683 /* mute internal speaker if HP is plugged */
1684 static void cxt5051_hp_automute(struct hda_codec *codec)
1685 {
1686         struct conexant_spec *spec = codec->spec;
1687
1688         spec->hp_present = snd_hda_jack_detect(codec, 0x16);
1689         cxt5051_update_speaker(codec);
1690 }
1691
1692 /* unsolicited event for HP jack sensing */
1693 static void cxt5051_hp_unsol_event(struct hda_codec *codec,
1694                                    unsigned int res)
1695 {
1696         int nid = (res & AC_UNSOL_RES_SUBTAG) >> 20;
1697         switch (res >> 26) {
1698         case CONEXANT_HP_EVENT:
1699                 cxt5051_hp_automute(codec);
1700                 break;
1701         case CXT5051_PORTB_EVENT:
1702                 cxt5051_portb_automic(codec);
1703                 break;
1704         case CXT5051_PORTC_EVENT:
1705                 cxt5051_portc_automic(codec);
1706                 break;
1707         }
1708         snd_hda_input_jack_report(codec, nid);
1709 }
1710
1711 static const struct snd_kcontrol_new cxt5051_playback_mixers[] = {
1712         HDA_CODEC_VOLUME("Master Playback Volume", 0x10, 0x00, HDA_OUTPUT),
1713         {
1714                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1715                 .name = "Master Playback Switch",
1716                 .info = cxt_eapd_info,
1717                 .get = cxt_eapd_get,
1718                 .put = cxt5051_hp_master_sw_put,
1719                 .private_value = 0x1a,
1720         },
1721         {}
1722 };
1723
1724 static const struct snd_kcontrol_new cxt5051_capture_mixers[] = {
1725         HDA_CODEC_VOLUME("Internal Mic Volume", 0x14, 0x00, HDA_INPUT),
1726         HDA_CODEC_MUTE("Internal Mic Switch", 0x14, 0x00, HDA_INPUT),
1727         HDA_CODEC_VOLUME("Mic Volume", 0x14, 0x01, HDA_INPUT),
1728         HDA_CODEC_MUTE("Mic Switch", 0x14, 0x01, HDA_INPUT),
1729         HDA_CODEC_VOLUME("Docking Mic Volume", 0x15, 0x00, HDA_INPUT),
1730         HDA_CODEC_MUTE("Docking Mic Switch", 0x15, 0x00, HDA_INPUT),
1731         {}
1732 };
1733
1734 static const struct snd_kcontrol_new cxt5051_hp_mixers[] = {
1735         HDA_CODEC_VOLUME("Internal Mic Volume", 0x14, 0x00, HDA_INPUT),
1736         HDA_CODEC_MUTE("Internal Mic Switch", 0x14, 0x00, HDA_INPUT),
1737         HDA_CODEC_VOLUME("Mic Volume", 0x15, 0x00, HDA_INPUT),
1738         HDA_CODEC_MUTE("Mic Switch", 0x15, 0x00, HDA_INPUT),
1739         {}
1740 };
1741
1742 static const struct snd_kcontrol_new cxt5051_hp_dv6736_mixers[] = {
1743         HDA_CODEC_VOLUME("Capture Volume", 0x14, 0x00, HDA_INPUT),
1744         HDA_CODEC_MUTE("Capture Switch", 0x14, 0x00, HDA_INPUT),
1745         {}
1746 };
1747
1748 static const struct snd_kcontrol_new cxt5051_f700_mixers[] = {
1749         HDA_CODEC_VOLUME("Capture Volume", 0x14, 0x01, HDA_INPUT),
1750         HDA_CODEC_MUTE("Capture Switch", 0x14, 0x01, HDA_INPUT),
1751         {}
1752 };
1753
1754 static const struct snd_kcontrol_new cxt5051_toshiba_mixers[] = {
1755         HDA_CODEC_VOLUME("Internal Mic Volume", 0x14, 0x00, HDA_INPUT),
1756         HDA_CODEC_MUTE("Internal Mic Switch", 0x14, 0x00, HDA_INPUT),
1757         HDA_CODEC_VOLUME("Mic Volume", 0x14, 0x01, HDA_INPUT),
1758         HDA_CODEC_MUTE("Mic Switch", 0x14, 0x01, HDA_INPUT),
1759         {}
1760 };
1761
1762 static const struct hda_verb cxt5051_init_verbs[] = {
1763         /* Line in, Mic */
1764         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03},
1765         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1766         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03},
1767         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1768         {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1769         {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03},
1770         /* SPK  */
1771         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1772         {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
1773         /* HP, Amp  */
1774         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1775         {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
1776         /* DAC1 */      
1777         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1778         /* Record selector: Internal mic */
1779         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x44},
1780         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1) | 0x44},
1781         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x44},
1782         /* SPDIF route: PCM */
1783         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1784         {0x1c, AC_VERB_SET_CONNECT_SEL, 0x0},
1785         /* EAPD */
1786         {0x1a, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */ 
1787         {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CONEXANT_HP_EVENT},
1788         { } /* end */
1789 };
1790
1791 static const struct hda_verb cxt5051_hp_dv6736_init_verbs[] = {
1792         /* Line in, Mic */
1793         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03},
1794         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1795         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0},
1796         {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0},
1797         /* SPK  */
1798         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1799         {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
1800         /* HP, Amp  */
1801         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1802         {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
1803         /* DAC1 */
1804         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1805         /* Record selector: Internal mic */
1806         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1) | 0x44},
1807         {0x14, AC_VERB_SET_CONNECT_SEL, 0x1},
1808         /* SPDIF route: PCM */
1809         {0x1c, AC_VERB_SET_CONNECT_SEL, 0x0},
1810         /* EAPD */
1811         {0x1a, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
1812         {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CONEXANT_HP_EVENT},
1813         { } /* end */
1814 };
1815
1816 static const struct hda_verb cxt5051_lenovo_x200_init_verbs[] = {
1817         /* Line in, Mic */
1818         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03},
1819         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1820         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03},
1821         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1822         {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1823         {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03},
1824         /* SPK  */
1825         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1826         {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
1827         /* HP, Amp  */
1828         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1829         {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
1830         /* Docking HP */
1831         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1832         {0x19, AC_VERB_SET_CONNECT_SEL, 0x00},
1833         /* DAC1 */
1834         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1835         /* Record selector: Internal mic */
1836         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x44},
1837         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1) | 0x44},
1838         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x44},
1839         /* SPDIF route: PCM */
1840         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* needed for W500 Advanced Mini Dock 250410 */
1841         {0x1c, AC_VERB_SET_CONNECT_SEL, 0x0},
1842         /* EAPD */
1843         {0x1a, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
1844         {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CONEXANT_HP_EVENT},
1845         {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CONEXANT_HP_EVENT},
1846         { } /* end */
1847 };
1848
1849 static const struct hda_verb cxt5051_f700_init_verbs[] = {
1850         /* Line in, Mic */
1851         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03},
1852         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1853         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0},
1854         {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0},
1855         /* SPK  */
1856         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1857         {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
1858         /* HP, Amp  */
1859         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1860         {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
1861         /* DAC1 */
1862         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1863         /* Record selector: Internal mic */
1864         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1) | 0x44},
1865         {0x14, AC_VERB_SET_CONNECT_SEL, 0x1},
1866         /* SPDIF route: PCM */
1867         {0x1c, AC_VERB_SET_CONNECT_SEL, 0x0},
1868         /* EAPD */
1869         {0x1a, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
1870         {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CONEXANT_HP_EVENT},
1871         { } /* end */
1872 };
1873
1874 static void cxt5051_init_mic_port(struct hda_codec *codec, hda_nid_t nid,
1875                                  unsigned int event)
1876 {
1877         snd_hda_codec_write(codec, nid, 0,
1878                             AC_VERB_SET_UNSOLICITED_ENABLE,
1879                             AC_USRSP_EN | event);
1880         snd_hda_input_jack_add(codec, nid, SND_JACK_MICROPHONE, NULL);
1881         snd_hda_input_jack_report(codec, nid);
1882 }
1883
1884 static const struct hda_verb cxt5051_ideapad_init_verbs[] = {
1885         /* Subwoofer */
1886         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1887         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1888         { } /* end */
1889 };
1890
1891 /* initialize jack-sensing, too */
1892 static int cxt5051_init(struct hda_codec *codec)
1893 {
1894         struct conexant_spec *spec = codec->spec;
1895
1896         conexant_init(codec);
1897         conexant_init_jacks(codec);
1898
1899         if (spec->auto_mic & AUTO_MIC_PORTB)
1900                 cxt5051_init_mic_port(codec, 0x17, CXT5051_PORTB_EVENT);
1901         if (spec->auto_mic & AUTO_MIC_PORTC)
1902                 cxt5051_init_mic_port(codec, 0x18, CXT5051_PORTC_EVENT);
1903
1904         if (codec->patch_ops.unsol_event) {
1905                 cxt5051_hp_automute(codec);
1906                 cxt5051_portb_automic(codec);
1907                 cxt5051_portc_automic(codec);
1908         }
1909         return 0;
1910 }
1911
1912
1913 enum {
1914         CXT5051_LAPTOP,  /* Laptops w/ EAPD support */
1915         CXT5051_HP,     /* no docking */
1916         CXT5051_HP_DV6736,      /* HP without mic switch */
1917         CXT5051_LENOVO_X200,    /* Lenovo X200 laptop, also used for Advanced Mini Dock 250410 */
1918         CXT5051_F700,       /* HP Compaq Presario F700 */
1919         CXT5051_TOSHIBA,        /* Toshiba M300 & co */
1920         CXT5051_IDEAPAD,        /* Lenovo IdeaPad Y430 */
1921         CXT5051_AUTO,           /* auto-parser */
1922         CXT5051_MODELS
1923 };
1924
1925 static const char *const cxt5051_models[CXT5051_MODELS] = {
1926         [CXT5051_LAPTOP]        = "laptop",
1927         [CXT5051_HP]            = "hp",
1928         [CXT5051_HP_DV6736]     = "hp-dv6736",
1929         [CXT5051_LENOVO_X200]   = "lenovo-x200",
1930         [CXT5051_F700]          = "hp-700",
1931         [CXT5051_TOSHIBA]       = "toshiba",
1932         [CXT5051_IDEAPAD]       = "ideapad",
1933         [CXT5051_AUTO]          = "auto",
1934 };
1935
1936 static const struct snd_pci_quirk cxt5051_cfg_tbl[] = {
1937         SND_PCI_QUIRK(0x103c, 0x30cf, "HP DV6736", CXT5051_HP_DV6736),
1938         SND_PCI_QUIRK(0x103c, 0x360b, "Compaq Presario CQ60", CXT5051_HP),
1939         SND_PCI_QUIRK(0x103c, 0x30ea, "Compaq Presario F700", CXT5051_F700),
1940         SND_PCI_QUIRK(0x1179, 0xff50, "Toshiba M30x", CXT5051_TOSHIBA),
1941         SND_PCI_QUIRK(0x14f1, 0x0101, "Conexant Reference board",
1942                       CXT5051_LAPTOP),
1943         SND_PCI_QUIRK(0x14f1, 0x5051, "HP Spartan 1.1", CXT5051_HP),
1944         SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo X200", CXT5051_LENOVO_X200),
1945         SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo IdeaPad", CXT5051_IDEAPAD),
1946         {}
1947 };
1948
1949 static int patch_cxt5051(struct hda_codec *codec)
1950 {
1951         struct conexant_spec *spec;
1952         int board_config;
1953
1954         board_config = snd_hda_check_board_config(codec, CXT5051_MODELS,
1955                                                   cxt5051_models,
1956                                                   cxt5051_cfg_tbl);
1957         if (board_config < 0)
1958                 board_config = CXT5051_AUTO;
1959         if (board_config == CXT5051_AUTO) {
1960                 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
1961                        codec->chip_name);
1962                 return patch_conexant_auto(codec);
1963         }
1964
1965         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1966         if (!spec)
1967                 return -ENOMEM;
1968         codec->spec = spec;
1969         codec->pin_amp_workaround = 1;
1970
1971         codec->patch_ops = conexant_patch_ops;
1972         codec->patch_ops.init = cxt5051_init;
1973
1974         spec->multiout.max_channels = 2;
1975         spec->multiout.num_dacs = ARRAY_SIZE(cxt5051_dac_nids);
1976         spec->multiout.dac_nids = cxt5051_dac_nids;
1977         spec->multiout.dig_out_nid = CXT5051_SPDIF_OUT;
1978         spec->num_adc_nids = 1; /* not 2; via auto-mic switch */
1979         spec->adc_nids = cxt5051_adc_nids;
1980         spec->num_mixers = 2;
1981         spec->mixers[0] = cxt5051_capture_mixers;
1982         spec->mixers[1] = cxt5051_playback_mixers;
1983         spec->num_init_verbs = 1;
1984         spec->init_verbs[0] = cxt5051_init_verbs;
1985         spec->spdif_route = 0;
1986         spec->num_channel_mode = ARRAY_SIZE(cxt5051_modes);
1987         spec->channel_mode = cxt5051_modes;
1988         spec->cur_adc = 0;
1989         spec->cur_adc_idx = 0;
1990
1991         set_beep_amp(spec, 0x13, 0, HDA_OUTPUT);
1992
1993         codec->patch_ops.unsol_event = cxt5051_hp_unsol_event;
1994
1995         spec->auto_mic = AUTO_MIC_PORTB | AUTO_MIC_PORTC;
1996         switch (board_config) {
1997         case CXT5051_HP:
1998                 spec->mixers[0] = cxt5051_hp_mixers;
1999                 break;
2000         case CXT5051_HP_DV6736:
2001                 spec->init_verbs[0] = cxt5051_hp_dv6736_init_verbs;
2002                 spec->mixers[0] = cxt5051_hp_dv6736_mixers;
2003                 spec->auto_mic = 0;
2004                 break;
2005         case CXT5051_LENOVO_X200:
2006                 spec->init_verbs[0] = cxt5051_lenovo_x200_init_verbs;
2007                 /* Thinkpad X301 does not have S/PDIF wired and no ability
2008                    to use a docking station. */
2009                 if (codec->subsystem_id == 0x17aa211f)
2010                         spec->multiout.dig_out_nid = 0;
2011                 break;
2012         case CXT5051_F700:
2013                 spec->init_verbs[0] = cxt5051_f700_init_verbs;
2014                 spec->mixers[0] = cxt5051_f700_mixers;
2015                 spec->auto_mic = 0;
2016                 break;
2017         case CXT5051_TOSHIBA:
2018                 spec->mixers[0] = cxt5051_toshiba_mixers;
2019                 spec->auto_mic = AUTO_MIC_PORTB;
2020                 break;
2021         case CXT5051_IDEAPAD:
2022                 spec->init_verbs[spec->num_init_verbs++] =
2023                         cxt5051_ideapad_init_verbs;
2024                 spec->ideapad = 1;
2025                 break;
2026         }
2027
2028         if (spec->beep_amp)
2029                 snd_hda_attach_beep_device(codec, spec->beep_amp);
2030
2031         return 0;
2032 }
2033
2034 /* Conexant 5066 specific */
2035
2036 static const hda_nid_t cxt5066_dac_nids[1] = { 0x10 };
2037 static const hda_nid_t cxt5066_adc_nids[3] = { 0x14, 0x15, 0x16 };
2038 static const hda_nid_t cxt5066_capsrc_nids[1] = { 0x17 };
2039 static const hda_nid_t cxt5066_digout_pin_nids[2] = { 0x20, 0x22 };
2040
2041 /* OLPC's microphone port is DC coupled for use with external sensors,
2042  * therefore we use a 50% mic bias in order to center the input signal with
2043  * the DC input range of the codec. */
2044 #define CXT5066_OLPC_EXT_MIC_BIAS PIN_VREF50
2045
2046 static const struct hda_channel_mode cxt5066_modes[1] = {
2047         { 2, NULL },
2048 };
2049
2050 #define HP_PRESENT_PORT_A       (1 << 0)
2051 #define HP_PRESENT_PORT_D       (1 << 1)
2052 #define hp_port_a_present(spec) ((spec)->hp_present & HP_PRESENT_PORT_A)
2053 #define hp_port_d_present(spec) ((spec)->hp_present & HP_PRESENT_PORT_D)
2054
2055 static void cxt5066_update_speaker(struct hda_codec *codec)
2056 {
2057         struct conexant_spec *spec = codec->spec;
2058         unsigned int pinctl;
2059
2060         snd_printdd("CXT5066: update speaker, hp_present=%d, cur_eapd=%d\n",
2061                     spec->hp_present, spec->cur_eapd);
2062
2063         /* Port A (HP) */
2064         pinctl = (hp_port_a_present(spec) && spec->cur_eapd) ? PIN_HP : 0;
2065         snd_hda_codec_write(codec, 0x19, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
2066                         pinctl);
2067
2068         /* Port D (HP/LO) */
2069         pinctl = spec->cur_eapd ? spec->port_d_mode : 0;
2070         if (spec->dell_automute || spec->thinkpad) {
2071                 /* Mute if Port A is connected */
2072                 if (hp_port_a_present(spec))
2073                         pinctl = 0;
2074         } else {
2075                 /* Thinkpad/Dell doesn't give pin-D status */
2076                 if (!hp_port_d_present(spec))
2077                         pinctl = 0;
2078         }
2079         snd_hda_codec_write(codec, 0x1c, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
2080                         pinctl);
2081
2082         /* CLASS_D AMP */
2083         pinctl = (!spec->hp_present && spec->cur_eapd) ? PIN_OUT : 0;
2084         snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
2085                         pinctl);
2086 }
2087
2088 /* turn on/off EAPD (+ mute HP) as a master switch */
2089 static int cxt5066_hp_master_sw_put(struct snd_kcontrol *kcontrol,
2090                                     struct snd_ctl_elem_value *ucontrol)
2091 {
2092         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2093
2094         if (!cxt_eapd_put(kcontrol, ucontrol))
2095                 return 0;
2096
2097         cxt5066_update_speaker(codec);
2098         return 1;
2099 }
2100
2101 static const struct hda_input_mux cxt5066_olpc_dc_bias = {
2102         .num_items = 3,
2103         .items = {
2104                 { "Off", PIN_IN },
2105                 { "50%", PIN_VREF50 },
2106                 { "80%", PIN_VREF80 },
2107         },
2108 };
2109
2110 static int cxt5066_set_olpc_dc_bias(struct hda_codec *codec)
2111 {
2112         struct conexant_spec *spec = codec->spec;
2113         /* Even though port F is the DC input, the bias is controlled on port B.
2114          * we also leave that port as an active input (but unselected) in DC mode
2115          * just in case that is necessary to make the bias setting take effect. */
2116         return snd_hda_codec_write_cache(codec, 0x1a, 0,
2117                 AC_VERB_SET_PIN_WIDGET_CONTROL,
2118                 cxt5066_olpc_dc_bias.items[spec->dc_input_bias].index);
2119 }
2120
2121 /* OLPC defers mic widget control until when capture is started because the
2122  * microphone LED comes on as soon as these settings are put in place. if we
2123  * did this before recording, it would give the false indication that recording
2124  * is happening when it is not. */
2125 static void cxt5066_olpc_select_mic(struct hda_codec *codec)
2126 {
2127         struct conexant_spec *spec = codec->spec;
2128         if (!spec->recording)
2129                 return;
2130
2131         if (spec->dc_enable) {
2132                 /* in DC mode we ignore presence detection and just use the jack
2133                  * through our special DC port */
2134                 const struct hda_verb enable_dc_mode[] = {
2135                         /* disble internal mic, port C */
2136                         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2137
2138                         /* enable DC capture, port F */
2139                         {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2140                         {},
2141                 };
2142
2143                 snd_hda_sequence_write(codec, enable_dc_mode);
2144                 /* port B input disabled (and bias set) through the following call */
2145                 cxt5066_set_olpc_dc_bias(codec);
2146                 return;
2147         }
2148
2149         /* disable DC (port F) */
2150         snd_hda_codec_write(codec, 0x1e, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
2151
2152         /* external mic, port B */
2153         snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
2154                 spec->ext_mic_present ? CXT5066_OLPC_EXT_MIC_BIAS : 0);
2155
2156         /* internal mic, port C */
2157         snd_hda_codec_write(codec, 0x1b, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
2158                 spec->ext_mic_present ? 0 : PIN_VREF80);
2159 }
2160
2161 /* toggle input of built-in and mic jack appropriately */
2162 static void cxt5066_olpc_automic(struct hda_codec *codec)
2163 {
2164         struct conexant_spec *spec = codec->spec;
2165         unsigned int present;
2166
2167         if (spec->dc_enable) /* don't do presence detection in DC mode */
2168                 return;
2169
2170         present = snd_hda_codec_read(codec, 0x1a, 0,
2171                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2172         if (present)
2173                 snd_printdd("CXT5066: external microphone detected\n");
2174         else
2175                 snd_printdd("CXT5066: external microphone absent\n");
2176
2177         snd_hda_codec_write(codec, 0x17, 0, AC_VERB_SET_CONNECT_SEL,
2178                 present ? 0 : 1);
2179         spec->ext_mic_present = !!present;
2180
2181         cxt5066_olpc_select_mic(codec);
2182 }
2183
2184 /* toggle input of built-in digital mic and mic jack appropriately */
2185 static void cxt5066_vostro_automic(struct hda_codec *codec)
2186 {
2187         unsigned int present;
2188
2189         struct hda_verb ext_mic_present[] = {
2190                 /* enable external mic, port B */
2191                 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2192
2193                 /* switch to external mic input */
2194                 {0x17, AC_VERB_SET_CONNECT_SEL, 0},
2195                 {0x14, AC_VERB_SET_CONNECT_SEL, 0},
2196
2197                 /* disable internal digital mic */
2198                 {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2199                 {}
2200         };
2201         static const struct hda_verb ext_mic_absent[] = {
2202                 /* enable internal mic, port C */
2203                 {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2204
2205                 /* switch to internal mic input */
2206                 {0x14, AC_VERB_SET_CONNECT_SEL, 2},
2207
2208                 /* disable external mic, port B */
2209                 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2210                 {}
2211         };
2212
2213         present = snd_hda_jack_detect(codec, 0x1a);
2214         if (present) {
2215                 snd_printdd("CXT5066: external microphone detected\n");
2216                 snd_hda_sequence_write(codec, ext_mic_present);
2217         } else {
2218                 snd_printdd("CXT5066: external microphone absent\n");
2219                 snd_hda_sequence_write(codec, ext_mic_absent);
2220         }
2221 }
2222
2223 /* toggle input of built-in digital mic and mic jack appropriately */
2224 static void cxt5066_ideapad_automic(struct hda_codec *codec)
2225 {
2226         unsigned int present;
2227
2228         struct hda_verb ext_mic_present[] = {
2229                 {0x14, AC_VERB_SET_CONNECT_SEL, 0},
2230                 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2231                 {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2232                 {}
2233         };
2234         static const struct hda_verb ext_mic_absent[] = {
2235                 {0x14, AC_VERB_SET_CONNECT_SEL, 2},
2236                 {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2237                 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2238                 {}
2239         };
2240
2241         present = snd_hda_jack_detect(codec, 0x1b);
2242         if (present) {
2243                 snd_printdd("CXT5066: external microphone detected\n");
2244                 snd_hda_sequence_write(codec, ext_mic_present);
2245         } else {
2246                 snd_printdd("CXT5066: external microphone absent\n");
2247                 snd_hda_sequence_write(codec, ext_mic_absent);
2248         }
2249 }
2250
2251
2252 /* toggle input of built-in digital mic and mic jack appropriately */
2253 static void cxt5066_asus_automic(struct hda_codec *codec)
2254 {
2255         unsigned int present;
2256
2257         present = snd_hda_jack_detect(codec, 0x1b);
2258         snd_printdd("CXT5066: external microphone present=%d\n", present);
2259         snd_hda_codec_write(codec, 0x17, 0, AC_VERB_SET_CONNECT_SEL,
2260                             present ? 1 : 0);
2261 }
2262
2263
2264 /* toggle input of built-in digital mic and mic jack appropriately */
2265 static void cxt5066_hp_laptop_automic(struct hda_codec *codec)
2266 {
2267         unsigned int present;
2268
2269         present = snd_hda_jack_detect(codec, 0x1b);
2270         snd_printdd("CXT5066: external microphone present=%d\n", present);
2271         snd_hda_codec_write(codec, 0x17, 0, AC_VERB_SET_CONNECT_SEL,
2272                             present ? 1 : 3);
2273 }
2274
2275
2276 /* toggle input of built-in digital mic and mic jack appropriately
2277    order is: external mic -> dock mic -> interal mic */
2278 static void cxt5066_thinkpad_automic(struct hda_codec *codec)
2279 {
2280         unsigned int ext_present, dock_present;
2281
2282         static const struct hda_verb ext_mic_present[] = {
2283                 {0x14, AC_VERB_SET_CONNECT_SEL, 0},
2284                 {0x17, AC_VERB_SET_CONNECT_SEL, 1},
2285                 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2286                 {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2287                 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2288                 {}
2289         };
2290         static const struct hda_verb dock_mic_present[] = {
2291                 {0x14, AC_VERB_SET_CONNECT_SEL, 0},
2292                 {0x17, AC_VERB_SET_CONNECT_SEL, 0},
2293                 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2294                 {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2295                 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2296                 {}
2297         };
2298         static const struct hda_verb ext_mic_absent[] = {
2299                 {0x14, AC_VERB_SET_CONNECT_SEL, 2},
2300                 {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2301                 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2302                 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2303                 {}
2304         };
2305
2306         ext_present = snd_hda_jack_detect(codec, 0x1b);
2307         dock_present = snd_hda_jack_detect(codec, 0x1a);
2308         if (ext_present) {
2309                 snd_printdd("CXT5066: external microphone detected\n");
2310                 snd_hda_sequence_write(codec, ext_mic_present);
2311         } else if (dock_present) {
2312                 snd_printdd("CXT5066: dock microphone detected\n");
2313                 snd_hda_sequence_write(codec, dock_mic_present);
2314         } else {
2315                 snd_printdd("CXT5066: external microphone absent\n");
2316                 snd_hda_sequence_write(codec, ext_mic_absent);
2317         }
2318 }
2319
2320 /* mute internal speaker if HP is plugged */
2321 static void cxt5066_hp_automute(struct hda_codec *codec)
2322 {
2323         struct conexant_spec *spec = codec->spec;
2324         unsigned int portA, portD;
2325
2326         /* Port A */
2327         portA = snd_hda_jack_detect(codec, 0x19);
2328
2329         /* Port D */
2330         portD = snd_hda_jack_detect(codec, 0x1c);
2331
2332         spec->hp_present = portA ? HP_PRESENT_PORT_A : 0;
2333         spec->hp_present |= portD ? HP_PRESENT_PORT_D : 0;
2334         snd_printdd("CXT5066: hp automute portA=%x portD=%x present=%d\n",
2335                 portA, portD, spec->hp_present);
2336         cxt5066_update_speaker(codec);
2337 }
2338
2339 /* Dispatch the right mic autoswitch function */
2340 static void cxt5066_automic(struct hda_codec *codec)
2341 {
2342         struct conexant_spec *spec = codec->spec;
2343
2344         if (spec->dell_vostro)
2345                 cxt5066_vostro_automic(codec);
2346         else if (spec->ideapad)
2347                 cxt5066_ideapad_automic(codec);
2348         else if (spec->thinkpad)
2349                 cxt5066_thinkpad_automic(codec);
2350         else if (spec->hp_laptop)
2351                 cxt5066_hp_laptop_automic(codec);
2352         else if (spec->asus)
2353                 cxt5066_asus_automic(codec);
2354 }
2355
2356 /* unsolicited event for jack sensing */
2357 static void cxt5066_olpc_unsol_event(struct hda_codec *codec, unsigned int res)
2358 {
2359         struct conexant_spec *spec = codec->spec;
2360         snd_printdd("CXT5066: unsol event %x (%x)\n", res, res >> 26);
2361         switch (res >> 26) {
2362         case CONEXANT_HP_EVENT:
2363                 cxt5066_hp_automute(codec);
2364                 break;
2365         case CONEXANT_MIC_EVENT:
2366                 /* ignore mic events in DC mode; we're always using the jack */
2367                 if (!spec->dc_enable)
2368                         cxt5066_olpc_automic(codec);
2369                 break;
2370         }
2371 }
2372
2373 /* unsolicited event for jack sensing */
2374 static void cxt5066_unsol_event(struct hda_codec *codec, unsigned int res)
2375 {
2376         snd_printdd("CXT5066: unsol event %x (%x)\n", res, res >> 26);
2377         switch (res >> 26) {
2378         case CONEXANT_HP_EVENT:
2379                 cxt5066_hp_automute(codec);
2380                 break;
2381         case CONEXANT_MIC_EVENT:
2382                 cxt5066_automic(codec);
2383                 break;
2384         }
2385 }
2386
2387
2388 static const struct hda_input_mux cxt5066_analog_mic_boost = {
2389         .num_items = 5,
2390         .items = {
2391                 { "0dB",  0 },
2392                 { "10dB", 1 },
2393                 { "20dB", 2 },
2394                 { "30dB", 3 },
2395                 { "40dB", 4 },
2396         },
2397 };
2398
2399 static void cxt5066_set_mic_boost(struct hda_codec *codec)
2400 {
2401         struct conexant_spec *spec = codec->spec;
2402         snd_hda_codec_write_cache(codec, 0x17, 0,
2403                 AC_VERB_SET_AMP_GAIN_MUTE,
2404                 AC_AMP_SET_RIGHT | AC_AMP_SET_LEFT | AC_AMP_SET_OUTPUT |
2405                         cxt5066_analog_mic_boost.items[spec->mic_boost].index);
2406         if (spec->ideapad || spec->thinkpad) {
2407                 /* adjust the internal mic as well...it is not through 0x17 */
2408                 snd_hda_codec_write_cache(codec, 0x23, 0,
2409                         AC_VERB_SET_AMP_GAIN_MUTE,
2410                         AC_AMP_SET_RIGHT | AC_AMP_SET_LEFT | AC_AMP_SET_INPUT |
2411                                 cxt5066_analog_mic_boost.
2412                                         items[spec->mic_boost].index);
2413         }
2414 }
2415
2416 static int cxt5066_mic_boost_mux_enum_info(struct snd_kcontrol *kcontrol,
2417                                            struct snd_ctl_elem_info *uinfo)
2418 {
2419         return snd_hda_input_mux_info(&cxt5066_analog_mic_boost, uinfo);
2420 }
2421
2422 static int cxt5066_mic_boost_mux_enum_get(struct snd_kcontrol *kcontrol,
2423                                           struct snd_ctl_elem_value *ucontrol)
2424 {
2425         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2426         struct conexant_spec *spec = codec->spec;
2427         ucontrol->value.enumerated.item[0] = spec->mic_boost;
2428         return 0;
2429 }
2430
2431 static int cxt5066_mic_boost_mux_enum_put(struct snd_kcontrol *kcontrol,
2432                                           struct snd_ctl_elem_value *ucontrol)
2433 {
2434         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2435         struct conexant_spec *spec = codec->spec;
2436         const struct hda_input_mux *imux = &cxt5066_analog_mic_boost;
2437         unsigned int idx;
2438         idx = ucontrol->value.enumerated.item[0];
2439         if (idx >= imux->num_items)
2440                 idx = imux->num_items - 1;
2441
2442         spec->mic_boost = idx;
2443         if (!spec->dc_enable)
2444                 cxt5066_set_mic_boost(codec);
2445         return 1;
2446 }
2447
2448 static void cxt5066_enable_dc(struct hda_codec *codec)
2449 {
2450         const struct hda_verb enable_dc_mode[] = {
2451                 /* disable gain */
2452                 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2453
2454                 /* switch to DC input */
2455                 {0x17, AC_VERB_SET_CONNECT_SEL, 3},
2456                 {}
2457         };
2458
2459         /* configure as input source */
2460         snd_hda_sequence_write(codec, enable_dc_mode);
2461         cxt5066_olpc_select_mic(codec); /* also sets configured bias */
2462 }
2463
2464 static void cxt5066_disable_dc(struct hda_codec *codec)
2465 {
2466         /* reconfigure input source */
2467         cxt5066_set_mic_boost(codec);
2468         /* automic also selects the right mic if we're recording */
2469         cxt5066_olpc_automic(codec);
2470 }
2471
2472 static int cxt5066_olpc_dc_get(struct snd_kcontrol *kcontrol,
2473                              struct snd_ctl_elem_value *ucontrol)
2474 {
2475         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2476         struct conexant_spec *spec = codec->spec;
2477         ucontrol->value.integer.value[0] = spec->dc_enable;
2478         return 0;
2479 }
2480
2481 static int cxt5066_olpc_dc_put(struct snd_kcontrol *kcontrol,
2482                              struct snd_ctl_elem_value *ucontrol)
2483 {
2484         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2485         struct conexant_spec *spec = codec->spec;
2486         int dc_enable = !!ucontrol->value.integer.value[0];
2487
2488         if (dc_enable == spec->dc_enable)
2489                 return 0;
2490
2491         spec->dc_enable = dc_enable;
2492         if (dc_enable)
2493                 cxt5066_enable_dc(codec);
2494         else
2495                 cxt5066_disable_dc(codec);
2496
2497         return 1;
2498 }
2499
2500 static int cxt5066_olpc_dc_bias_enum_info(struct snd_kcontrol *kcontrol,
2501                                            struct snd_ctl_elem_info *uinfo)
2502 {
2503         return snd_hda_input_mux_info(&cxt5066_olpc_dc_bias, uinfo);
2504 }
2505
2506 static int cxt5066_olpc_dc_bias_enum_get(struct snd_kcontrol *kcontrol,
2507                                           struct snd_ctl_elem_value *ucontrol)
2508 {
2509         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2510         struct conexant_spec *spec = codec->spec;
2511         ucontrol->value.enumerated.item[0] = spec->dc_input_bias;
2512         return 0;
2513 }
2514
2515 static int cxt5066_olpc_dc_bias_enum_put(struct snd_kcontrol *kcontrol,
2516                                           struct snd_ctl_elem_value *ucontrol)
2517 {
2518         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2519         struct conexant_spec *spec = codec->spec;
2520         const struct hda_input_mux *imux = &cxt5066_analog_mic_boost;
2521         unsigned int idx;
2522
2523         idx = ucontrol->value.enumerated.item[0];
2524         if (idx >= imux->num_items)
2525                 idx = imux->num_items - 1;
2526
2527         spec->dc_input_bias = idx;
2528         if (spec->dc_enable)
2529                 cxt5066_set_olpc_dc_bias(codec);
2530         return 1;
2531 }
2532
2533 static void cxt5066_olpc_capture_prepare(struct hda_codec *codec)
2534 {
2535         struct conexant_spec *spec = codec->spec;
2536         /* mark as recording and configure the microphone widget so that the
2537          * recording LED comes on. */
2538         spec->recording = 1;
2539         cxt5066_olpc_select_mic(codec);
2540 }
2541
2542 static void cxt5066_olpc_capture_cleanup(struct hda_codec *codec)
2543 {
2544         struct conexant_spec *spec = codec->spec;
2545         const struct hda_verb disable_mics[] = {
2546                 /* disable external mic, port B */
2547                 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2548
2549                 /* disble internal mic, port C */
2550                 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2551
2552                 /* disable DC capture, port F */
2553                 {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2554                 {},
2555         };
2556
2557         snd_hda_sequence_write(codec, disable_mics);
2558         spec->recording = 0;
2559 }
2560
2561 static void conexant_check_dig_outs(struct hda_codec *codec,
2562                                     const hda_nid_t *dig_pins,
2563                                     int num_pins)
2564 {
2565         struct conexant_spec *spec = codec->spec;
2566         hda_nid_t *nid_loc = &spec->multiout.dig_out_nid;
2567         int i;
2568
2569         for (i = 0; i < num_pins; i++, dig_pins++) {
2570                 unsigned int cfg = snd_hda_codec_get_pincfg(codec, *dig_pins);
2571                 if (get_defcfg_connect(cfg) == AC_JACK_PORT_NONE)
2572                         continue;
2573                 if (snd_hda_get_connections(codec, *dig_pins, nid_loc, 1) != 1)
2574                         continue;
2575                 if (spec->slave_dig_outs[0])
2576                         nid_loc++;
2577                 else
2578                         nid_loc = spec->slave_dig_outs;
2579         }
2580 }
2581
2582 static const struct hda_input_mux cxt5066_capture_source = {
2583         .num_items = 4,
2584         .items = {
2585                 { "Mic B", 0 },
2586                 { "Mic C", 1 },
2587                 { "Mic E", 2 },
2588                 { "Mic F", 3 },
2589         },
2590 };
2591
2592 static const struct hda_bind_ctls cxt5066_bind_capture_vol_others = {
2593         .ops = &snd_hda_bind_vol,
2594         .values = {
2595                 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_INPUT),
2596                 HDA_COMPOSE_AMP_VAL(0x14, 3, 2, HDA_INPUT),
2597                 0
2598         },
2599 };
2600
2601 static const struct hda_bind_ctls cxt5066_bind_capture_sw_others = {
2602         .ops = &snd_hda_bind_sw,
2603         .values = {
2604                 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_INPUT),
2605                 HDA_COMPOSE_AMP_VAL(0x14, 3, 2, HDA_INPUT),
2606                 0
2607         },
2608 };
2609
2610 static const struct snd_kcontrol_new cxt5066_mixer_master[] = {
2611         HDA_CODEC_VOLUME("Master Playback Volume", 0x10, 0x00, HDA_OUTPUT),
2612         {}
2613 };
2614
2615 static const struct snd_kcontrol_new cxt5066_mixer_master_olpc[] = {
2616         {
2617                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2618                 .name = "Master Playback Volume",
2619                 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
2620                                   SNDRV_CTL_ELEM_ACCESS_TLV_READ |
2621                                   SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK,
2622                 .subdevice = HDA_SUBDEV_AMP_FLAG,
2623                 .info = snd_hda_mixer_amp_volume_info,
2624                 .get = snd_hda_mixer_amp_volume_get,
2625                 .put = snd_hda_mixer_amp_volume_put,
2626                 .tlv = { .c = snd_hda_mixer_amp_tlv },
2627                 /* offset by 28 volume steps to limit minimum gain to -46dB */
2628                 .private_value =
2629                         HDA_COMPOSE_AMP_VAL_OFS(0x10, 3, 0, HDA_OUTPUT, 28),
2630         },
2631         {}
2632 };
2633
2634 static const struct snd_kcontrol_new cxt5066_mixer_olpc_dc[] = {
2635         {
2636                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2637                 .name = "DC Mode Enable Switch",
2638                 .info = snd_ctl_boolean_mono_info,
2639                 .get = cxt5066_olpc_dc_get,
2640                 .put = cxt5066_olpc_dc_put,
2641         },
2642         {
2643                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2644                 .name = "DC Input Bias Enum",
2645                 .info = cxt5066_olpc_dc_bias_enum_info,
2646                 .get = cxt5066_olpc_dc_bias_enum_get,
2647                 .put = cxt5066_olpc_dc_bias_enum_put,
2648         },
2649         {}
2650 };
2651
2652 static const struct snd_kcontrol_new cxt5066_mixers[] = {
2653         {
2654                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2655                 .name = "Master Playback Switch",
2656                 .info = cxt_eapd_info,
2657                 .get = cxt_eapd_get,
2658                 .put = cxt5066_hp_master_sw_put,
2659                 .private_value = 0x1d,
2660         },
2661
2662         {
2663                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2664                 .name = "Analog Mic Boost Capture Enum",
2665                 .info = cxt5066_mic_boost_mux_enum_info,
2666                 .get = cxt5066_mic_boost_mux_enum_get,
2667                 .put = cxt5066_mic_boost_mux_enum_put,
2668         },
2669
2670         HDA_BIND_VOL("Capture Volume", &cxt5066_bind_capture_vol_others),
2671         HDA_BIND_SW("Capture Switch", &cxt5066_bind_capture_sw_others),
2672         {}
2673 };
2674
2675 static const struct snd_kcontrol_new cxt5066_vostro_mixers[] = {
2676         {
2677                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2678                 .name = "Internal Mic Boost Capture Enum",
2679                 .info = cxt5066_mic_boost_mux_enum_info,
2680                 .get = cxt5066_mic_boost_mux_enum_get,
2681                 .put = cxt5066_mic_boost_mux_enum_put,
2682                 .private_value = 0x23 | 0x100,
2683         },
2684         {}
2685 };
2686
2687 static const struct hda_verb cxt5066_init_verbs[] = {
2688         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, /* Port B */
2689         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, /* Port C */
2690         {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Port F */
2691         {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Port E */
2692
2693         /* Speakers  */
2694         {0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2695         {0x1f, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
2696
2697         /* HP, Amp  */
2698         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2699         {0x19, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
2700
2701         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2702         {0x1c, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
2703
2704         /* DAC1 */
2705         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2706
2707         /* Node 14 connections: 0x17 0x18 0x23 0x24 0x27 */
2708         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x50},
2709         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2710         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2) | 0x50},
2711         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2712         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2713
2714         /* no digital microphone support yet */
2715         {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2716
2717         /* Audio input selector */
2718         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x3},
2719
2720         /* SPDIF route: PCM */
2721         {0x20, AC_VERB_SET_CONNECT_SEL, 0x0},
2722         {0x22, AC_VERB_SET_CONNECT_SEL, 0x0},
2723
2724         {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2725         {0x22, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2726
2727         /* EAPD */
2728         {0x1d, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
2729
2730         /* not handling these yet */
2731         {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, 0},
2732         {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, 0},
2733         {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, 0},
2734         {0x1c, AC_VERB_SET_UNSOLICITED_ENABLE, 0},
2735         {0x1d, AC_VERB_SET_UNSOLICITED_ENABLE, 0},
2736         {0x1e, AC_VERB_SET_UNSOLICITED_ENABLE, 0},
2737         {0x20, AC_VERB_SET_UNSOLICITED_ENABLE, 0},
2738         {0x22, AC_VERB_SET_UNSOLICITED_ENABLE, 0},
2739         { } /* end */
2740 };
2741
2742 static const struct hda_verb cxt5066_init_verbs_olpc[] = {
2743         /* Port A: headphones */
2744         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2745         {0x19, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
2746
2747         /* Port B: external microphone */
2748         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2749
2750         /* Port C: internal microphone */
2751         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2752
2753         /* Port D: unused */
2754         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2755
2756         /* Port E: unused, but has primary EAPD */
2757         {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2758         {0x1d, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
2759
2760         /* Port F: external DC input through microphone port */
2761         {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2762
2763         /* Port G: internal speakers */
2764         {0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2765         {0x1f, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
2766
2767         /* DAC1 */
2768         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2769
2770         /* DAC2: unused */
2771         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2772
2773         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x50},
2774         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2775         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2776         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2777         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2778         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2779         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2780         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2781         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2782         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2783         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2784         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2785
2786         /* Disable digital microphone port */
2787         {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2788
2789         /* Audio input selectors */
2790         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x3},
2791         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2792
2793         /* Disable SPDIF */
2794         {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2795         {0x22, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2796
2797         /* enable unsolicited events for Port A and B */
2798         {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT},
2799         {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT},
2800         { } /* end */
2801 };
2802
2803 static const struct hda_verb cxt5066_init_verbs_vostro[] = {
2804         /* Port A: headphones */
2805         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2806         {0x19, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
2807
2808         /* Port B: external microphone */
2809         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2810
2811         /* Port C: unused */
2812         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2813
2814         /* Port D: unused */
2815         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2816
2817         /* Port E: unused, but has primary EAPD */
2818         {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2819         {0x1d, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
2820
2821         /* Port F: unused */
2822         {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2823
2824         /* Port G: internal speakers */
2825         {0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2826         {0x1f, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
2827
2828         /* DAC1 */
2829         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2830
2831         /* DAC2: unused */
2832         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2833
2834         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2835         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2836         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2837         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2838         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2839         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2840         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2841         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2842         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2843         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2844         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2845         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2846
2847         /* Digital microphone port */
2848         {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2849
2850         /* Audio input selectors */
2851         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x3},
2852         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2853
2854         /* Disable SPDIF */
2855         {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2856         {0x22, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2857
2858         /* enable unsolicited events for Port A and B */
2859         {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT},
2860         {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT},
2861         { } /* end */
2862 };
2863
2864 static const struct hda_verb cxt5066_init_verbs_ideapad[] = {
2865         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, /* Port B */
2866         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, /* Port C */
2867         {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Port F */
2868         {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Port E */
2869
2870         /* Speakers  */
2871         {0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2872         {0x1f, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
2873
2874         /* HP, Amp  */
2875         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2876         {0x19, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
2877
2878         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2879         {0x1c, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
2880
2881         /* DAC1 */
2882         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2883
2884         /* Node 14 connections: 0x17 0x18 0x23 0x24 0x27 */
2885         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x50},
2886         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2887         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2) | 0x50},
2888         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2889         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2890         {0x14, AC_VERB_SET_CONNECT_SEL, 2},     /* default to internal mic */
2891
2892         /* Audio input selector */
2893         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x2},
2894         {0x17, AC_VERB_SET_CONNECT_SEL, 1},     /* route ext mic */
2895
2896         /* SPDIF route: PCM */
2897         {0x20, AC_VERB_SET_CONNECT_SEL, 0x0},
2898         {0x22, AC_VERB_SET_CONNECT_SEL, 0x0},
2899
2900         {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2901         {0x22, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2902
2903         /* internal microphone */
2904         {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* enable internal mic */
2905
2906         /* EAPD */
2907         {0x1d, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
2908
2909         {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT},
2910         {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT},
2911         { } /* end */
2912 };
2913
2914 static const struct hda_verb cxt5066_init_verbs_thinkpad[] = {
2915         {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Port F */
2916         {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Port E */
2917
2918         /* Port G: internal speakers  */
2919         {0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2920         {0x1f, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
2921
2922         /* Port A: HP, Amp  */
2923         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2924         {0x19, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
2925
2926         /* Port B: Mic Dock */
2927         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2928
2929         /* Port C: Mic */
2930         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2931
2932         /* Port D: HP Dock, Amp */
2933         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2934         {0x1c, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
2935
2936         /* DAC1 */
2937         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2938
2939         /* Node 14 connections: 0x17 0x18 0x23 0x24 0x27 */
2940         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x50},
2941         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2942         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2) | 0x50},
2943         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2944         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2945         {0x14, AC_VERB_SET_CONNECT_SEL, 2},     /* default to internal mic */
2946
2947         /* Audio input selector */
2948         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x2},
2949         {0x17, AC_VERB_SET_CONNECT_SEL, 1},     /* route ext mic */
2950
2951         /* SPDIF route: PCM */
2952         {0x20, AC_VERB_SET_CONNECT_SEL, 0x0},
2953         {0x22, AC_VERB_SET_CONNECT_SEL, 0x0},
2954
2955         {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2956         {0x22, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2957
2958         /* internal microphone */
2959         {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* enable internal mic */
2960
2961         /* EAPD */
2962         {0x1d, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
2963
2964         /* enable unsolicited events for Port A, B, C and D */
2965         {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT},
2966         {0x1c, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT},
2967         {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT},
2968         {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT},
2969         { } /* end */
2970 };
2971
2972 static const struct hda_verb cxt5066_init_verbs_portd_lo[] = {
2973         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2974         { } /* end */
2975 };
2976
2977
2978 static const struct hda_verb cxt5066_init_verbs_hp_laptop[] = {
2979         {0x14, AC_VERB_SET_CONNECT_SEL, 0x0},
2980         {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT},
2981         {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT},
2982         { } /* end */
2983 };
2984
2985 /* initialize jack-sensing, too */
2986 static int cxt5066_init(struct hda_codec *codec)
2987 {
2988         snd_printdd("CXT5066: init\n");
2989         conexant_init(codec);
2990         if (codec->patch_ops.unsol_event) {
2991                 cxt5066_hp_automute(codec);
2992                 cxt5066_automic(codec);
2993         }
2994         cxt5066_set_mic_boost(codec);
2995         return 0;
2996 }
2997
2998 static int cxt5066_olpc_init(struct hda_codec *codec)
2999 {
3000         struct conexant_spec *spec = codec->spec;
3001         snd_printdd("CXT5066: init\n");
3002         conexant_init(codec);
3003         cxt5066_hp_automute(codec);
3004         if (!spec->dc_enable) {
3005                 cxt5066_set_mic_boost(codec);
3006                 cxt5066_olpc_automic(codec);
3007         } else {
3008                 cxt5066_enable_dc(codec);
3009         }
3010         return 0;
3011 }
3012
3013 enum {
3014         CXT5066_LAPTOP,         /* Laptops w/ EAPD support */
3015         CXT5066_DELL_LAPTOP,    /* Dell Laptop */
3016         CXT5066_OLPC_XO_1_5,    /* OLPC XO 1.5 */
3017         CXT5066_DELL_VOSTRO,    /* Dell Vostro 1015i */
3018         CXT5066_IDEAPAD,        /* Lenovo IdeaPad U150 */
3019         CXT5066_THINKPAD,       /* Lenovo ThinkPad T410s, others? */
3020         CXT5066_ASUS,           /* Asus K52JU, Lenovo G560 - Int mic at 0x1a and Ext mic at 0x1b */
3021         CXT5066_HP_LAPTOP,      /* HP Laptop */
3022         CXT5066_MODELS
3023 };
3024
3025 static const char * const cxt5066_models[CXT5066_MODELS] = {
3026         [CXT5066_LAPTOP]        = "laptop",
3027         [CXT5066_DELL_LAPTOP]   = "dell-laptop",
3028         [CXT5066_OLPC_XO_1_5]   = "olpc-xo-1_5",
3029         [CXT5066_DELL_VOSTRO]   = "dell-vostro",
3030         [CXT5066_IDEAPAD]       = "ideapad",
3031         [CXT5066_THINKPAD]      = "thinkpad",
3032         [CXT5066_ASUS]          = "asus",
3033         [CXT5066_HP_LAPTOP]     = "hp-laptop",
3034 };
3035
3036 static const struct snd_pci_quirk cxt5066_cfg_tbl[] = {
3037         SND_PCI_QUIRK_MASK(0x1025, 0xff00, 0x0400, "Acer", CXT5066_IDEAPAD),
3038         SND_PCI_QUIRK(0x1028, 0x02d8, "Dell Vostro", CXT5066_DELL_VOSTRO),
3039         SND_PCI_QUIRK(0x1028, 0x02f5, "Dell Vostro 320", CXT5066_IDEAPAD),
3040         SND_PCI_QUIRK(0x1028, 0x0401, "Dell Vostro 1014", CXT5066_DELL_VOSTRO),
3041         SND_PCI_QUIRK(0x1028, 0x0402, "Dell Vostro", CXT5066_DELL_VOSTRO),
3042         SND_PCI_QUIRK(0x1028, 0x0408, "Dell Inspiron One 19T", CXT5066_IDEAPAD),
3043         SND_PCI_QUIRK(0x1028, 0x050f, "Dell Inspiron", CXT5066_IDEAPAD),
3044         SND_PCI_QUIRK(0x1028, 0x0510, "Dell Vostro", CXT5066_IDEAPAD),
3045         SND_PCI_QUIRK(0x103c, 0x360b, "HP G60", CXT5066_HP_LAPTOP),
3046         SND_PCI_QUIRK(0x1043, 0x13f3, "Asus A52J", CXT5066_ASUS),
3047         SND_PCI_QUIRK(0x1043, 0x1643, "Asus K52JU", CXT5066_ASUS),
3048         SND_PCI_QUIRK(0x1043, 0x1993, "Asus U50F", CXT5066_ASUS),
3049         SND_PCI_QUIRK(0x1179, 0xff1e, "Toshiba Satellite C650D", CXT5066_IDEAPAD),
3050         SND_PCI_QUIRK(0x1179, 0xff50, "Toshiba Satellite P500-PSPGSC-01800T", CXT5066_OLPC_XO_1_5),
3051         SND_PCI_QUIRK(0x1179, 0xffe0, "Toshiba Satellite Pro T130-15F", CXT5066_OLPC_XO_1_5),
3052         SND_PCI_QUIRK(0x14f1, 0x0101, "Conexant Reference board",
3053                       CXT5066_LAPTOP),
3054         SND_PCI_QUIRK(0x152d, 0x0833, "OLPC XO-1.5", CXT5066_OLPC_XO_1_5),
3055         SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo T400s", CXT5066_THINKPAD),
3056         SND_PCI_QUIRK(0x17aa, 0x21c5, "Thinkpad Edge 13", CXT5066_THINKPAD),
3057         SND_PCI_QUIRK(0x17aa, 0x21c6, "Thinkpad Edge 13", CXT5066_ASUS),
3058         SND_PCI_QUIRK(0x17aa, 0x215e, "Lenovo Thinkpad", CXT5066_THINKPAD),
3059         SND_PCI_QUIRK(0x17aa, 0x21da, "Lenovo X220", CXT5066_THINKPAD),
3060         SND_PCI_QUIRK(0x17aa, 0x21db, "Lenovo X220-tablet", CXT5066_THINKPAD),
3061         SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo G560", CXT5066_ASUS),
3062         SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", CXT5066_IDEAPAD), /* Fallback for Lenovos without dock mic */
3063         {}
3064 };
3065
3066 static int patch_cxt5066(struct hda_codec *codec)
3067 {
3068         struct conexant_spec *spec;
3069         int board_config;
3070
3071         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
3072         if (!spec)
3073                 return -ENOMEM;
3074         codec->spec = spec;
3075
3076         codec->patch_ops = conexant_patch_ops;
3077         codec->patch_ops.init = conexant_init;
3078
3079         spec->dell_automute = 0;
3080         spec->multiout.max_channels = 2;
3081         spec->multiout.num_dacs = ARRAY_SIZE(cxt5066_dac_nids);
3082         spec->multiout.dac_nids = cxt5066_dac_nids;
3083         conexant_check_dig_outs(codec, cxt5066_digout_pin_nids,
3084             ARRAY_SIZE(cxt5066_digout_pin_nids));
3085         spec->num_adc_nids = 1;
3086         spec->adc_nids = cxt5066_adc_nids;
3087         spec->capsrc_nids = cxt5066_capsrc_nids;
3088         spec->input_mux = &cxt5066_capture_source;
3089
3090         spec->port_d_mode = PIN_HP;
3091
3092         spec->num_init_verbs = 1;
3093         spec->init_verbs[0] = cxt5066_init_verbs;
3094         spec->num_channel_mode = ARRAY_SIZE(cxt5066_modes);
3095         spec->channel_mode = cxt5066_modes;
3096         spec->cur_adc = 0;
3097         spec->cur_adc_idx = 0;
3098
3099         set_beep_amp(spec, 0x13, 0, HDA_OUTPUT);
3100
3101         board_config = snd_hda_check_board_config(codec, CXT5066_MODELS,
3102                                                   cxt5066_models, cxt5066_cfg_tbl);
3103         switch (board_config) {
3104         default:
3105         case CXT5066_LAPTOP:
3106                 spec->mixers[spec->num_mixers++] = cxt5066_mixer_master;
3107                 spec->mixers[spec->num_mixers++] = cxt5066_mixers;
3108                 break;
3109         case CXT5066_DELL_LAPTOP:
3110                 spec->mixers[spec->num_mixers++] = cxt5066_mixer_master;
3111                 spec->mixers[spec->num_mixers++] = cxt5066_mixers;
3112
3113                 spec->port_d_mode = PIN_OUT;
3114                 spec->init_verbs[spec->num_init_verbs] = cxt5066_init_verbs_portd_lo;
3115                 spec->num_init_verbs++;
3116                 spec->dell_automute = 1;
3117                 break;
3118         case CXT5066_ASUS:
3119         case CXT5066_HP_LAPTOP:
3120                 codec->patch_ops.init = cxt5066_init;
3121                 codec->patch_ops.unsol_event = cxt5066_unsol_event;
3122                 spec->init_verbs[spec->num_init_verbs] =
3123                         cxt5066_init_verbs_hp_laptop;
3124                 spec->num_init_verbs++;
3125                 spec->hp_laptop = board_config == CXT5066_HP_LAPTOP;
3126                 spec->asus = board_config == CXT5066_ASUS;
3127                 spec->mixers[spec->num_mixers++] = cxt5066_mixer_master;
3128                 spec->mixers[spec->num_mixers++] = cxt5066_mixers;
3129                 /* no S/PDIF out */
3130                 if (board_config == CXT5066_HP_LAPTOP)
3131                         spec->multiout.dig_out_nid = 0;
3132                 /* input source automatically selected */
3133                 spec->input_mux = NULL;
3134                 spec->port_d_mode = 0;
3135                 spec->mic_boost = 3; /* default 30dB gain */
3136                 break;
3137
3138         case CXT5066_OLPC_XO_1_5:
3139                 codec->patch_ops.init = cxt5066_olpc_init;
3140                 codec->patch_ops.unsol_event = cxt5066_olpc_unsol_event;
3141                 spec->init_verbs[0] = cxt5066_init_verbs_olpc;
3142                 spec->mixers[spec->num_mixers++] = cxt5066_mixer_master_olpc;
3143                 spec->mixers[spec->num_mixers++] = cxt5066_mixer_olpc_dc;
3144                 spec->mixers[spec->num_mixers++] = cxt5066_mixers;
3145                 spec->port_d_mode = 0;
3146                 spec->mic_boost = 3; /* default 30dB gain */
3147
3148                 /* no S/PDIF out */
3149                 spec->multiout.dig_out_nid = 0;
3150
3151                 /* input source automatically selected */
3152                 spec->input_mux = NULL;
3153
3154                 /* our capture hooks which allow us to turn on the microphone LED
3155                  * at the right time */
3156                 spec->capture_prepare = cxt5066_olpc_capture_prepare;
3157                 spec->capture_cleanup = cxt5066_olpc_capture_cleanup;
3158                 break;
3159         case CXT5066_DELL_VOSTRO:
3160                 codec->patch_ops.init = cxt5066_init;
3161                 codec->patch_ops.unsol_event = cxt5066_unsol_event;
3162                 spec->init_verbs[0] = cxt5066_init_verbs_vostro;
3163                 spec->mixers[spec->num_mixers++] = cxt5066_mixer_master_olpc;
3164                 spec->mixers[spec->num_mixers++] = cxt5066_mixers;
3165                 spec->mixers[spec->num_mixers++] = cxt5066_vostro_mixers;
3166                 spec->port_d_mode = 0;
3167                 spec->dell_vostro = 1;
3168                 spec->mic_boost = 3; /* default 30dB gain */
3169
3170                 /* no S/PDIF out */
3171                 spec->multiout.dig_out_nid = 0;
3172
3173                 /* input source automatically selected */
3174                 spec->input_mux = NULL;
3175                 break;
3176         case CXT5066_IDEAPAD:
3177                 codec->patch_ops.init = cxt5066_init;
3178                 codec->patch_ops.unsol_event = cxt5066_unsol_event;
3179                 spec->mixers[spec->num_mixers++] = cxt5066_mixer_master;
3180                 spec->mixers[spec->num_mixers++] = cxt5066_mixers;
3181                 spec->init_verbs[0] = cxt5066_init_verbs_ideapad;
3182                 spec->port_d_mode = 0;
3183                 spec->ideapad = 1;
3184                 spec->mic_boost = 2;    /* default 20dB gain */
3185
3186                 /* no S/PDIF out */
3187                 spec->multiout.dig_out_nid = 0;
3188
3189                 /* input source automatically selected */
3190                 spec->input_mux = NULL;
3191                 break;
3192         case CXT5066_THINKPAD:
3193                 codec->patch_ops.init = cxt5066_init;
3194                 codec->patch_ops.unsol_event = cxt5066_unsol_event;
3195                 spec->mixers[spec->num_mixers++] = cxt5066_mixer_master;
3196                 spec->mixers[spec->num_mixers++] = cxt5066_mixers;
3197                 spec->init_verbs[0] = cxt5066_init_verbs_thinkpad;
3198                 spec->thinkpad = 1;
3199                 spec->port_d_mode = PIN_OUT;
3200                 spec->mic_boost = 2;    /* default 20dB gain */
3201
3202                 /* no S/PDIF out */
3203                 spec->multiout.dig_out_nid = 0;
3204
3205                 /* input source automatically selected */
3206                 spec->input_mux = NULL;
3207                 break;
3208         }
3209
3210         if (spec->beep_amp)
3211                 snd_hda_attach_beep_device(codec, spec->beep_amp);
3212
3213         return 0;
3214 }
3215
3216 /*
3217  * Automatic parser for CX20641 & co
3218  */
3219
3220 static int cx_auto_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
3221                                        struct hda_codec *codec,
3222                                        unsigned int stream_tag,
3223                                        unsigned int format,
3224                                        struct snd_pcm_substream *substream)
3225 {
3226         struct conexant_spec *spec = codec->spec;
3227         hda_nid_t adc = spec->imux_adcs[spec->cur_mux[0]];
3228         if (spec->adc_switching) {
3229                 spec->cur_adc = adc;
3230                 spec->cur_adc_stream_tag = stream_tag;
3231                 spec->cur_adc_format = format;
3232         }
3233         snd_hda_codec_setup_stream(codec, adc, stream_tag, 0, format);
3234         return 0;
3235 }
3236
3237 static int cx_auto_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
3238                                        struct hda_codec *codec,
3239                                        struct snd_pcm_substream *substream)
3240 {
3241         struct conexant_spec *spec = codec->spec;
3242         snd_hda_codec_cleanup_stream(codec, spec->cur_adc);
3243         spec->cur_adc = 0;
3244         return 0;
3245 }
3246
3247 static const struct hda_pcm_stream cx_auto_pcm_analog_capture = {
3248         .substreams = 1,
3249         .channels_min = 2,
3250         .channels_max = 2,
3251         .nid = 0, /* fill later */
3252         .ops = {
3253                 .prepare = cx_auto_capture_pcm_prepare,
3254                 .cleanup = cx_auto_capture_pcm_cleanup
3255         },
3256 };
3257
3258 static const hda_nid_t cx_auto_adc_nids[] = { 0x14 };
3259
3260 /* get the connection index of @nid in the widget @mux */
3261 static int get_connection_index(struct hda_codec *codec, hda_nid_t mux,
3262                                 hda_nid_t nid)
3263 {
3264         hda_nid_t conn[HDA_MAX_NUM_INPUTS];
3265         int i, nums;
3266
3267         nums = snd_hda_get_connections(codec, mux, conn, ARRAY_SIZE(conn));
3268         for (i = 0; i < nums; i++)
3269                 if (conn[i] == nid)
3270                         return i;
3271         return -1;
3272 }
3273
3274 static int has_multi_connection(struct hda_codec *codec, hda_nid_t mux)
3275 {
3276         hda_nid_t conn[HDA_MAX_NUM_INPUTS];
3277         int nums;
3278
3279         nums = snd_hda_get_connections(codec, mux, conn, ARRAY_SIZE(conn));
3280         return nums > 1;
3281 }
3282
3283 /* get an unassigned DAC from the given list.
3284  * Return the nid if found and reduce the DAC list, or return zero if
3285  * not found
3286  */
3287 static hda_nid_t get_unassigned_dac(struct hda_codec *codec, hda_nid_t pin,
3288                                     hda_nid_t *dacs, int *num_dacs)
3289 {
3290         int i, nums = *num_dacs;
3291         hda_nid_t ret = 0;
3292
3293         for (i = 0; i < nums; i++) {
3294                 if (get_connection_index(codec, pin, dacs[i]) >= 0) {
3295                         ret = dacs[i];
3296                         break;
3297                 }
3298         }
3299         if (!ret)
3300                 return 0;
3301         if (--nums > 0)
3302                 memmove(dacs, dacs + 1, nums * sizeof(hda_nid_t));
3303         *num_dacs = nums;
3304         return ret;
3305 }
3306
3307 #define MAX_AUTO_DACS   5
3308
3309 /* fill analog DAC list from the widget tree */
3310 static int fill_cx_auto_dacs(struct hda_codec *codec, hda_nid_t *dacs)
3311 {
3312         hda_nid_t nid, end_nid;
3313         int nums = 0;
3314
3315         end_nid = codec->start_nid + codec->num_nodes;
3316         for (nid = codec->start_nid; nid < end_nid; nid++) {
3317                 unsigned int wcaps = get_wcaps(codec, nid);
3318                 unsigned int type = get_wcaps_type(wcaps);
3319                 if (type == AC_WID_AUD_OUT && !(wcaps & AC_WCAP_DIGITAL)) {
3320                         dacs[nums++] = nid;
3321                         if (nums >= MAX_AUTO_DACS)
3322                                 break;
3323                 }
3324         }
3325         return nums;
3326 }
3327
3328 /* fill pin_dac_pair list from the pin and dac list */
3329 static int fill_dacs_for_pins(struct hda_codec *codec, hda_nid_t *pins,
3330                               int num_pins, hda_nid_t *dacs, int *rest,
3331                               struct pin_dac_pair *filled, int type)
3332 {
3333         int i, nums;
3334
3335         nums = 0;
3336         for (i = 0; i < num_pins; i++) {
3337                 filled[nums].pin = pins[i];
3338                 filled[nums].type = type;
3339                 filled[nums].dac = get_unassigned_dac(codec, pins[i], dacs, rest);
3340                 nums++;
3341         }
3342         return nums;
3343 }
3344
3345 /* parse analog output paths */
3346 static void cx_auto_parse_output(struct hda_codec *codec)
3347 {
3348         struct conexant_spec *spec = codec->spec;
3349         struct auto_pin_cfg *cfg = &spec->autocfg;
3350         hda_nid_t dacs[MAX_AUTO_DACS];
3351         int i, j, nums, rest;
3352
3353         rest = fill_cx_auto_dacs(codec, dacs);
3354         /* parse all analog output pins */
3355         nums = fill_dacs_for_pins(codec, cfg->line_out_pins, cfg->line_outs,
3356                                   dacs, &rest, spec->dac_info,
3357                                   AUTO_PIN_LINE_OUT);
3358         nums += fill_dacs_for_pins(codec, cfg->hp_pins, cfg->hp_outs,
3359                                   dacs, &rest, spec->dac_info + nums,
3360                                   AUTO_PIN_HP_OUT);
3361         nums += fill_dacs_for_pins(codec, cfg->speaker_pins, cfg->speaker_outs,
3362                                   dacs, &rest, spec->dac_info + nums,
3363                                   AUTO_PIN_SPEAKER_OUT);
3364         spec->dac_info_filled = nums;
3365         /* fill multiout struct */
3366         for (i = 0; i < nums; i++) {
3367                 hda_nid_t dac = spec->dac_info[i].dac;
3368                 if (!dac)
3369                         continue;
3370                 switch (spec->dac_info[i].type) {
3371                 case AUTO_PIN_LINE_OUT:
3372                         spec->private_dac_nids[spec->multiout.num_dacs] = dac;
3373                         spec->multiout.num_dacs++;
3374                         break;
3375                 case AUTO_PIN_HP_OUT:
3376                 case AUTO_PIN_SPEAKER_OUT:
3377                         if (!spec->multiout.hp_nid) {
3378                                 spec->multiout.hp_nid = dac;
3379                                 break;
3380                         }
3381                         for (j = 0; j < ARRAY_SIZE(spec->multiout.extra_out_nid); j++)
3382                                 if (!spec->multiout.extra_out_nid[j]) {
3383                                         spec->multiout.extra_out_nid[j] = dac;
3384                                         break;
3385                                 }
3386                         break;
3387                 }
3388         }
3389         spec->multiout.dac_nids = spec->private_dac_nids;
3390         spec->multiout.max_channels = spec->multiout.num_dacs * 2;
3391
3392         if (cfg->hp_outs > 0)
3393                 spec->auto_mute = 1;
3394         spec->vmaster_nid = spec->private_dac_nids[0];
3395 }
3396
3397 static void cx_auto_turn_eapd(struct hda_codec *codec, int num_pins,
3398                               hda_nid_t *pins, bool on);
3399
3400 /* auto-mute/unmute speaker and line outs according to headphone jack */
3401 static void cx_auto_hp_automute(struct hda_codec *codec)
3402 {
3403         struct conexant_spec *spec = codec->spec;
3404         struct auto_pin_cfg *cfg = &spec->autocfg;
3405         int i, present;
3406
3407         if (!spec->auto_mute)
3408                 return;
3409         present = 0;
3410         for (i = 0; i < cfg->hp_outs; i++) {
3411                 if (snd_hda_jack_detect(codec, cfg->hp_pins[i])) {
3412                         present = 1;
3413                         break;
3414                 }
3415         }
3416         cx_auto_turn_eapd(codec, cfg->hp_outs, cfg->hp_pins, present);
3417         for (i = 0; i < cfg->line_outs; i++) {
3418                 snd_hda_codec_write(codec, cfg->line_out_pins[i], 0,
3419                                     AC_VERB_SET_PIN_WIDGET_CONTROL,
3420                                     present ? 0 : PIN_OUT);
3421         }
3422         cx_auto_turn_eapd(codec, cfg->line_outs, cfg->line_out_pins, !present);
3423         for (i = 0; !present && i < cfg->line_outs; i++)
3424                 if (snd_hda_jack_detect(codec, cfg->line_out_pins[i]))
3425                         present = 1;
3426         for (i = 0; i < cfg->speaker_outs; i++) {
3427                 snd_hda_codec_write(codec, cfg->speaker_pins[i], 0,
3428                                     AC_VERB_SET_PIN_WIDGET_CONTROL,
3429                                     present ? 0 : PIN_OUT);
3430         }
3431         cx_auto_turn_eapd(codec, cfg->speaker_outs, cfg->speaker_pins, !present);
3432 }
3433
3434 static int cx_auto_mux_enum_info(struct snd_kcontrol *kcontrol,
3435                                  struct snd_ctl_elem_info *uinfo)
3436 {
3437         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3438         struct conexant_spec *spec = codec->spec;
3439
3440         return snd_hda_input_mux_info(&spec->private_imux, uinfo);
3441 }
3442
3443 static int cx_auto_mux_enum_get(struct snd_kcontrol *kcontrol,
3444                                 struct snd_ctl_elem_value *ucontrol)
3445 {
3446         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3447         struct conexant_spec *spec = codec->spec;
3448
3449         ucontrol->value.enumerated.item[0] = spec->cur_mux[0];
3450         return 0;
3451 }
3452
3453 static int cx_auto_mux_enum_update(struct hda_codec *codec,
3454                                    const struct hda_input_mux *imux,
3455                                    unsigned int idx)
3456 {
3457         struct conexant_spec *spec = codec->spec;
3458         hda_nid_t adc;
3459
3460         if (!imux->num_items)
3461                 return 0;
3462         if (idx >= imux->num_items)
3463                 idx = imux->num_items - 1;
3464         if (spec->cur_mux[0] == idx)
3465                 return 0;
3466         adc = spec->imux_adcs[idx];
3467         if (has_multi_connection(codec, adc))
3468                 snd_hda_codec_write(codec, adc, 0,
3469                                     AC_VERB_SET_CONNECT_SEL,
3470                                     imux->items[idx].index);
3471         if (spec->cur_adc && spec->cur_adc != adc) {
3472                 /* stream is running, let's swap the current ADC */
3473                 __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1);
3474                 spec->cur_adc = adc;
3475                 snd_hda_codec_setup_stream(codec, adc,
3476                                            spec->cur_adc_stream_tag, 0,
3477                                            spec->cur_adc_format);
3478         }
3479         spec->cur_mux[0] = idx;
3480         return 1;
3481 }
3482
3483 static int cx_auto_mux_enum_put(struct snd_kcontrol *kcontrol,
3484                                 struct snd_ctl_elem_value *ucontrol)
3485 {
3486         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3487         struct conexant_spec *spec = codec->spec;
3488
3489         return cx_auto_mux_enum_update(codec, &spec->private_imux,
3490                                        ucontrol->value.enumerated.item[0]);
3491 }
3492
3493 static const struct snd_kcontrol_new cx_auto_capture_mixers[] = {
3494         {
3495                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3496                 .name = "Capture Source",
3497                 .info = cx_auto_mux_enum_info,
3498                 .get = cx_auto_mux_enum_get,
3499                 .put = cx_auto_mux_enum_put
3500         },
3501         {}
3502 };
3503
3504 /* automatic switch internal and external mic */
3505 static void cx_auto_automic(struct hda_codec *codec)
3506 {
3507         struct conexant_spec *spec = codec->spec;
3508         struct auto_pin_cfg *cfg = &spec->autocfg;
3509         int ext_idx = spec->auto_mic_ext;
3510
3511         if (!spec->auto_mic)
3512                 return;
3513         if (snd_hda_jack_detect(codec, cfg->inputs[ext_idx].pin))
3514                 cx_auto_mux_enum_update(codec, &spec->private_imux, ext_idx);
3515         else
3516                 cx_auto_mux_enum_update(codec, &spec->private_imux, !ext_idx);
3517 }
3518
3519 static void cx_auto_unsol_event(struct hda_codec *codec, unsigned int res)
3520 {
3521         int nid = (res & AC_UNSOL_RES_SUBTAG) >> 20;
3522         switch (res >> 26) {
3523         case CONEXANT_HP_EVENT:
3524                 cx_auto_hp_automute(codec);
3525                 snd_hda_input_jack_report(codec, nid);
3526                 break;
3527         case CONEXANT_MIC_EVENT:
3528                 cx_auto_automic(codec);
3529                 snd_hda_input_jack_report(codec, nid);
3530                 break;
3531         }
3532 }
3533
3534 /* return true if it's an internal-mic pin */
3535 static int is_int_mic(struct hda_codec *codec, hda_nid_t pin)
3536 {
3537         unsigned int def_conf = snd_hda_codec_get_pincfg(codec, pin);
3538         return get_defcfg_device(def_conf) == AC_JACK_MIC_IN &&
3539                 snd_hda_get_input_pin_attr(def_conf) == INPUT_PIN_ATTR_INT;
3540 }
3541
3542 /* return true if it's an external-mic pin */
3543 static int is_ext_mic(struct hda_codec *codec, hda_nid_t pin)
3544 {
3545         unsigned int def_conf = snd_hda_codec_get_pincfg(codec, pin);
3546         return get_defcfg_device(def_conf) == AC_JACK_MIC_IN &&
3547                 snd_hda_get_input_pin_attr(def_conf) >= INPUT_PIN_ATTR_NORMAL &&
3548                 (snd_hda_query_pin_caps(codec, pin) & AC_PINCAP_PRES_DETECT);
3549 }
3550
3551 /* check whether the pin config is suitable for auto-mic switching;
3552  * auto-mic is enabled only when one int-mic and one-ext mic exist
3553  */
3554 static void cx_auto_check_auto_mic(struct hda_codec *codec)
3555 {
3556         struct conexant_spec *spec = codec->spec;
3557         struct auto_pin_cfg *cfg = &spec->autocfg;
3558
3559         if (is_ext_mic(codec, cfg->inputs[0].pin) &&
3560             is_int_mic(codec, cfg->inputs[1].pin)) {
3561                 spec->auto_mic = 1;
3562                 spec->auto_mic_ext = 0;
3563                 return;
3564         }
3565         if (is_int_mic(codec, cfg->inputs[0].pin) &&
3566             is_ext_mic(codec, cfg->inputs[1].pin)) {
3567                 spec->auto_mic = 1;
3568                 spec->auto_mic_ext = 1;
3569                 return;
3570         }
3571 }
3572
3573 static void cx_auto_parse_input(struct hda_codec *codec)
3574 {
3575         struct conexant_spec *spec = codec->spec;
3576         struct auto_pin_cfg *cfg = &spec->autocfg;
3577         struct hda_input_mux *imux;
3578         int i, j;
3579
3580         imux = &spec->private_imux;
3581         for (i = 0; i < cfg->num_inputs; i++) {
3582                 for (j = 0; j < spec->num_adc_nids; j++) {
3583                         hda_nid_t adc = spec->adc_nids[j];
3584                         int idx = get_connection_index(codec, adc,
3585                                                cfg->inputs[i].pin);
3586                         if (idx >= 0) {
3587                                 const char *label;
3588                                 label = hda_get_autocfg_input_label(codec, cfg, i);
3589                                 snd_hda_add_imux_item(imux, label, idx, NULL);
3590                                 spec->imux_adcs[i] = adc;
3591                                 break;
3592                         }
3593                 }
3594         }
3595         if (imux->num_items == 2 && cfg->num_inputs == 2)
3596                 cx_auto_check_auto_mic(codec);
3597         if (imux->num_items > 1 && !spec->auto_mic) {
3598                 for (i = 1; i < imux->num_items; i++) {
3599                         if (spec->imux_adcs[i] != spec->imux_adcs[0]) {
3600                                 spec->adc_switching = 1;
3601                                 break;
3602                         }
3603                 }
3604         }
3605 }
3606
3607 /* get digital-input audio widget corresponding to the given pin */
3608 static hda_nid_t cx_auto_get_dig_in(struct hda_codec *codec, hda_nid_t pin)
3609 {
3610         hda_nid_t nid, end_nid;
3611
3612         end_nid = codec->start_nid + codec->num_nodes;
3613         for (nid = codec->start_nid; nid < end_nid; nid++) {
3614                 unsigned int wcaps = get_wcaps(codec, nid);
3615                 unsigned int type = get_wcaps_type(wcaps);
3616                 if (type == AC_WID_AUD_IN && (wcaps & AC_WCAP_DIGITAL)) {
3617                         if (get_connection_index(codec, nid, pin) >= 0)
3618                                 return nid;
3619                 }
3620         }
3621         return 0;
3622 }
3623
3624 static void cx_auto_parse_digital(struct hda_codec *codec)
3625 {
3626         struct conexant_spec *spec = codec->spec;
3627         struct auto_pin_cfg *cfg = &spec->autocfg;
3628         hda_nid_t nid;
3629
3630         if (cfg->dig_outs &&
3631             snd_hda_get_connections(codec, cfg->dig_out_pins[0], &nid, 1) == 1)
3632                 spec->multiout.dig_out_nid = nid;
3633         if (cfg->dig_in_pin)
3634                 spec->dig_in_nid = cx_auto_get_dig_in(codec, cfg->dig_in_pin);
3635 }
3636
3637 #ifdef CONFIG_SND_HDA_INPUT_BEEP
3638 static void cx_auto_parse_beep(struct hda_codec *codec)
3639 {
3640         struct conexant_spec *spec = codec->spec;
3641         hda_nid_t nid, end_nid;
3642
3643         end_nid = codec->start_nid + codec->num_nodes;
3644         for (nid = codec->start_nid; nid < end_nid; nid++)
3645                 if (get_wcaps_type(get_wcaps(codec, nid)) == AC_WID_BEEP) {
3646                         set_beep_amp(spec, nid, 0, HDA_OUTPUT);
3647                         break;
3648                 }
3649 }
3650 #else
3651 #define cx_auto_parse_beep(codec)
3652 #endif
3653
3654 static int cx_auto_parse_auto_config(struct hda_codec *codec)
3655 {
3656         struct conexant_spec *spec = codec->spec;
3657         int err;
3658
3659         err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
3660         if (err < 0)
3661                 return err;
3662
3663         cx_auto_parse_output(codec);
3664         cx_auto_parse_input(codec);
3665         cx_auto_parse_digital(codec);
3666         cx_auto_parse_beep(codec);
3667         return 0;
3668 }
3669
3670 static void cx_auto_turn_eapd(struct hda_codec *codec, int num_pins,
3671                               hda_nid_t *pins, bool on)
3672 {
3673         int i;
3674         for (i = 0; i < num_pins; i++) {
3675                 if (snd_hda_query_pin_caps(codec, pins[i]) & AC_PINCAP_EAPD)
3676                         snd_hda_codec_write(codec, pins[i], 0,
3677                                             AC_VERB_SET_EAPD_BTLENABLE,
3678                                             on ? 0x02 : 0);
3679         }
3680 }
3681
3682 static void select_connection(struct hda_codec *codec, hda_nid_t pin,
3683                               hda_nid_t src)
3684 {
3685         int idx = get_connection_index(codec, pin, src);
3686         if (idx >= 0)
3687                 snd_hda_codec_write(codec, pin, 0,
3688                                     AC_VERB_SET_CONNECT_SEL, idx);
3689 }
3690
3691 static void cx_auto_init_output(struct hda_codec *codec)
3692 {
3693         struct conexant_spec *spec = codec->spec;
3694         struct auto_pin_cfg *cfg = &spec->autocfg;
3695         hda_nid_t nid;
3696         int i, val;
3697
3698         for (i = 0; i < spec->multiout.num_dacs; i++) {
3699                 nid = spec->multiout.dac_nids[i];
3700                 if (query_amp_caps(codec, nid, HDA_OUTPUT) & AC_AMPCAP_MUTE)
3701                         val = AMP_OUT_MUTE;
3702                 else
3703                         val = AMP_OUT_ZERO;
3704                 snd_hda_codec_write(codec, nid, 0,
3705                                     AC_VERB_SET_AMP_GAIN_MUTE, val);
3706         }
3707
3708         for (i = 0; i < cfg->hp_outs; i++)
3709                 snd_hda_codec_write(codec, cfg->hp_pins[i], 0,
3710                                     AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP);
3711         if (spec->auto_mute) {
3712                 for (i = 0; i < cfg->hp_outs; i++) {
3713                         snd_hda_codec_write(codec, cfg->hp_pins[i], 0,
3714                                     AC_VERB_SET_UNSOLICITED_ENABLE,
3715                                     AC_USRSP_EN | CONEXANT_HP_EVENT);
3716                 }
3717                 cx_auto_hp_automute(codec);
3718         } else {
3719                 for (i = 0; i < cfg->line_outs; i++)
3720                         snd_hda_codec_write(codec, cfg->line_out_pins[i], 0,
3721                                     AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
3722                 for (i = 0; i < cfg->speaker_outs; i++)
3723                         snd_hda_codec_write(codec, cfg->speaker_pins[i], 0,
3724                                     AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
3725                 /* turn on EAPD */
3726                 cx_auto_turn_eapd(codec, cfg->line_outs, cfg->line_out_pins,
3727                                   true);
3728                 cx_auto_turn_eapd(codec, cfg->hp_outs, cfg->hp_pins,
3729                                   true);
3730                 cx_auto_turn_eapd(codec, cfg->speaker_outs, cfg->speaker_pins,
3731                                   true);
3732         }
3733
3734         for (i = 0; i < spec->dac_info_filled; i++) {
3735                 nid = spec->dac_info[i].dac;
3736                 if (!nid)
3737                         nid = spec->multiout.dac_nids[0];
3738                 select_connection(codec, spec->dac_info[i].pin, nid);
3739         }
3740 }
3741
3742 static void cx_auto_init_input(struct hda_codec *codec)
3743 {
3744         struct conexant_spec *spec = codec->spec;
3745         struct auto_pin_cfg *cfg = &spec->autocfg;
3746         int i, val;
3747
3748         for (i = 0; i < spec->num_adc_nids; i++) {
3749                 hda_nid_t nid = spec->adc_nids[i];
3750                 if (query_amp_caps(codec, nid, HDA_INPUT) & AC_AMPCAP_MUTE)
3751                         val = AMP_IN_MUTE(0);
3752                 else
3753                         val = AMP_IN_UNMUTE(0);
3754                 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
3755                                     val);
3756         }
3757
3758         for (i = 0; i < cfg->num_inputs; i++) {
3759                 unsigned int type;
3760                 if (cfg->inputs[i].type == AUTO_PIN_MIC)
3761                         type = PIN_VREF80;
3762                 else
3763                         type = PIN_IN;
3764                 snd_hda_codec_write(codec, cfg->inputs[i].pin, 0,
3765                                     AC_VERB_SET_PIN_WIDGET_CONTROL, type);
3766         }
3767
3768         if (spec->auto_mic) {
3769                 int ext_idx = spec->auto_mic_ext;
3770                 snd_hda_codec_write(codec, cfg->inputs[ext_idx].pin, 0,
3771                                     AC_VERB_SET_UNSOLICITED_ENABLE,
3772                                     AC_USRSP_EN | CONEXANT_MIC_EVENT);
3773                 cx_auto_automic(codec);
3774         } else {
3775                 for (i = 0; i < spec->num_adc_nids; i++) {
3776                         snd_hda_codec_write(codec, spec->adc_nids[i], 0,
3777                                             AC_VERB_SET_CONNECT_SEL,
3778                                             spec->private_imux.items[0].index);
3779                 }
3780         }
3781 }
3782
3783 static void cx_auto_init_digital(struct hda_codec *codec)
3784 {
3785         struct conexant_spec *spec = codec->spec;
3786         struct auto_pin_cfg *cfg = &spec->autocfg;
3787
3788         if (spec->multiout.dig_out_nid)
3789                 snd_hda_codec_write(codec, cfg->dig_out_pins[0], 0,
3790                                     AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
3791         if (spec->dig_in_nid)
3792                 snd_hda_codec_write(codec, cfg->dig_in_pin, 0,
3793                                     AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN);
3794 }
3795
3796 static int cx_auto_init(struct hda_codec *codec)
3797 {
3798         /*snd_hda_sequence_write(codec, cx_auto_init_verbs);*/
3799         cx_auto_init_output(codec);
3800         cx_auto_init_input(codec);
3801         cx_auto_init_digital(codec);
3802         return 0;
3803 }
3804
3805 static int cx_auto_add_volume_idx(struct hda_codec *codec, const char *basename,
3806                               const char *dir, int cidx,
3807                               hda_nid_t nid, int hda_dir, int amp_idx)
3808 {
3809         static char name[32];
3810         static struct snd_kcontrol_new knew[] = {
3811                 HDA_CODEC_VOLUME(name, 0, 0, 0),
3812                 HDA_CODEC_MUTE(name, 0, 0, 0),
3813         };
3814         static const char * const sfx[2] = { "Volume", "Switch" };
3815         int i, err;
3816
3817         for (i = 0; i < 2; i++) {
3818                 struct snd_kcontrol *kctl;
3819                 knew[i].private_value = HDA_COMPOSE_AMP_VAL(nid, 3, amp_idx,
3820                                                             hda_dir);
3821                 knew[i].subdevice = HDA_SUBDEV_AMP_FLAG;
3822                 knew[i].index = cidx;
3823                 snprintf(name, sizeof(name), "%s%s %s", basename, dir, sfx[i]);
3824                 kctl = snd_ctl_new1(&knew[i], codec);
3825                 if (!kctl)
3826                         return -ENOMEM;
3827                 err = snd_hda_ctl_add(codec, nid, kctl);
3828                 if (err < 0)
3829                         return err;
3830                 if (!(query_amp_caps(codec, nid, hda_dir) & AC_AMPCAP_MUTE))
3831                         break;
3832         }
3833         return 0;
3834 }
3835
3836 #define cx_auto_add_volume(codec, str, dir, cidx, nid, hda_dir)         \
3837         cx_auto_add_volume_idx(codec, str, dir, cidx, nid, hda_dir, 0)
3838
3839 #define cx_auto_add_pb_volume(codec, nid, str, idx)                     \
3840         cx_auto_add_volume(codec, str, " Playback", idx, nid, HDA_OUTPUT)
3841
3842 static int cx_auto_build_output_controls(struct hda_codec *codec)
3843 {
3844         struct conexant_spec *spec = codec->spec;
3845         int i, err;
3846         int num_line = 0, num_hp = 0, num_spk = 0;
3847         static const char * const texts[3] = { "Front", "Surround", "CLFE" };
3848
3849         if (spec->dac_info_filled == 1)
3850                 return cx_auto_add_pb_volume(codec, spec->dac_info[0].dac,
3851                                              "Master", 0);
3852         for (i = 0; i < spec->dac_info_filled; i++) {
3853                 const char *label;
3854                 int idx, type;
3855                 if (!spec->dac_info[i].dac)
3856                         continue;
3857                 type = spec->dac_info[i].type;
3858                 if (type == AUTO_PIN_LINE_OUT)
3859                         type = spec->autocfg.line_out_type;
3860                 switch (type) {
3861                 case AUTO_PIN_LINE_OUT:
3862                 default:
3863                         label = texts[num_line++];
3864                         idx = 0;
3865                         break;
3866                 case AUTO_PIN_HP_OUT:
3867                         label = "Headphone";
3868                         idx = num_hp++;
3869                         break;
3870                 case AUTO_PIN_SPEAKER_OUT:
3871                         label = "Speaker";
3872                         idx = num_spk++;
3873                         break;
3874                 }
3875                 err = cx_auto_add_pb_volume(codec, spec->dac_info[i].dac,
3876                                             label, idx);
3877                 if (err < 0)
3878                         return err;
3879         }
3880         return 0;
3881 }
3882
3883 static int cx_auto_add_capture_volume(struct hda_codec *codec, hda_nid_t nid,
3884                                       const char *label, const char *pfx,
3885                                       int cidx)
3886 {
3887         struct conexant_spec *spec = codec->spec;
3888         int i;
3889
3890         for (i = 0; i < spec->num_adc_nids; i++) {
3891                 hda_nid_t adc_nid = spec->adc_nids[i];
3892                 int idx = get_connection_index(codec, adc_nid, nid);
3893                 if (idx < 0)
3894                         continue;
3895                 return cx_auto_add_volume_idx(codec, label, pfx,
3896                                               cidx, adc_nid, HDA_INPUT, idx);
3897         }
3898         return 0;
3899 }
3900
3901 static int cx_auto_build_input_controls(struct hda_codec *codec)
3902 {
3903         struct conexant_spec *spec = codec->spec;
3904         struct auto_pin_cfg *cfg = &spec->autocfg;
3905         static const char *prev_label;
3906         int i, err, cidx;
3907
3908         prev_label = NULL;
3909         cidx = 0;
3910         for (i = 0; i < cfg->num_inputs; i++) {
3911                 hda_nid_t nid = cfg->inputs[i].pin;
3912                 const char *label;
3913                 int pin_amp = get_wcaps(codec, nid) & AC_WCAP_IN_AMP;
3914
3915                 label = hda_get_autocfg_input_label(codec, cfg, i);
3916                 if (label == prev_label)
3917                         cidx++;
3918                 else
3919                         cidx = 0;
3920                 prev_label = label;
3921
3922                 if (pin_amp) {
3923                         err = cx_auto_add_volume(codec, label, " Boost", cidx,
3924                                                  nid, HDA_INPUT);
3925                         if (err < 0)
3926                                 return err;
3927                 }
3928
3929                 if (cfg->num_inputs == 1) {
3930                         err = cx_auto_add_capture_volume(codec, nid,
3931                                                          "Capture", "", cidx);
3932                 } else {
3933                         err = cx_auto_add_capture_volume(codec, nid,
3934                                                          label, " Capture", cidx);
3935                 }
3936                 if (err < 0)
3937                         return err;
3938         }
3939
3940         if (spec->private_imux.num_items > 1 && !spec->auto_mic) {
3941                 err = snd_hda_add_new_ctls(codec, cx_auto_capture_mixers);
3942                 if (err < 0)
3943                         return err;
3944         }
3945
3946         return 0;
3947 }
3948
3949 static int cx_auto_build_controls(struct hda_codec *codec)
3950 {
3951         int err;
3952
3953         err = cx_auto_build_output_controls(codec);
3954         if (err < 0)
3955                 return err;
3956         err = cx_auto_build_input_controls(codec);
3957         if (err < 0)
3958                 return err;
3959         return conexant_build_controls(codec);
3960 }
3961
3962 static const struct hda_codec_ops cx_auto_patch_ops = {
3963         .build_controls = cx_auto_build_controls,
3964         .build_pcms = conexant_build_pcms,
3965         .init = cx_auto_init,
3966         .free = conexant_free,
3967         .unsol_event = cx_auto_unsol_event,
3968 #ifdef CONFIG_SND_HDA_POWER_SAVE
3969         .suspend = conexant_suspend,
3970 #endif
3971         .reboot_notify = snd_hda_shutup_pins,
3972 };
3973
3974 static int patch_conexant_auto(struct hda_codec *codec)
3975 {
3976         struct conexant_spec *spec;
3977         int err;
3978
3979         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
3980         if (!spec)
3981                 return -ENOMEM;
3982         codec->spec = spec;
3983         if (codec->vendor_id == 0x14f15051) {
3984                 codec->pin_amp_workaround = 1;
3985                 spec->adc_nids = cxt5051_adc_nids;
3986                 spec->num_adc_nids = ARRAY_SIZE(cxt5051_adc_nids);
3987                 spec->capsrc_nids = spec->adc_nids;
3988         } else {
3989                 spec->adc_nids = cx_auto_adc_nids;
3990                 spec->num_adc_nids = ARRAY_SIZE(cx_auto_adc_nids);
3991                 spec->capsrc_nids = spec->adc_nids;
3992         }
3993         err = cx_auto_parse_auto_config(codec);
3994         if (err < 0) {
3995                 kfree(codec->spec);
3996                 codec->spec = NULL;
3997                 return err;
3998         }
3999         spec->capture_stream = &cx_auto_pcm_analog_capture;
4000         codec->patch_ops = cx_auto_patch_ops;
4001         if (spec->beep_amp)
4002                 snd_hda_attach_beep_device(codec, spec->beep_amp);
4003         return 0;
4004 }
4005
4006 /*
4007  */
4008
4009 static const struct hda_codec_preset snd_hda_preset_conexant[] = {
4010         { .id = 0x14f15045, .name = "CX20549 (Venice)",
4011           .patch = patch_cxt5045 },
4012         { .id = 0x14f15047, .name = "CX20551 (Waikiki)",
4013           .patch = patch_cxt5047 },
4014         { .id = 0x14f15051, .name = "CX20561 (Hermosa)",
4015           .patch = patch_cxt5051 },
4016         { .id = 0x14f15066, .name = "CX20582 (Pebble)",
4017           .patch = patch_cxt5066 },
4018         { .id = 0x14f15067, .name = "CX20583 (Pebble HSF)",
4019           .patch = patch_cxt5066 },
4020         { .id = 0x14f15068, .name = "CX20584",
4021           .patch = patch_cxt5066 },
4022         { .id = 0x14f15069, .name = "CX20585",
4023           .patch = patch_cxt5066 },
4024         { .id = 0x14f1506e, .name = "CX20590",
4025           .patch = patch_cxt5066 },
4026         { .id = 0x14f15097, .name = "CX20631",
4027           .patch = patch_conexant_auto },
4028         { .id = 0x14f15098, .name = "CX20632",
4029           .patch = patch_conexant_auto },
4030         { .id = 0x14f150a1, .name = "CX20641",
4031           .patch = patch_conexant_auto },
4032         { .id = 0x14f150a2, .name = "CX20642",
4033           .patch = patch_conexant_auto },
4034         { .id = 0x14f150ab, .name = "CX20651",
4035           .patch = patch_conexant_auto },
4036         { .id = 0x14f150ac, .name = "CX20652",
4037           .patch = patch_conexant_auto },
4038         { .id = 0x14f150b8, .name = "CX20664",
4039           .patch = patch_conexant_auto },
4040         { .id = 0x14f150b9, .name = "CX20665",
4041           .patch = patch_conexant_auto },
4042         {} /* terminator */
4043 };
4044
4045 MODULE_ALIAS("snd-hda-codec-id:14f15045");
4046 MODULE_ALIAS("snd-hda-codec-id:14f15047");
4047 MODULE_ALIAS("snd-hda-codec-id:14f15051");
4048 MODULE_ALIAS("snd-hda-codec-id:14f15066");
4049 MODULE_ALIAS("snd-hda-codec-id:14f15067");
4050 MODULE_ALIAS("snd-hda-codec-id:14f15068");
4051 MODULE_ALIAS("snd-hda-codec-id:14f15069");
4052 MODULE_ALIAS("snd-hda-codec-id:14f1506e");
4053 MODULE_ALIAS("snd-hda-codec-id:14f15097");
4054 MODULE_ALIAS("snd-hda-codec-id:14f15098");
4055 MODULE_ALIAS("snd-hda-codec-id:14f150a1");
4056 MODULE_ALIAS("snd-hda-codec-id:14f150a2");
4057 MODULE_ALIAS("snd-hda-codec-id:14f150ab");
4058 MODULE_ALIAS("snd-hda-codec-id:14f150ac");
4059 MODULE_ALIAS("snd-hda-codec-id:14f150b8");
4060 MODULE_ALIAS("snd-hda-codec-id:14f150b9");
4061
4062 MODULE_LICENSE("GPL");
4063 MODULE_DESCRIPTION("Conexant HD-audio codec");
4064
4065 static struct hda_codec_preset_list conexant_list = {
4066         .preset = snd_hda_preset_conexant,
4067         .owner = THIS_MODULE,
4068 };
4069
4070 static int __init patch_conexant_init(void)
4071 {
4072         return snd_hda_add_codec_preset(&conexant_list);
4073 }
4074
4075 static void __exit patch_conexant_exit(void)
4076 {
4077         snd_hda_delete_codec_preset(&conexant_list);
4078 }
4079
4080 module_init(patch_conexant_init)
4081 module_exit(patch_conexant_exit)