ALSA: hda - Fixed internal mic initialization for Dell Vostro 1015
[linux-2.6.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
33 #define CXT_PIN_DIR_IN              0x00
34 #define CXT_PIN_DIR_OUT             0x01
35 #define CXT_PIN_DIR_INOUT           0x02
36 #define CXT_PIN_DIR_IN_NOMICBIAS    0x03
37 #define CXT_PIN_DIR_INOUT_NOMICBIAS 0x04
38
39 #define CONEXANT_HP_EVENT       0x37
40 #define CONEXANT_MIC_EVENT      0x38
41
42 /* Conexant 5051 specific */
43
44 #define CXT5051_SPDIF_OUT       0x1C
45 #define CXT5051_PORTB_EVENT     0x38
46 #define CXT5051_PORTC_EVENT     0x39
47
48
49 struct conexant_jack {
50
51         hda_nid_t nid;
52         int type;
53         struct snd_jack *jack;
54
55 };
56
57 struct conexant_spec {
58
59         struct snd_kcontrol_new *mixers[5];
60         int num_mixers;
61         hda_nid_t vmaster_nid;
62
63         const struct hda_verb *init_verbs[5];   /* initialization verbs
64                                                  * don't forget NULL
65                                                  * termination!
66                                                  */
67         unsigned int num_init_verbs;
68
69         /* playback */
70         struct hda_multi_out multiout;  /* playback set-up
71                                          * max_channels, dacs must be set
72                                          * dig_out_nid and hp_nid are optional
73                                          */
74         unsigned int cur_eapd;
75         unsigned int hp_present;
76         unsigned int no_auto_mic;
77         unsigned int need_dac_fix;
78
79         /* capture */
80         unsigned int num_adc_nids;
81         hda_nid_t *adc_nids;
82         hda_nid_t dig_in_nid;           /* digital-in NID; optional */
83
84         unsigned int cur_adc_idx;
85         hda_nid_t cur_adc;
86         unsigned int cur_adc_stream_tag;
87         unsigned int cur_adc_format;
88
89         /* capture source */
90         const struct hda_input_mux *input_mux;
91         hda_nid_t *capsrc_nids;
92         unsigned int cur_mux[3];
93
94         /* channel model */
95         const struct hda_channel_mode *channel_mode;
96         int num_channel_mode;
97
98         /* PCM information */
99         struct hda_pcm pcm_rec[2];      /* used in build_pcms() */
100
101         unsigned int spdif_route;
102
103         /* jack detection */
104         struct snd_array jacks;
105
106         /* dynamic controls, init_verbs and input_mux */
107         struct auto_pin_cfg autocfg;
108         struct hda_input_mux private_imux;
109         hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
110
111         unsigned int dell_automute;
112         unsigned int port_d_mode;
113         unsigned char ext_mic_bias;
114         unsigned int dell_vostro;
115 };
116
117 static int conexant_playback_pcm_open(struct hda_pcm_stream *hinfo,
118                                       struct hda_codec *codec,
119                                       struct snd_pcm_substream *substream)
120 {
121         struct conexant_spec *spec = codec->spec;
122         return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
123                                              hinfo);
124 }
125
126 static int conexant_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
127                                          struct hda_codec *codec,
128                                          unsigned int stream_tag,
129                                          unsigned int format,
130                                          struct snd_pcm_substream *substream)
131 {
132         struct conexant_spec *spec = codec->spec;
133         return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
134                                                 stream_tag,
135                                                 format, substream);
136 }
137
138 static int conexant_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
139                                          struct hda_codec *codec,
140                                          struct snd_pcm_substream *substream)
141 {
142         struct conexant_spec *spec = codec->spec;
143         return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
144 }
145
146 /*
147  * Digital out
148  */
149 static int conexant_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
150                                           struct hda_codec *codec,
151                                           struct snd_pcm_substream *substream)
152 {
153         struct conexant_spec *spec = codec->spec;
154         return snd_hda_multi_out_dig_open(codec, &spec->multiout);
155 }
156
157 static int conexant_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
158                                          struct hda_codec *codec,
159                                          struct snd_pcm_substream *substream)
160 {
161         struct conexant_spec *spec = codec->spec;
162         return snd_hda_multi_out_dig_close(codec, &spec->multiout);
163 }
164
165 static int conexant_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
166                                          struct hda_codec *codec,
167                                          unsigned int stream_tag,
168                                          unsigned int format,
169                                          struct snd_pcm_substream *substream)
170 {
171         struct conexant_spec *spec = codec->spec;
172         return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
173                                              stream_tag,
174                                              format, substream);
175 }
176
177 /*
178  * Analog capture
179  */
180 static int conexant_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
181                                       struct hda_codec *codec,
182                                       unsigned int stream_tag,
183                                       unsigned int format,
184                                       struct snd_pcm_substream *substream)
185 {
186         struct conexant_spec *spec = codec->spec;
187         snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
188                                    stream_tag, 0, format);
189         return 0;
190 }
191
192 static int conexant_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
193                                       struct hda_codec *codec,
194                                       struct snd_pcm_substream *substream)
195 {
196         struct conexant_spec *spec = codec->spec;
197         snd_hda_codec_cleanup_stream(codec, spec->adc_nids[substream->number]);
198         return 0;
199 }
200
201
202
203 static struct hda_pcm_stream conexant_pcm_analog_playback = {
204         .substreams = 1,
205         .channels_min = 2,
206         .channels_max = 2,
207         .nid = 0, /* fill later */
208         .ops = {
209                 .open = conexant_playback_pcm_open,
210                 .prepare = conexant_playback_pcm_prepare,
211                 .cleanup = conexant_playback_pcm_cleanup
212         },
213 };
214
215 static struct hda_pcm_stream conexant_pcm_analog_capture = {
216         .substreams = 1,
217         .channels_min = 2,
218         .channels_max = 2,
219         .nid = 0, /* fill later */
220         .ops = {
221                 .prepare = conexant_capture_pcm_prepare,
222                 .cleanup = conexant_capture_pcm_cleanup
223         },
224 };
225
226
227 static struct hda_pcm_stream conexant_pcm_digital_playback = {
228         .substreams = 1,
229         .channels_min = 2,
230         .channels_max = 2,
231         .nid = 0, /* fill later */
232         .ops = {
233                 .open = conexant_dig_playback_pcm_open,
234                 .close = conexant_dig_playback_pcm_close,
235                 .prepare = conexant_dig_playback_pcm_prepare
236         },
237 };
238
239 static struct hda_pcm_stream conexant_pcm_digital_capture = {
240         .substreams = 1,
241         .channels_min = 2,
242         .channels_max = 2,
243         /* NID is set in alc_build_pcms */
244 };
245
246 static int cx5051_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
247                                       struct hda_codec *codec,
248                                       unsigned int stream_tag,
249                                       unsigned int format,
250                                       struct snd_pcm_substream *substream)
251 {
252         struct conexant_spec *spec = codec->spec;
253         spec->cur_adc = spec->adc_nids[spec->cur_adc_idx];
254         spec->cur_adc_stream_tag = stream_tag;
255         spec->cur_adc_format = format;
256         snd_hda_codec_setup_stream(codec, spec->cur_adc, stream_tag, 0, format);
257         return 0;
258 }
259
260 static int cx5051_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
261                                       struct hda_codec *codec,
262                                       struct snd_pcm_substream *substream)
263 {
264         struct conexant_spec *spec = codec->spec;
265         snd_hda_codec_cleanup_stream(codec, spec->cur_adc);
266         spec->cur_adc = 0;
267         return 0;
268 }
269
270 static struct hda_pcm_stream cx5051_pcm_analog_capture = {
271         .substreams = 1,
272         .channels_min = 2,
273         .channels_max = 2,
274         .nid = 0, /* fill later */
275         .ops = {
276                 .prepare = cx5051_capture_pcm_prepare,
277                 .cleanup = cx5051_capture_pcm_cleanup
278         },
279 };
280
281 static int conexant_build_pcms(struct hda_codec *codec)
282 {
283         struct conexant_spec *spec = codec->spec;
284         struct hda_pcm *info = spec->pcm_rec;
285
286         codec->num_pcms = 1;
287         codec->pcm_info = info;
288
289         info->name = "CONEXANT Analog";
290         info->stream[SNDRV_PCM_STREAM_PLAYBACK] = conexant_pcm_analog_playback;
291         info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max =
292                 spec->multiout.max_channels;
293         info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
294                 spec->multiout.dac_nids[0];
295         if (codec->vendor_id == 0x14f15051)
296                 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
297                         cx5051_pcm_analog_capture;
298         else
299                 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
300                         conexant_pcm_analog_capture;
301         info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = spec->num_adc_nids;
302         info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
303
304         if (spec->multiout.dig_out_nid) {
305                 info++;
306                 codec->num_pcms++;
307                 info->name = "Conexant Digital";
308                 info->pcm_type = HDA_PCM_TYPE_SPDIF;
309                 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
310                         conexant_pcm_digital_playback;
311                 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
312                         spec->multiout.dig_out_nid;
313                 if (spec->dig_in_nid) {
314                         info->stream[SNDRV_PCM_STREAM_CAPTURE] =
315                                 conexant_pcm_digital_capture;
316                         info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
317                                 spec->dig_in_nid;
318                 }
319         }
320
321         return 0;
322 }
323
324 static int conexant_mux_enum_info(struct snd_kcontrol *kcontrol,
325                                   struct snd_ctl_elem_info *uinfo)
326 {
327         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
328         struct conexant_spec *spec = codec->spec;
329
330         return snd_hda_input_mux_info(spec->input_mux, uinfo);
331 }
332
333 static int conexant_mux_enum_get(struct snd_kcontrol *kcontrol,
334                                  struct snd_ctl_elem_value *ucontrol)
335 {
336         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
337         struct conexant_spec *spec = codec->spec;
338         unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
339
340         ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
341         return 0;
342 }
343
344 static int conexant_mux_enum_put(struct snd_kcontrol *kcontrol,
345                                  struct snd_ctl_elem_value *ucontrol)
346 {
347         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
348         struct conexant_spec *spec = codec->spec;
349         unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
350
351         return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol,
352                                      spec->capsrc_nids[adc_idx],
353                                      &spec->cur_mux[adc_idx]);
354 }
355
356 #ifdef CONFIG_SND_HDA_INPUT_JACK
357 static void conexant_free_jack_priv(struct snd_jack *jack)
358 {
359         struct conexant_jack *jacks = jack->private_data;
360         jacks->nid = 0;
361         jacks->jack = NULL;
362 }
363
364 static int conexant_add_jack(struct hda_codec *codec,
365                 hda_nid_t nid, int type)
366 {
367         struct conexant_spec *spec;
368         struct conexant_jack *jack;
369         const char *name;
370         int err;
371
372         spec = codec->spec;
373         snd_array_init(&spec->jacks, sizeof(*jack), 32);
374         jack = snd_array_new(&spec->jacks);
375         name = (type == SND_JACK_HEADPHONE) ? "Headphone" : "Mic" ;
376
377         if (!jack)
378                 return -ENOMEM;
379
380         jack->nid = nid;
381         jack->type = type;
382
383         err = snd_jack_new(codec->bus->card, name, type, &jack->jack);
384         if (err < 0)
385                 return err;
386         jack->jack->private_data = jack;
387         jack->jack->private_free = conexant_free_jack_priv;
388         return 0;
389 }
390
391 static void conexant_report_jack(struct hda_codec *codec, hda_nid_t nid)
392 {
393         struct conexant_spec *spec = codec->spec;
394         struct conexant_jack *jacks = spec->jacks.list;
395
396         if (jacks) {
397                 int i;
398                 for (i = 0; i < spec->jacks.used; i++) {
399                         if (jacks->nid == nid) {
400                                 unsigned int present;
401                                 present = snd_hda_jack_detect(codec, nid);
402
403                                 present = (present) ? jacks->type : 0 ;
404
405                                 snd_jack_report(jacks->jack,
406                                                 present);
407                         }
408                         jacks++;
409                 }
410         }
411 }
412
413 static int conexant_init_jacks(struct hda_codec *codec)
414 {
415         struct conexant_spec *spec = codec->spec;
416         int i;
417
418         for (i = 0; i < spec->num_init_verbs; i++) {
419                 const struct hda_verb *hv;
420
421                 hv = spec->init_verbs[i];
422                 while (hv->nid) {
423                         int err = 0;
424                         switch (hv->param ^ AC_USRSP_EN) {
425                         case CONEXANT_HP_EVENT:
426                                 err = conexant_add_jack(codec, hv->nid,
427                                                 SND_JACK_HEADPHONE);
428                                 conexant_report_jack(codec, hv->nid);
429                                 break;
430                         case CXT5051_PORTC_EVENT:
431                         case CONEXANT_MIC_EVENT:
432                                 err = conexant_add_jack(codec, hv->nid,
433                                                 SND_JACK_MICROPHONE);
434                                 conexant_report_jack(codec, hv->nid);
435                                 break;
436                         }
437                         if (err < 0)
438                                 return err;
439                         ++hv;
440                 }
441         }
442         return 0;
443
444 }
445 #else
446 static inline void conexant_report_jack(struct hda_codec *codec, hda_nid_t nid)
447 {
448 }
449
450 static inline int conexant_init_jacks(struct hda_codec *codec)
451 {
452         return 0;
453 }
454 #endif
455
456 static int conexant_init(struct hda_codec *codec)
457 {
458         struct conexant_spec *spec = codec->spec;
459         int i;
460
461         for (i = 0; i < spec->num_init_verbs; i++)
462                 snd_hda_sequence_write(codec, spec->init_verbs[i]);
463         return 0;
464 }
465
466 static void conexant_free(struct hda_codec *codec)
467 {
468 #ifdef CONFIG_SND_HDA_INPUT_JACK
469         struct conexant_spec *spec = codec->spec;
470         if (spec->jacks.list) {
471                 struct conexant_jack *jacks = spec->jacks.list;
472                 int i;
473                 for (i = 0; i < spec->jacks.used; i++, jacks++) {
474                         if (jacks->jack)
475                                 snd_device_free(codec->bus->card, jacks->jack);
476                 }
477                 snd_array_free(&spec->jacks);
478         }
479 #endif
480         kfree(codec->spec);
481 }
482
483 static struct snd_kcontrol_new cxt_capture_mixers[] = {
484         {
485                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
486                 .name = "Capture Source",
487                 .info = conexant_mux_enum_info,
488                 .get = conexant_mux_enum_get,
489                 .put = conexant_mux_enum_put
490         },
491         {}
492 };
493
494 static const char *slave_vols[] = {
495         "Headphone Playback Volume",
496         "Speaker Playback Volume",
497         NULL
498 };
499
500 static const char *slave_sws[] = {
501         "Headphone Playback Switch",
502         "Speaker Playback Switch",
503         NULL
504 };
505
506 static int conexant_build_controls(struct hda_codec *codec)
507 {
508         struct conexant_spec *spec = codec->spec;
509         unsigned int i;
510         int err;
511
512         for (i = 0; i < spec->num_mixers; i++) {
513                 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
514                 if (err < 0)
515                         return err;
516         }
517         if (spec->multiout.dig_out_nid) {
518                 err = snd_hda_create_spdif_out_ctls(codec,
519                                                     spec->multiout.dig_out_nid);
520                 if (err < 0)
521                         return err;
522                 err = snd_hda_create_spdif_share_sw(codec,
523                                                     &spec->multiout);
524                 if (err < 0)
525                         return err;
526                 spec->multiout.share_spdif = 1;
527         } 
528         if (spec->dig_in_nid) {
529                 err = snd_hda_create_spdif_in_ctls(codec,spec->dig_in_nid);
530                 if (err < 0)
531                         return err;
532         }
533
534         /* if we have no master control, let's create it */
535         if (spec->vmaster_nid &&
536             !snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
537                 unsigned int vmaster_tlv[4];
538                 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
539                                         HDA_OUTPUT, vmaster_tlv);
540                 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
541                                           vmaster_tlv, slave_vols);
542                 if (err < 0)
543                         return err;
544         }
545         if (spec->vmaster_nid &&
546             !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
547                 err = snd_hda_add_vmaster(codec, "Master Playback Switch",
548                                           NULL, slave_sws);
549                 if (err < 0)
550                         return err;
551         }
552
553         if (spec->input_mux) {
554                 err = snd_hda_add_new_ctls(codec, cxt_capture_mixers);
555                 if (err < 0)
556                         return err;
557         }
558
559         return 0;
560 }
561
562 static struct hda_codec_ops conexant_patch_ops = {
563         .build_controls = conexant_build_controls,
564         .build_pcms = conexant_build_pcms,
565         .init = conexant_init,
566         .free = conexant_free,
567 };
568
569 /*
570  * EAPD control
571  * the private value = nid | (invert << 8)
572  */
573
574 #define cxt_eapd_info           snd_ctl_boolean_mono_info
575
576 static int cxt_eapd_get(struct snd_kcontrol *kcontrol,
577                              struct snd_ctl_elem_value *ucontrol)
578 {
579         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
580         struct conexant_spec *spec = codec->spec;
581         int invert = (kcontrol->private_value >> 8) & 1;
582         if (invert)
583                 ucontrol->value.integer.value[0] = !spec->cur_eapd;
584         else
585                 ucontrol->value.integer.value[0] = spec->cur_eapd;
586         return 0;
587
588 }
589
590 static int cxt_eapd_put(struct snd_kcontrol *kcontrol,
591                              struct snd_ctl_elem_value *ucontrol)
592 {
593         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
594         struct conexant_spec *spec = codec->spec;
595         int invert = (kcontrol->private_value >> 8) & 1;
596         hda_nid_t nid = kcontrol->private_value & 0xff;
597         unsigned int eapd;
598
599         eapd = !!ucontrol->value.integer.value[0];
600         if (invert)
601                 eapd = !eapd;
602         if (eapd == spec->cur_eapd)
603                 return 0;
604         
605         spec->cur_eapd = eapd;
606         snd_hda_codec_write_cache(codec, nid,
607                                   0, AC_VERB_SET_EAPD_BTLENABLE,
608                                   eapd ? 0x02 : 0x00);
609         return 1;
610 }
611
612 /* controls for test mode */
613 #ifdef CONFIG_SND_DEBUG
614
615 #define CXT_EAPD_SWITCH(xname, nid, mask) \
616         { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
617           .info = cxt_eapd_info, \
618           .get = cxt_eapd_get, \
619           .put = cxt_eapd_put, \
620           .private_value = nid | (mask<<16) }
621
622
623
624 static int conexant_ch_mode_info(struct snd_kcontrol *kcontrol,
625                                  struct snd_ctl_elem_info *uinfo)
626 {
627         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
628         struct conexant_spec *spec = codec->spec;
629         return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
630                                     spec->num_channel_mode);
631 }
632
633 static int conexant_ch_mode_get(struct snd_kcontrol *kcontrol,
634                                 struct snd_ctl_elem_value *ucontrol)
635 {
636         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
637         struct conexant_spec *spec = codec->spec;
638         return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
639                                    spec->num_channel_mode,
640                                    spec->multiout.max_channels);
641 }
642
643 static int conexant_ch_mode_put(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         int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
649                                       spec->num_channel_mode,
650                                       &spec->multiout.max_channels);
651         if (err >= 0 && spec->need_dac_fix)
652                 spec->multiout.num_dacs = spec->multiout.max_channels / 2;
653         return err;
654 }
655
656 #define CXT_PIN_MODE(xname, nid, dir) \
657         { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
658           .info = conexant_ch_mode_info, \
659           .get = conexant_ch_mode_get, \
660           .put = conexant_ch_mode_put, \
661           .private_value = nid | (dir<<16) }
662
663 #endif /* CONFIG_SND_DEBUG */
664
665 /* Conexant 5045 specific */
666
667 static hda_nid_t cxt5045_dac_nids[1] = { 0x19 };
668 static hda_nid_t cxt5045_adc_nids[1] = { 0x1a };
669 static hda_nid_t cxt5045_capsrc_nids[1] = { 0x1a };
670 #define CXT5045_SPDIF_OUT       0x18
671
672 static struct hda_channel_mode cxt5045_modes[1] = {
673         { 2, NULL },
674 };
675
676 static struct hda_input_mux cxt5045_capture_source = {
677         .num_items = 2,
678         .items = {
679                 { "IntMic", 0x1 },
680                 { "ExtMic", 0x2 },
681         }
682 };
683
684 static struct hda_input_mux cxt5045_capture_source_benq = {
685         .num_items = 5,
686         .items = {
687                 { "IntMic", 0x1 },
688                 { "ExtMic", 0x2 },
689                 { "LineIn", 0x3 },
690                 { "CD",     0x4 },
691                 { "Mixer",  0x0 },
692         }
693 };
694
695 static struct hda_input_mux cxt5045_capture_source_hp530 = {
696         .num_items = 2,
697         .items = {
698                 { "ExtMic", 0x1 },
699                 { "IntMic", 0x2 },
700         }
701 };
702
703 /* turn on/off EAPD (+ mute HP) as a master switch */
704 static int cxt5045_hp_master_sw_put(struct snd_kcontrol *kcontrol,
705                                     struct snd_ctl_elem_value *ucontrol)
706 {
707         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
708         struct conexant_spec *spec = codec->spec;
709         unsigned int bits;
710
711         if (!cxt_eapd_put(kcontrol, ucontrol))
712                 return 0;
713
714         /* toggle internal speakers mute depending of presence of
715          * the headphone jack
716          */
717         bits = (!spec->hp_present && spec->cur_eapd) ? 0 : HDA_AMP_MUTE;
718         snd_hda_codec_amp_stereo(codec, 0x10, HDA_OUTPUT, 0,
719                                  HDA_AMP_MUTE, bits);
720
721         bits = spec->cur_eapd ? 0 : HDA_AMP_MUTE;
722         snd_hda_codec_amp_stereo(codec, 0x11, HDA_OUTPUT, 0,
723                                  HDA_AMP_MUTE, bits);
724         return 1;
725 }
726
727 /* bind volumes of both NID 0x10 and 0x11 */
728 static struct hda_bind_ctls cxt5045_hp_bind_master_vol = {
729         .ops = &snd_hda_bind_vol,
730         .values = {
731                 HDA_COMPOSE_AMP_VAL(0x10, 3, 0, HDA_OUTPUT),
732                 HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT),
733                 0
734         },
735 };
736
737 /* toggle input of built-in and mic jack appropriately */
738 static void cxt5045_hp_automic(struct hda_codec *codec)
739 {
740         static struct hda_verb mic_jack_on[] = {
741                 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
742                 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
743                 {}
744         };
745         static struct hda_verb mic_jack_off[] = {
746                 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
747                 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
748                 {}
749         };
750         unsigned int present;
751
752         present = snd_hda_jack_detect(codec, 0x12);
753         if (present)
754                 snd_hda_sequence_write(codec, mic_jack_on);
755         else
756                 snd_hda_sequence_write(codec, mic_jack_off);
757 }
758
759
760 /* mute internal speaker if HP is plugged */
761 static void cxt5045_hp_automute(struct hda_codec *codec)
762 {
763         struct conexant_spec *spec = codec->spec;
764         unsigned int bits;
765
766         spec->hp_present = snd_hda_jack_detect(codec, 0x11);
767
768         bits = (spec->hp_present || !spec->cur_eapd) ? HDA_AMP_MUTE : 0; 
769         snd_hda_codec_amp_stereo(codec, 0x10, HDA_OUTPUT, 0,
770                                  HDA_AMP_MUTE, bits);
771 }
772
773 /* unsolicited event for HP jack sensing */
774 static void cxt5045_hp_unsol_event(struct hda_codec *codec,
775                                    unsigned int res)
776 {
777         res >>= 26;
778         switch (res) {
779         case CONEXANT_HP_EVENT:
780                 cxt5045_hp_automute(codec);
781                 break;
782         case CONEXANT_MIC_EVENT:
783                 cxt5045_hp_automic(codec);
784                 break;
785
786         }
787 }
788
789 static struct snd_kcontrol_new cxt5045_mixers[] = {
790         HDA_CODEC_VOLUME("Int Mic Capture Volume", 0x1a, 0x01, HDA_INPUT),
791         HDA_CODEC_MUTE("Int Mic Capture Switch", 0x1a, 0x01, HDA_INPUT),
792         HDA_CODEC_VOLUME("Ext Mic Capture Volume", 0x1a, 0x02, HDA_INPUT),
793         HDA_CODEC_MUTE("Ext Mic Capture Switch", 0x1a, 0x02, HDA_INPUT),
794         HDA_CODEC_VOLUME("PCM Playback Volume", 0x17, 0x0, HDA_INPUT),
795         HDA_CODEC_MUTE("PCM Playback Switch", 0x17, 0x0, HDA_INPUT),
796         HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x17, 0x1, HDA_INPUT),
797         HDA_CODEC_MUTE("Int Mic Playback Switch", 0x17, 0x1, HDA_INPUT),
798         HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x17, 0x2, HDA_INPUT),
799         HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x17, 0x2, HDA_INPUT),
800         HDA_BIND_VOL("Master Playback Volume", &cxt5045_hp_bind_master_vol),
801         {
802                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
803                 .name = "Master Playback Switch",
804                 .info = cxt_eapd_info,
805                 .get = cxt_eapd_get,
806                 .put = cxt5045_hp_master_sw_put,
807                 .private_value = 0x10,
808         },
809
810         {}
811 };
812
813 static struct snd_kcontrol_new cxt5045_benq_mixers[] = {
814         HDA_CODEC_VOLUME("CD Capture Volume", 0x1a, 0x04, HDA_INPUT),
815         HDA_CODEC_MUTE("CD Capture Switch", 0x1a, 0x04, HDA_INPUT),
816         HDA_CODEC_VOLUME("CD Playback Volume", 0x17, 0x4, HDA_INPUT),
817         HDA_CODEC_MUTE("CD Playback Switch", 0x17, 0x4, HDA_INPUT),
818
819         HDA_CODEC_VOLUME("Line In Capture Volume", 0x1a, 0x03, HDA_INPUT),
820         HDA_CODEC_MUTE("Line In Capture Switch", 0x1a, 0x03, HDA_INPUT),
821         HDA_CODEC_VOLUME("Line In Playback Volume", 0x17, 0x3, HDA_INPUT),
822         HDA_CODEC_MUTE("Line In Playback Switch", 0x17, 0x3, HDA_INPUT),
823
824         HDA_CODEC_VOLUME("Mixer Capture Volume", 0x1a, 0x0, HDA_INPUT),
825         HDA_CODEC_MUTE("Mixer Capture Switch", 0x1a, 0x0, HDA_INPUT),
826
827         {}
828 };
829
830 static struct snd_kcontrol_new cxt5045_mixers_hp530[] = {
831         HDA_CODEC_VOLUME("Int Mic Capture Volume", 0x1a, 0x02, HDA_INPUT),
832         HDA_CODEC_MUTE("Int Mic Capture Switch", 0x1a, 0x02, HDA_INPUT),
833         HDA_CODEC_VOLUME("Ext Mic Capture Volume", 0x1a, 0x01, HDA_INPUT),
834         HDA_CODEC_MUTE("Ext Mic Capture Switch", 0x1a, 0x01, HDA_INPUT),
835         HDA_CODEC_VOLUME("PCM Playback Volume", 0x17, 0x0, HDA_INPUT),
836         HDA_CODEC_MUTE("PCM Playback Switch", 0x17, 0x0, HDA_INPUT),
837         HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x17, 0x2, HDA_INPUT),
838         HDA_CODEC_MUTE("Int Mic Playback Switch", 0x17, 0x2, HDA_INPUT),
839         HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x17, 0x1, HDA_INPUT),
840         HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x17, 0x1, HDA_INPUT),
841         HDA_BIND_VOL("Master Playback Volume", &cxt5045_hp_bind_master_vol),
842         {
843                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
844                 .name = "Master Playback Switch",
845                 .info = cxt_eapd_info,
846                 .get = cxt_eapd_get,
847                 .put = cxt5045_hp_master_sw_put,
848                 .private_value = 0x10,
849         },
850
851         {}
852 };
853
854 static struct hda_verb cxt5045_init_verbs[] = {
855         /* Line in, Mic */
856         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_80 },
857         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_80 },
858         /* HP, Amp  */
859         {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
860         {0x10, AC_VERB_SET_CONNECT_SEL, 0x1},
861         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
862         {0x11, AC_VERB_SET_CONNECT_SEL, 0x1},
863         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
864         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
865         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
866         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
867         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
868         /* Record selector: Int mic */
869         {0x1a, AC_VERB_SET_CONNECT_SEL,0x1},
870         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE,
871          AC_AMP_SET_INPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x17},
872         /* SPDIF route: PCM */
873         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
874         { 0x13, AC_VERB_SET_CONNECT_SEL, 0x0 },
875         /* EAPD */
876         {0x10, AC_VERB_SET_EAPD_BTLENABLE, 0x2 }, /* default on */ 
877         { } /* end */
878 };
879
880 static struct hda_verb cxt5045_benq_init_verbs[] = {
881         /* Int Mic, Mic */
882         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_80 },
883         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_80 },
884         /* Line In,HP, Amp  */
885         {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
886         {0x10, AC_VERB_SET_CONNECT_SEL, 0x1},
887         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
888         {0x11, AC_VERB_SET_CONNECT_SEL, 0x1},
889         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
890         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
891         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
892         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
893         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
894         /* Record selector: Int mic */
895         {0x1a, AC_VERB_SET_CONNECT_SEL, 0x1},
896         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE,
897          AC_AMP_SET_INPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x17},
898         /* SPDIF route: PCM */
899         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
900         {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
901         /* EAPD */
902         {0x10, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
903         { } /* end */
904 };
905
906 static struct hda_verb cxt5045_hp_sense_init_verbs[] = {
907         /* pin sensing on HP jack */
908         {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT},
909         { } /* end */
910 };
911
912 static struct hda_verb cxt5045_mic_sense_init_verbs[] = {
913         /* pin sensing on HP jack */
914         {0x12, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT},
915         { } /* end */
916 };
917
918 #ifdef CONFIG_SND_DEBUG
919 /* Test configuration for debugging, modelled after the ALC260 test
920  * configuration.
921  */
922 static struct hda_input_mux cxt5045_test_capture_source = {
923         .num_items = 5,
924         .items = {
925                 { "MIXER", 0x0 },
926                 { "MIC1 pin", 0x1 },
927                 { "LINE1 pin", 0x2 },
928                 { "HP-OUT pin", 0x3 },
929                 { "CD pin", 0x4 },
930         },
931 };
932
933 static struct snd_kcontrol_new cxt5045_test_mixer[] = {
934
935         /* Output controls */
936         HDA_CODEC_VOLUME("Speaker Playback Volume", 0x10, 0x0, HDA_OUTPUT),
937         HDA_CODEC_MUTE("Speaker Playback Switch", 0x10, 0x0, HDA_OUTPUT),
938         HDA_CODEC_VOLUME("Node 11 Playback Volume", 0x11, 0x0, HDA_OUTPUT),
939         HDA_CODEC_MUTE("Node 11 Playback Switch", 0x11, 0x0, HDA_OUTPUT),
940         HDA_CODEC_VOLUME("Node 12 Playback Volume", 0x12, 0x0, HDA_OUTPUT),
941         HDA_CODEC_MUTE("Node 12 Playback Switch", 0x12, 0x0, HDA_OUTPUT),
942         
943         /* Modes for retasking pin widgets */
944         CXT_PIN_MODE("HP-OUT pin mode", 0x11, CXT_PIN_DIR_INOUT),
945         CXT_PIN_MODE("LINE1 pin mode", 0x12, CXT_PIN_DIR_INOUT),
946
947         /* EAPD Switch Control */
948         CXT_EAPD_SWITCH("External Amplifier", 0x10, 0x0),
949
950         /* Loopback mixer controls */
951
952         HDA_CODEC_VOLUME("Mixer-1 Volume", 0x17, 0x0, HDA_INPUT),
953         HDA_CODEC_MUTE("Mixer-1 Switch", 0x17, 0x0, HDA_INPUT),
954         HDA_CODEC_VOLUME("Mixer-2 Volume", 0x17, 0x1, HDA_INPUT),
955         HDA_CODEC_MUTE("Mixer-2 Switch", 0x17, 0x1, HDA_INPUT),
956         HDA_CODEC_VOLUME("Mixer-3 Volume", 0x17, 0x2, HDA_INPUT),
957         HDA_CODEC_MUTE("Mixer-3 Switch", 0x17, 0x2, HDA_INPUT),
958         HDA_CODEC_VOLUME("Mixer-4 Volume", 0x17, 0x3, HDA_INPUT),
959         HDA_CODEC_MUTE("Mixer-4 Switch", 0x17, 0x3, HDA_INPUT),
960         HDA_CODEC_VOLUME("Mixer-5 Volume", 0x17, 0x4, HDA_INPUT),
961         HDA_CODEC_MUTE("Mixer-5 Switch", 0x17, 0x4, HDA_INPUT),
962         {
963                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
964                 .name = "Input Source",
965                 .info = conexant_mux_enum_info,
966                 .get = conexant_mux_enum_get,
967                 .put = conexant_mux_enum_put,
968         },
969         /* Audio input controls */
970         HDA_CODEC_VOLUME("Input-1 Volume", 0x1a, 0x0, HDA_INPUT),
971         HDA_CODEC_MUTE("Input-1 Switch", 0x1a, 0x0, HDA_INPUT),
972         HDA_CODEC_VOLUME("Input-2 Volume", 0x1a, 0x1, HDA_INPUT),
973         HDA_CODEC_MUTE("Input-2 Switch", 0x1a, 0x1, HDA_INPUT),
974         HDA_CODEC_VOLUME("Input-3 Volume", 0x1a, 0x2, HDA_INPUT),
975         HDA_CODEC_MUTE("Input-3 Switch", 0x1a, 0x2, HDA_INPUT),
976         HDA_CODEC_VOLUME("Input-4 Volume", 0x1a, 0x3, HDA_INPUT),
977         HDA_CODEC_MUTE("Input-4 Switch", 0x1a, 0x3, HDA_INPUT),
978         HDA_CODEC_VOLUME("Input-5 Volume", 0x1a, 0x4, HDA_INPUT),
979         HDA_CODEC_MUTE("Input-5 Switch", 0x1a, 0x4, HDA_INPUT),
980         { } /* end */
981 };
982
983 static struct hda_verb cxt5045_test_init_verbs[] = {
984         /* Set connections */
985         { 0x10, AC_VERB_SET_CONNECT_SEL, 0x0 },
986         { 0x11, AC_VERB_SET_CONNECT_SEL, 0x0 },
987         { 0x12, AC_VERB_SET_CONNECT_SEL, 0x0 },
988         /* Enable retasking pins as output, initially without power amp */
989         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
990         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
991
992         /* Disable digital (SPDIF) pins initially, but users can enable
993          * them via a mixer switch.  In the case of SPDIF-out, this initverb
994          * payload also sets the generation to 0, output to be in "consumer"
995          * PCM format, copyright asserted, no pre-emphasis and no validity
996          * control.
997          */
998         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
999         {0x18, AC_VERB_SET_DIGI_CONVERT_1, 0},
1000
1001         /* Start with output sum widgets muted and their output gains at min */
1002         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1003         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1004
1005         /* Unmute retasking pin widget output buffers since the default
1006          * state appears to be output.  As the pin mode is changed by the
1007          * user the pin mode control will take care of enabling the pin's
1008          * input/output buffers as needed.
1009          */
1010         {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1011         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1012
1013         /* Mute capture amp left and right */
1014         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1015
1016         /* Set ADC connection select to match default mixer setting (mic1
1017          * pin)
1018          */
1019         {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
1020         {0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
1021
1022         /* Mute all inputs to mixer widget (even unconnected ones) */
1023         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* Mixer pin */
1024         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* Mic1 pin */
1025         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* Line pin */
1026         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* HP pin */
1027         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
1028
1029         { }
1030 };
1031 #endif
1032
1033
1034 /* initialize jack-sensing, too */
1035 static int cxt5045_init(struct hda_codec *codec)
1036 {
1037         conexant_init(codec);
1038         cxt5045_hp_automute(codec);
1039         return 0;
1040 }
1041
1042
1043 enum {
1044         CXT5045_LAPTOP_HPSENSE,
1045         CXT5045_LAPTOP_MICSENSE,
1046         CXT5045_LAPTOP_HPMICSENSE,
1047         CXT5045_BENQ,
1048         CXT5045_LAPTOP_HP530,
1049 #ifdef CONFIG_SND_DEBUG
1050         CXT5045_TEST,
1051 #endif
1052         CXT5045_MODELS
1053 };
1054
1055 static const char *cxt5045_models[CXT5045_MODELS] = {
1056         [CXT5045_LAPTOP_HPSENSE]        = "laptop-hpsense",
1057         [CXT5045_LAPTOP_MICSENSE]       = "laptop-micsense",
1058         [CXT5045_LAPTOP_HPMICSENSE]     = "laptop-hpmicsense",
1059         [CXT5045_BENQ]                  = "benq",
1060         [CXT5045_LAPTOP_HP530]          = "laptop-hp530",
1061 #ifdef CONFIG_SND_DEBUG
1062         [CXT5045_TEST]          = "test",
1063 #endif
1064 };
1065
1066 static struct snd_pci_quirk cxt5045_cfg_tbl[] = {
1067         SND_PCI_QUIRK(0x103c, 0x30d5, "HP 530", CXT5045_LAPTOP_HP530),
1068         SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3000, "HP DV Series",
1069                            CXT5045_LAPTOP_HPSENSE),
1070         SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba P105", CXT5045_LAPTOP_MICSENSE),
1071         SND_PCI_QUIRK(0x152d, 0x0753, "Benq R55E", CXT5045_BENQ),
1072         SND_PCI_QUIRK(0x1734, 0x10ad, "Fujitsu Si1520", CXT5045_LAPTOP_MICSENSE),
1073         SND_PCI_QUIRK(0x1734, 0x10cb, "Fujitsu Si3515", CXT5045_LAPTOP_HPMICSENSE),
1074         SND_PCI_QUIRK(0x1734, 0x110e, "Fujitsu V5505",
1075                       CXT5045_LAPTOP_HPMICSENSE),
1076         SND_PCI_QUIRK(0x1509, 0x1e40, "FIC", CXT5045_LAPTOP_HPMICSENSE),
1077         SND_PCI_QUIRK(0x1509, 0x2f05, "FIC", CXT5045_LAPTOP_HPMICSENSE),
1078         SND_PCI_QUIRK(0x1509, 0x2f06, "FIC", CXT5045_LAPTOP_HPMICSENSE),
1079         SND_PCI_QUIRK_MASK(0x1631, 0xff00, 0xc100, "Packard Bell",
1080                            CXT5045_LAPTOP_HPMICSENSE),
1081         SND_PCI_QUIRK(0x8086, 0x2111, "Conexant Reference board", CXT5045_LAPTOP_HPSENSE),
1082         {}
1083 };
1084
1085 static int patch_cxt5045(struct hda_codec *codec)
1086 {
1087         struct conexant_spec *spec;
1088         int board_config;
1089
1090         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1091         if (!spec)
1092                 return -ENOMEM;
1093         codec->spec = spec;
1094         codec->pin_amp_workaround = 1;
1095
1096         spec->multiout.max_channels = 2;
1097         spec->multiout.num_dacs = ARRAY_SIZE(cxt5045_dac_nids);
1098         spec->multiout.dac_nids = cxt5045_dac_nids;
1099         spec->multiout.dig_out_nid = CXT5045_SPDIF_OUT;
1100         spec->num_adc_nids = 1;
1101         spec->adc_nids = cxt5045_adc_nids;
1102         spec->capsrc_nids = cxt5045_capsrc_nids;
1103         spec->input_mux = &cxt5045_capture_source;
1104         spec->num_mixers = 1;
1105         spec->mixers[0] = cxt5045_mixers;
1106         spec->num_init_verbs = 1;
1107         spec->init_verbs[0] = cxt5045_init_verbs;
1108         spec->spdif_route = 0;
1109         spec->num_channel_mode = ARRAY_SIZE(cxt5045_modes),
1110         spec->channel_mode = cxt5045_modes,
1111
1112
1113         codec->patch_ops = conexant_patch_ops;
1114
1115         board_config = snd_hda_check_board_config(codec, CXT5045_MODELS,
1116                                                   cxt5045_models,
1117                                                   cxt5045_cfg_tbl);
1118         switch (board_config) {
1119         case CXT5045_LAPTOP_HPSENSE:
1120                 codec->patch_ops.unsol_event = cxt5045_hp_unsol_event;
1121                 spec->input_mux = &cxt5045_capture_source;
1122                 spec->num_init_verbs = 2;
1123                 spec->init_verbs[1] = cxt5045_hp_sense_init_verbs;
1124                 spec->mixers[0] = cxt5045_mixers;
1125                 codec->patch_ops.init = cxt5045_init;
1126                 break;
1127         case CXT5045_LAPTOP_MICSENSE:
1128                 codec->patch_ops.unsol_event = cxt5045_hp_unsol_event;
1129                 spec->input_mux = &cxt5045_capture_source;
1130                 spec->num_init_verbs = 2;
1131                 spec->init_verbs[1] = cxt5045_mic_sense_init_verbs;
1132                 spec->mixers[0] = cxt5045_mixers;
1133                 codec->patch_ops.init = cxt5045_init;
1134                 break;
1135         default:
1136         case CXT5045_LAPTOP_HPMICSENSE:
1137                 codec->patch_ops.unsol_event = cxt5045_hp_unsol_event;
1138                 spec->input_mux = &cxt5045_capture_source;
1139                 spec->num_init_verbs = 3;
1140                 spec->init_verbs[1] = cxt5045_hp_sense_init_verbs;
1141                 spec->init_verbs[2] = cxt5045_mic_sense_init_verbs;
1142                 spec->mixers[0] = cxt5045_mixers;
1143                 codec->patch_ops.init = cxt5045_init;
1144                 break;
1145         case CXT5045_BENQ:
1146                 codec->patch_ops.unsol_event = cxt5045_hp_unsol_event;
1147                 spec->input_mux = &cxt5045_capture_source_benq;
1148                 spec->num_init_verbs = 1;
1149                 spec->init_verbs[0] = cxt5045_benq_init_verbs;
1150                 spec->mixers[0] = cxt5045_mixers;
1151                 spec->mixers[1] = cxt5045_benq_mixers;
1152                 spec->num_mixers = 2;
1153                 codec->patch_ops.init = cxt5045_init;
1154                 break;
1155         case CXT5045_LAPTOP_HP530:
1156                 codec->patch_ops.unsol_event = cxt5045_hp_unsol_event;
1157                 spec->input_mux = &cxt5045_capture_source_hp530;
1158                 spec->num_init_verbs = 2;
1159                 spec->init_verbs[1] = cxt5045_hp_sense_init_verbs;
1160                 spec->mixers[0] = cxt5045_mixers_hp530;
1161                 codec->patch_ops.init = cxt5045_init;
1162                 break;
1163 #ifdef CONFIG_SND_DEBUG
1164         case CXT5045_TEST:
1165                 spec->input_mux = &cxt5045_test_capture_source;
1166                 spec->mixers[0] = cxt5045_test_mixer;
1167                 spec->init_verbs[0] = cxt5045_test_init_verbs;
1168                 break;
1169                 
1170 #endif  
1171         }
1172
1173         switch (codec->subsystem_id >> 16) {
1174         case 0x103c:
1175         case 0x1734:
1176                 /* HP & Fujitsu-Siemens laptops have really bad sound over 0dB
1177                  * on NID 0x17. Fix max PCM level to 0 dB
1178                  * (originally it has 0x2b steps with 0dB offset 0x14)
1179                  */
1180                 snd_hda_override_amp_caps(codec, 0x17, HDA_INPUT,
1181                                           (0x14 << AC_AMPCAP_OFFSET_SHIFT) |
1182                                           (0x14 << AC_AMPCAP_NUM_STEPS_SHIFT) |
1183                                           (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) |
1184                                           (1 << AC_AMPCAP_MUTE_SHIFT));
1185                 break;
1186         }
1187
1188         return 0;
1189 }
1190
1191
1192 /* Conexant 5047 specific */
1193 #define CXT5047_SPDIF_OUT       0x11
1194
1195 static hda_nid_t cxt5047_dac_nids[1] = { 0x10 }; /* 0x1c */
1196 static hda_nid_t cxt5047_adc_nids[1] = { 0x12 };
1197 static hda_nid_t cxt5047_capsrc_nids[1] = { 0x1a };
1198
1199 static struct hda_channel_mode cxt5047_modes[1] = {
1200         { 2, NULL },
1201 };
1202
1203 static struct hda_input_mux cxt5047_toshiba_capture_source = {
1204         .num_items = 2,
1205         .items = {
1206                 { "ExtMic", 0x2 },
1207                 { "Line-In", 0x1 },
1208         }
1209 };
1210
1211 /* turn on/off EAPD (+ mute HP) as a master switch */
1212 static int cxt5047_hp_master_sw_put(struct snd_kcontrol *kcontrol,
1213                                     struct snd_ctl_elem_value *ucontrol)
1214 {
1215         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1216         struct conexant_spec *spec = codec->spec;
1217         unsigned int bits;
1218
1219         if (!cxt_eapd_put(kcontrol, ucontrol))
1220                 return 0;
1221
1222         /* toggle internal speakers mute depending of presence of
1223          * the headphone jack
1224          */
1225         bits = (!spec->hp_present && spec->cur_eapd) ? 0 : HDA_AMP_MUTE;
1226         /* NOTE: Conexat codec needs the index for *OUTPUT* amp of
1227          * pin widgets unlike other codecs.  In this case, we need to
1228          * set index 0x01 for the volume from the mixer amp 0x19.
1229          */
1230         snd_hda_codec_amp_stereo(codec, 0x1d, HDA_OUTPUT, 0x01,
1231                                  HDA_AMP_MUTE, bits);
1232         bits = spec->cur_eapd ? 0 : HDA_AMP_MUTE;
1233         snd_hda_codec_amp_stereo(codec, 0x13, HDA_OUTPUT, 0,
1234                                  HDA_AMP_MUTE, bits);
1235         return 1;
1236 }
1237
1238 /* mute internal speaker if HP is plugged */
1239 static void cxt5047_hp_automute(struct hda_codec *codec)
1240 {
1241         struct conexant_spec *spec = codec->spec;
1242         unsigned int bits;
1243
1244         spec->hp_present = snd_hda_jack_detect(codec, 0x13);
1245
1246         bits = (spec->hp_present || !spec->cur_eapd) ? HDA_AMP_MUTE : 0;
1247         /* See the note in cxt5047_hp_master_sw_put */
1248         snd_hda_codec_amp_stereo(codec, 0x1d, HDA_OUTPUT, 0x01,
1249                                  HDA_AMP_MUTE, bits);
1250 }
1251
1252 /* toggle input of built-in and mic jack appropriately */
1253 static void cxt5047_hp_automic(struct hda_codec *codec)
1254 {
1255         static struct hda_verb mic_jack_on[] = {
1256                 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1257                 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1258                 {}
1259         };
1260         static struct hda_verb mic_jack_off[] = {
1261                 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1262                 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1263                 {}
1264         };
1265         unsigned int present;
1266
1267         present = snd_hda_jack_detect(codec, 0x15);
1268         if (present)
1269                 snd_hda_sequence_write(codec, mic_jack_on);
1270         else
1271                 snd_hda_sequence_write(codec, mic_jack_off);
1272 }
1273
1274 /* unsolicited event for HP jack sensing */
1275 static void cxt5047_hp_unsol_event(struct hda_codec *codec,
1276                                   unsigned int res)
1277 {
1278         switch (res >> 26) {
1279         case CONEXANT_HP_EVENT:
1280                 cxt5047_hp_automute(codec);
1281                 break;
1282         case CONEXANT_MIC_EVENT:
1283                 cxt5047_hp_automic(codec);
1284                 break;
1285         }
1286 }
1287
1288 static struct snd_kcontrol_new cxt5047_base_mixers[] = {
1289         HDA_CODEC_VOLUME("Mic Playback Volume", 0x19, 0x02, HDA_INPUT),
1290         HDA_CODEC_MUTE("Mic Playback Switch", 0x19, 0x02, HDA_INPUT),
1291         HDA_CODEC_VOLUME("Mic Boost", 0x1a, 0x0, HDA_OUTPUT),
1292         HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x03, HDA_INPUT),
1293         HDA_CODEC_MUTE("Capture Switch", 0x12, 0x03, HDA_INPUT),
1294         HDA_CODEC_VOLUME("PCM Volume", 0x10, 0x00, HDA_OUTPUT),
1295         HDA_CODEC_MUTE("PCM Switch", 0x10, 0x00, HDA_OUTPUT),
1296         {
1297                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1298                 .name = "Master Playback Switch",
1299                 .info = cxt_eapd_info,
1300                 .get = cxt_eapd_get,
1301                 .put = cxt5047_hp_master_sw_put,
1302                 .private_value = 0x13,
1303         },
1304
1305         {}
1306 };
1307
1308 static struct snd_kcontrol_new cxt5047_hp_spk_mixers[] = {
1309         /* See the note in cxt5047_hp_master_sw_put */
1310         HDA_CODEC_VOLUME("Speaker Playback Volume", 0x1d, 0x01, HDA_OUTPUT),
1311         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x13, 0x00, HDA_OUTPUT),
1312         {}
1313 };
1314
1315 static struct snd_kcontrol_new cxt5047_hp_only_mixers[] = {
1316         HDA_CODEC_VOLUME("Master Playback Volume", 0x13, 0x00, HDA_OUTPUT),
1317         { } /* end */
1318 };
1319
1320 static struct hda_verb cxt5047_init_verbs[] = {
1321         /* Line in, Mic, Built-in Mic */
1322         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1323         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_50 },
1324         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_50 },
1325         /* HP, Speaker  */
1326         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
1327         {0x13, AC_VERB_SET_CONNECT_SEL, 0x0}, /* mixer(0x19) */
1328         {0x1d, AC_VERB_SET_CONNECT_SEL, 0x1}, /* mixer(0x19) */
1329         /* Record selector: Mic */
1330         {0x12, AC_VERB_SET_CONNECT_SEL,0x03},
1331         {0x19, AC_VERB_SET_AMP_GAIN_MUTE,
1332          AC_AMP_SET_INPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x17},
1333         {0x1A, AC_VERB_SET_CONNECT_SEL,0x02},
1334         {0x1A, AC_VERB_SET_AMP_GAIN_MUTE,
1335          AC_AMP_SET_OUTPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x00},
1336         {0x1A, AC_VERB_SET_AMP_GAIN_MUTE,
1337          AC_AMP_SET_OUTPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x03},
1338         /* SPDIF route: PCM */
1339         { 0x18, AC_VERB_SET_CONNECT_SEL, 0x0 },
1340         /* Enable unsolicited events */
1341         {0x13, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT},
1342         {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT},
1343         { } /* end */
1344 };
1345
1346 /* configuration for Toshiba Laptops */
1347 static struct hda_verb cxt5047_toshiba_init_verbs[] = {
1348         {0x13, AC_VERB_SET_EAPD_BTLENABLE, 0x0}, /* default off */
1349         {}
1350 };
1351
1352 /* Test configuration for debugging, modelled after the ALC260 test
1353  * configuration.
1354  */
1355 #ifdef CONFIG_SND_DEBUG
1356 static struct hda_input_mux cxt5047_test_capture_source = {
1357         .num_items = 4,
1358         .items = {
1359                 { "LINE1 pin", 0x0 },
1360                 { "MIC1 pin", 0x1 },
1361                 { "MIC2 pin", 0x2 },
1362                 { "CD pin", 0x3 },
1363         },
1364 };
1365
1366 static struct snd_kcontrol_new cxt5047_test_mixer[] = {
1367
1368         /* Output only controls */
1369         HDA_CODEC_VOLUME("OutAmp-1 Volume", 0x10, 0x0, HDA_OUTPUT),
1370         HDA_CODEC_MUTE("OutAmp-1 Switch", 0x10,0x0, HDA_OUTPUT),
1371         HDA_CODEC_VOLUME("OutAmp-2 Volume", 0x1c, 0x0, HDA_OUTPUT),
1372         HDA_CODEC_MUTE("OutAmp-2 Switch", 0x1c, 0x0, HDA_OUTPUT),
1373         HDA_CODEC_VOLUME("Speaker Playback Volume", 0x1d, 0x0, HDA_OUTPUT),
1374         HDA_CODEC_MUTE("Speaker Playback Switch", 0x1d, 0x0, HDA_OUTPUT),
1375         HDA_CODEC_VOLUME("HeadPhone Playback Volume", 0x13, 0x0, HDA_OUTPUT),
1376         HDA_CODEC_MUTE("HeadPhone Playback Switch", 0x13, 0x0, HDA_OUTPUT),
1377         HDA_CODEC_VOLUME("Line1-Out Playback Volume", 0x14, 0x0, HDA_OUTPUT),
1378         HDA_CODEC_MUTE("Line1-Out Playback Switch", 0x14, 0x0, HDA_OUTPUT),
1379         HDA_CODEC_VOLUME("Line2-Out Playback Volume", 0x15, 0x0, HDA_OUTPUT),
1380         HDA_CODEC_MUTE("Line2-Out Playback Switch", 0x15, 0x0, HDA_OUTPUT),
1381
1382         /* Modes for retasking pin widgets */
1383         CXT_PIN_MODE("LINE1 pin mode", 0x14, CXT_PIN_DIR_INOUT),
1384         CXT_PIN_MODE("MIC1 pin mode", 0x15, CXT_PIN_DIR_INOUT),
1385
1386         /* EAPD Switch Control */
1387         CXT_EAPD_SWITCH("External Amplifier", 0x13, 0x0),
1388
1389         /* Loopback mixer controls */
1390         HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x12, 0x01, HDA_INPUT),
1391         HDA_CODEC_MUTE("MIC1 Playback Switch", 0x12, 0x01, HDA_INPUT),
1392         HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x12, 0x02, HDA_INPUT),
1393         HDA_CODEC_MUTE("MIC2 Playback Switch", 0x12, 0x02, HDA_INPUT),
1394         HDA_CODEC_VOLUME("LINE Playback Volume", 0x12, 0x0, HDA_INPUT),
1395         HDA_CODEC_MUTE("LINE Playback Switch", 0x12, 0x0, HDA_INPUT),
1396         HDA_CODEC_VOLUME("CD Playback Volume", 0x12, 0x04, HDA_INPUT),
1397         HDA_CODEC_MUTE("CD Playback Switch", 0x12, 0x04, HDA_INPUT),
1398
1399         HDA_CODEC_VOLUME("Capture-1 Volume", 0x19, 0x0, HDA_INPUT),
1400         HDA_CODEC_MUTE("Capture-1 Switch", 0x19, 0x0, HDA_INPUT),
1401         HDA_CODEC_VOLUME("Capture-2 Volume", 0x19, 0x1, HDA_INPUT),
1402         HDA_CODEC_MUTE("Capture-2 Switch", 0x19, 0x1, HDA_INPUT),
1403         HDA_CODEC_VOLUME("Capture-3 Volume", 0x19, 0x2, HDA_INPUT),
1404         HDA_CODEC_MUTE("Capture-3 Switch", 0x19, 0x2, HDA_INPUT),
1405         HDA_CODEC_VOLUME("Capture-4 Volume", 0x19, 0x3, HDA_INPUT),
1406         HDA_CODEC_MUTE("Capture-4 Switch", 0x19, 0x3, HDA_INPUT),
1407         {
1408                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1409                 .name = "Input Source",
1410                 .info = conexant_mux_enum_info,
1411                 .get = conexant_mux_enum_get,
1412                 .put = conexant_mux_enum_put,
1413         },
1414         HDA_CODEC_VOLUME("Mic Boost Volume", 0x1a, 0x0, HDA_OUTPUT),
1415
1416         { } /* end */
1417 };
1418
1419 static struct hda_verb cxt5047_test_init_verbs[] = {
1420         /* Enable retasking pins as output, initially without power amp */
1421         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1422         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1423         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1424
1425         /* Disable digital (SPDIF) pins initially, but users can enable
1426          * them via a mixer switch.  In the case of SPDIF-out, this initverb
1427          * payload also sets the generation to 0, output to be in "consumer"
1428          * PCM format, copyright asserted, no pre-emphasis and no validity
1429          * control.
1430          */
1431         {0x18, AC_VERB_SET_DIGI_CONVERT_1, 0},
1432
1433         /* Ensure mic1, mic2, line1 pin widgets take input from the 
1434          * OUT1 sum bus when acting as an output.
1435          */
1436         {0x1a, AC_VERB_SET_CONNECT_SEL, 0},
1437         {0x1b, AC_VERB_SET_CONNECT_SEL, 0},
1438
1439         /* Start with output sum widgets muted and their output gains at min */
1440         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1441         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1442
1443         /* Unmute retasking pin widget output buffers since the default
1444          * state appears to be output.  As the pin mode is changed by the
1445          * user the pin mode control will take care of enabling the pin's
1446          * input/output buffers as needed.
1447          */
1448         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1449         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1450         {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1451
1452         /* Mute capture amp left and right */
1453         {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1454
1455         /* Set ADC connection select to match default mixer setting (mic1
1456          * pin)
1457          */
1458         {0x12, AC_VERB_SET_CONNECT_SEL, 0x00},
1459
1460         /* Mute all inputs to mixer widget (even unconnected ones) */
1461         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
1462         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
1463         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
1464         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
1465         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
1466         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
1467         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
1468         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
1469
1470         { }
1471 };
1472 #endif
1473
1474
1475 /* initialize jack-sensing, too */
1476 static int cxt5047_hp_init(struct hda_codec *codec)
1477 {
1478         conexant_init(codec);
1479         cxt5047_hp_automute(codec);
1480         return 0;
1481 }
1482
1483
1484 enum {
1485         CXT5047_LAPTOP,         /* Laptops w/o EAPD support */
1486         CXT5047_LAPTOP_HP,      /* Some HP laptops */
1487         CXT5047_LAPTOP_EAPD,    /* Laptops with EAPD support */
1488 #ifdef CONFIG_SND_DEBUG
1489         CXT5047_TEST,
1490 #endif
1491         CXT5047_MODELS
1492 };
1493
1494 static const char *cxt5047_models[CXT5047_MODELS] = {
1495         [CXT5047_LAPTOP]        = "laptop",
1496         [CXT5047_LAPTOP_HP]     = "laptop-hp",
1497         [CXT5047_LAPTOP_EAPD]   = "laptop-eapd",
1498 #ifdef CONFIG_SND_DEBUG
1499         [CXT5047_TEST]          = "test",
1500 #endif
1501 };
1502
1503 static struct snd_pci_quirk cxt5047_cfg_tbl[] = {
1504         SND_PCI_QUIRK(0x103c, 0x30a5, "HP DV5200T/DV8000T", CXT5047_LAPTOP_HP),
1505         SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3000, "HP DV Series",
1506                            CXT5047_LAPTOP),
1507         SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba P100", CXT5047_LAPTOP_EAPD),
1508         {}
1509 };
1510
1511 static int patch_cxt5047(struct hda_codec *codec)
1512 {
1513         struct conexant_spec *spec;
1514         int board_config;
1515
1516         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1517         if (!spec)
1518                 return -ENOMEM;
1519         codec->spec = spec;
1520         codec->pin_amp_workaround = 1;
1521
1522         spec->multiout.max_channels = 2;
1523         spec->multiout.num_dacs = ARRAY_SIZE(cxt5047_dac_nids);
1524         spec->multiout.dac_nids = cxt5047_dac_nids;
1525         spec->multiout.dig_out_nid = CXT5047_SPDIF_OUT;
1526         spec->num_adc_nids = 1;
1527         spec->adc_nids = cxt5047_adc_nids;
1528         spec->capsrc_nids = cxt5047_capsrc_nids;
1529         spec->num_mixers = 1;
1530         spec->mixers[0] = cxt5047_base_mixers;
1531         spec->num_init_verbs = 1;
1532         spec->init_verbs[0] = cxt5047_init_verbs;
1533         spec->spdif_route = 0;
1534         spec->num_channel_mode = ARRAY_SIZE(cxt5047_modes),
1535         spec->channel_mode = cxt5047_modes,
1536
1537         codec->patch_ops = conexant_patch_ops;
1538
1539         board_config = snd_hda_check_board_config(codec, CXT5047_MODELS,
1540                                                   cxt5047_models,
1541                                                   cxt5047_cfg_tbl);
1542         switch (board_config) {
1543         case CXT5047_LAPTOP:
1544                 spec->num_mixers = 2;
1545                 spec->mixers[1] = cxt5047_hp_spk_mixers;
1546                 codec->patch_ops.unsol_event = cxt5047_hp_unsol_event;
1547                 break;
1548         case CXT5047_LAPTOP_HP:
1549                 spec->num_mixers = 2;
1550                 spec->mixers[1] = cxt5047_hp_only_mixers;
1551                 codec->patch_ops.unsol_event = cxt5047_hp_unsol_event;
1552                 codec->patch_ops.init = cxt5047_hp_init;
1553                 break;
1554         case CXT5047_LAPTOP_EAPD:
1555                 spec->input_mux = &cxt5047_toshiba_capture_source;
1556                 spec->num_mixers = 2;
1557                 spec->mixers[1] = cxt5047_hp_spk_mixers;
1558                 spec->num_init_verbs = 2;
1559                 spec->init_verbs[1] = cxt5047_toshiba_init_verbs;
1560                 codec->patch_ops.unsol_event = cxt5047_hp_unsol_event;
1561                 break;
1562 #ifdef CONFIG_SND_DEBUG
1563         case CXT5047_TEST:
1564                 spec->input_mux = &cxt5047_test_capture_source;
1565                 spec->mixers[0] = cxt5047_test_mixer;
1566                 spec->init_verbs[0] = cxt5047_test_init_verbs;
1567                 codec->patch_ops.unsol_event = cxt5047_hp_unsol_event;
1568 #endif  
1569         }
1570         spec->vmaster_nid = 0x13;
1571         return 0;
1572 }
1573
1574 /* Conexant 5051 specific */
1575 static hda_nid_t cxt5051_dac_nids[1] = { 0x10 };
1576 static hda_nid_t cxt5051_adc_nids[2] = { 0x14, 0x15 };
1577
1578 static struct hda_channel_mode cxt5051_modes[1] = {
1579         { 2, NULL },
1580 };
1581
1582 static void cxt5051_update_speaker(struct hda_codec *codec)
1583 {
1584         struct conexant_spec *spec = codec->spec;
1585         unsigned int pinctl;
1586         pinctl = (!spec->hp_present && spec->cur_eapd) ? PIN_OUT : 0;
1587         snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
1588                             pinctl);
1589 }
1590
1591 /* turn on/off EAPD (+ mute HP) as a master switch */
1592 static int cxt5051_hp_master_sw_put(struct snd_kcontrol *kcontrol,
1593                                     struct snd_ctl_elem_value *ucontrol)
1594 {
1595         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1596
1597         if (!cxt_eapd_put(kcontrol, ucontrol))
1598                 return 0;
1599         cxt5051_update_speaker(codec);
1600         return 1;
1601 }
1602
1603 /* toggle input of built-in and mic jack appropriately */
1604 static void cxt5051_portb_automic(struct hda_codec *codec)
1605 {
1606         struct conexant_spec *spec = codec->spec;
1607         unsigned int present;
1608
1609         if (spec->no_auto_mic)
1610                 return;
1611         present = snd_hda_jack_detect(codec, 0x17);
1612         snd_hda_codec_write(codec, 0x14, 0,
1613                             AC_VERB_SET_CONNECT_SEL,
1614                             present ? 0x01 : 0x00);
1615 }
1616
1617 /* switch the current ADC according to the jack state */
1618 static void cxt5051_portc_automic(struct hda_codec *codec)
1619 {
1620         struct conexant_spec *spec = codec->spec;
1621         unsigned int present;
1622         hda_nid_t new_adc;
1623
1624         if (spec->no_auto_mic)
1625                 return;
1626         present = snd_hda_jack_detect(codec, 0x18);
1627         if (present)
1628                 spec->cur_adc_idx = 1;
1629         else
1630                 spec->cur_adc_idx = 0;
1631         new_adc = spec->adc_nids[spec->cur_adc_idx];
1632         if (spec->cur_adc && spec->cur_adc != new_adc) {
1633                 /* stream is running, let's swap the current ADC */
1634                 snd_hda_codec_cleanup_stream(codec, spec->cur_adc);
1635                 spec->cur_adc = new_adc;
1636                 snd_hda_codec_setup_stream(codec, new_adc,
1637                                            spec->cur_adc_stream_tag, 0,
1638                                            spec->cur_adc_format);
1639         }
1640 }
1641
1642 /* mute internal speaker if HP is plugged */
1643 static void cxt5051_hp_automute(struct hda_codec *codec)
1644 {
1645         struct conexant_spec *spec = codec->spec;
1646
1647         spec->hp_present = snd_hda_jack_detect(codec, 0x16);
1648         cxt5051_update_speaker(codec);
1649 }
1650
1651 /* unsolicited event for HP jack sensing */
1652 static void cxt5051_hp_unsol_event(struct hda_codec *codec,
1653                                    unsigned int res)
1654 {
1655         int nid = (res & AC_UNSOL_RES_SUBTAG) >> 20;
1656         switch (res >> 26) {
1657         case CONEXANT_HP_EVENT:
1658                 cxt5051_hp_automute(codec);
1659                 break;
1660         case CXT5051_PORTB_EVENT:
1661                 cxt5051_portb_automic(codec);
1662                 break;
1663         case CXT5051_PORTC_EVENT:
1664                 cxt5051_portc_automic(codec);
1665                 break;
1666         }
1667         conexant_report_jack(codec, nid);
1668 }
1669
1670 static struct snd_kcontrol_new cxt5051_mixers[] = {
1671         HDA_CODEC_VOLUME("Internal Mic Volume", 0x14, 0x00, HDA_INPUT),
1672         HDA_CODEC_MUTE("Internal Mic Switch", 0x14, 0x00, HDA_INPUT),
1673         HDA_CODEC_VOLUME("External Mic Volume", 0x14, 0x01, HDA_INPUT),
1674         HDA_CODEC_MUTE("External Mic Switch", 0x14, 0x01, HDA_INPUT),
1675         HDA_CODEC_VOLUME("Docking Mic Volume", 0x15, 0x00, HDA_INPUT),
1676         HDA_CODEC_MUTE("Docking Mic Switch", 0x15, 0x00, HDA_INPUT),
1677         HDA_CODEC_VOLUME("Master Playback Volume", 0x10, 0x00, HDA_OUTPUT),
1678         {
1679                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1680                 .name = "Master Playback Switch",
1681                 .info = cxt_eapd_info,
1682                 .get = cxt_eapd_get,
1683                 .put = cxt5051_hp_master_sw_put,
1684                 .private_value = 0x1a,
1685         },
1686
1687         {}
1688 };
1689
1690 static struct snd_kcontrol_new cxt5051_hp_mixers[] = {
1691         HDA_CODEC_VOLUME("Internal Mic Volume", 0x14, 0x00, HDA_INPUT),
1692         HDA_CODEC_MUTE("Internal Mic Switch", 0x14, 0x00, HDA_INPUT),
1693         HDA_CODEC_VOLUME("External Mic Volume", 0x15, 0x00, HDA_INPUT),
1694         HDA_CODEC_MUTE("External Mic Switch", 0x15, 0x00, HDA_INPUT),
1695         HDA_CODEC_VOLUME("Master Playback Volume", 0x10, 0x00, HDA_OUTPUT),
1696         {
1697                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1698                 .name = "Master Playback Switch",
1699                 .info = cxt_eapd_info,
1700                 .get = cxt_eapd_get,
1701                 .put = cxt5051_hp_master_sw_put,
1702                 .private_value = 0x1a,
1703         },
1704
1705         {}
1706 };
1707
1708 static struct snd_kcontrol_new cxt5051_hp_dv6736_mixers[] = {
1709         HDA_CODEC_VOLUME("Mic Volume", 0x14, 0x00, HDA_INPUT),
1710         HDA_CODEC_MUTE("Mic Switch", 0x14, 0x00, HDA_INPUT),
1711         HDA_CODEC_VOLUME("Master Playback Volume", 0x10, 0x00, HDA_OUTPUT),
1712         {
1713                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1714                 .name = "Master Playback Switch",
1715                 .info = cxt_eapd_info,
1716                 .get = cxt_eapd_get,
1717                 .put = cxt5051_hp_master_sw_put,
1718                 .private_value = 0x1a,
1719         },
1720
1721         {}
1722 };
1723
1724 static struct hda_verb cxt5051_init_verbs[] = {
1725         /* Line in, Mic */
1726         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03},
1727         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1728         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03},
1729         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1730         {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1731         {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03},
1732         /* SPK  */
1733         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1734         {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
1735         /* HP, Amp  */
1736         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1737         {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
1738         /* DAC1 */      
1739         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1740         /* Record selector: Int mic */
1741         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x44},
1742         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1) | 0x44},
1743         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x44},
1744         /* SPDIF route: PCM */
1745         {0x1c, AC_VERB_SET_CONNECT_SEL, 0x0},
1746         /* EAPD */
1747         {0x1a, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */ 
1748         {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CONEXANT_HP_EVENT},
1749         {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CXT5051_PORTB_EVENT},
1750         {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CXT5051_PORTC_EVENT},
1751         { } /* end */
1752 };
1753
1754 static struct hda_verb cxt5051_hp_dv6736_init_verbs[] = {
1755         /* Line in, Mic */
1756         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03},
1757         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1758         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0},
1759         {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0},
1760         /* SPK  */
1761         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1762         {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
1763         /* HP, Amp  */
1764         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1765         {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
1766         /* DAC1 */
1767         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1768         /* Record selector: Int mic */
1769         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1) | 0x44},
1770         {0x14, AC_VERB_SET_CONNECT_SEL, 0x1},
1771         /* SPDIF route: PCM */
1772         {0x1c, AC_VERB_SET_CONNECT_SEL, 0x0},
1773         /* EAPD */
1774         {0x1a, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
1775         {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CONEXANT_HP_EVENT},
1776         {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CXT5051_PORTB_EVENT},
1777         { } /* end */
1778 };
1779
1780 static struct hda_verb cxt5051_lenovo_x200_init_verbs[] = {
1781         /* Line in, Mic */
1782         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03},
1783         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1784         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03},
1785         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1786         {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1787         {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03},
1788         /* SPK  */
1789         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1790         {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
1791         /* HP, Amp  */
1792         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1793         {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
1794         /* Docking HP */
1795         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1796         {0x19, AC_VERB_SET_CONNECT_SEL, 0x00},
1797         /* DAC1 */
1798         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1799         /* Record selector: Int mic */
1800         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x44},
1801         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1) | 0x44},
1802         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x44},
1803         /* SPDIF route: PCM */
1804         {0x1c, AC_VERB_SET_CONNECT_SEL, 0x0},
1805         /* EAPD */
1806         {0x1a, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
1807         {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CONEXANT_HP_EVENT},
1808         {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CXT5051_PORTB_EVENT},
1809         {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CXT5051_PORTC_EVENT},
1810         {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CONEXANT_HP_EVENT},
1811         { } /* end */
1812 };
1813
1814 /* initialize jack-sensing, too */
1815 static int cxt5051_init(struct hda_codec *codec)
1816 {
1817         conexant_init(codec);
1818         conexant_init_jacks(codec);
1819         if (codec->patch_ops.unsol_event) {
1820                 cxt5051_hp_automute(codec);
1821                 cxt5051_portb_automic(codec);
1822                 cxt5051_portc_automic(codec);
1823         }
1824         return 0;
1825 }
1826
1827
1828 enum {
1829         CXT5051_LAPTOP,  /* Laptops w/ EAPD support */
1830         CXT5051_HP,     /* no docking */
1831         CXT5051_HP_DV6736,      /* HP without mic switch */
1832         CXT5051_LENOVO_X200,    /* Lenovo X200 laptop */
1833         CXT5051_MODELS
1834 };
1835
1836 static const char *cxt5051_models[CXT5051_MODELS] = {
1837         [CXT5051_LAPTOP]        = "laptop",
1838         [CXT5051_HP]            = "hp",
1839         [CXT5051_HP_DV6736]     = "hp-dv6736",
1840         [CXT5051_LENOVO_X200]   = "lenovo-x200",
1841 };
1842
1843 static struct snd_pci_quirk cxt5051_cfg_tbl[] = {
1844         SND_PCI_QUIRK(0x103c, 0x30cf, "HP DV6736", CXT5051_HP_DV6736),
1845         SND_PCI_QUIRK(0x103c, 0x360b, "Compaq Presario CQ60", CXT5051_HP),
1846         SND_PCI_QUIRK(0x14f1, 0x0101, "Conexant Reference board",
1847                       CXT5051_LAPTOP),
1848         SND_PCI_QUIRK(0x14f1, 0x5051, "HP Spartan 1.1", CXT5051_HP),
1849         SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo X200", CXT5051_LENOVO_X200),
1850         {}
1851 };
1852
1853 static int patch_cxt5051(struct hda_codec *codec)
1854 {
1855         struct conexant_spec *spec;
1856         int board_config;
1857
1858         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1859         if (!spec)
1860                 return -ENOMEM;
1861         codec->spec = spec;
1862         codec->pin_amp_workaround = 1;
1863
1864         codec->patch_ops = conexant_patch_ops;
1865         codec->patch_ops.init = cxt5051_init;
1866
1867         spec->multiout.max_channels = 2;
1868         spec->multiout.num_dacs = ARRAY_SIZE(cxt5051_dac_nids);
1869         spec->multiout.dac_nids = cxt5051_dac_nids;
1870         spec->multiout.dig_out_nid = CXT5051_SPDIF_OUT;
1871         spec->num_adc_nids = 1; /* not 2; via auto-mic switch */
1872         spec->adc_nids = cxt5051_adc_nids;
1873         spec->num_mixers = 1;
1874         spec->mixers[0] = cxt5051_mixers;
1875         spec->num_init_verbs = 1;
1876         spec->init_verbs[0] = cxt5051_init_verbs;
1877         spec->spdif_route = 0;
1878         spec->num_channel_mode = ARRAY_SIZE(cxt5051_modes);
1879         spec->channel_mode = cxt5051_modes;
1880         spec->cur_adc = 0;
1881         spec->cur_adc_idx = 0;
1882
1883         codec->patch_ops.unsol_event = cxt5051_hp_unsol_event;
1884
1885         board_config = snd_hda_check_board_config(codec, CXT5051_MODELS,
1886                                                   cxt5051_models,
1887                                                   cxt5051_cfg_tbl);
1888         switch (board_config) {
1889         case CXT5051_HP:
1890                 spec->mixers[0] = cxt5051_hp_mixers;
1891                 break;
1892         case CXT5051_HP_DV6736:
1893                 spec->init_verbs[0] = cxt5051_hp_dv6736_init_verbs;
1894                 spec->mixers[0] = cxt5051_hp_dv6736_mixers;
1895                 spec->no_auto_mic = 1;
1896                 break;
1897         case CXT5051_LENOVO_X200:
1898                 spec->init_verbs[0] = cxt5051_lenovo_x200_init_verbs;
1899                 break;
1900         }
1901
1902         return 0;
1903 }
1904
1905 /* Conexant 5066 specific */
1906
1907 static hda_nid_t cxt5066_dac_nids[1] = { 0x10 };
1908 static hda_nid_t cxt5066_adc_nids[3] = { 0x14, 0x15, 0x16 };
1909 static hda_nid_t cxt5066_capsrc_nids[1] = { 0x17 };
1910 #define CXT5066_SPDIF_OUT       0x21
1911
1912 /* OLPC's microphone port is DC coupled for use with external sensors,
1913  * therefore we use a 50% mic bias in order to center the input signal with
1914  * the DC input range of the codec. */
1915 #define CXT5066_OLPC_EXT_MIC_BIAS PIN_VREF50
1916
1917 static struct hda_channel_mode cxt5066_modes[1] = {
1918         { 2, NULL },
1919 };
1920
1921 static void cxt5066_update_speaker(struct hda_codec *codec)
1922 {
1923         struct conexant_spec *spec = codec->spec;
1924         unsigned int pinctl;
1925
1926         snd_printdd("CXT5066: update speaker, hp_present=%d\n",
1927                 spec->hp_present);
1928
1929         /* Port A (HP) */
1930         pinctl = ((spec->hp_present & 1) && spec->cur_eapd) ? PIN_HP : 0;
1931         snd_hda_codec_write(codec, 0x19, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
1932                         pinctl);
1933
1934         /* Port D (HP/LO) */
1935         pinctl = ((spec->hp_present & 2) && spec->cur_eapd)
1936                 ? spec->port_d_mode : 0;
1937         snd_hda_codec_write(codec, 0x1c, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
1938                         pinctl);
1939
1940         /* CLASS_D AMP */
1941         pinctl = (!spec->hp_present && spec->cur_eapd) ? PIN_OUT : 0;
1942         snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
1943                         pinctl);
1944
1945         if (spec->dell_automute) {
1946                 /* DELL AIO Port Rule: PortA > PortD > IntSpk */
1947                 pinctl = (!(spec->hp_present & 1) && spec->cur_eapd)
1948                         ? PIN_OUT : 0;
1949                 snd_hda_codec_write(codec, 0x1c, 0,
1950                         AC_VERB_SET_PIN_WIDGET_CONTROL, pinctl);
1951         }
1952 }
1953
1954 /* turn on/off EAPD (+ mute HP) as a master switch */
1955 static int cxt5066_hp_master_sw_put(struct snd_kcontrol *kcontrol,
1956                                     struct snd_ctl_elem_value *ucontrol)
1957 {
1958         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1959
1960         if (!cxt_eapd_put(kcontrol, ucontrol))
1961                 return 0;
1962
1963         cxt5066_update_speaker(codec);
1964         return 1;
1965 }
1966
1967 /* toggle input of built-in and mic jack appropriately */
1968 static void cxt5066_automic(struct hda_codec *codec)
1969 {
1970         struct conexant_spec *spec = codec->spec;
1971         struct hda_verb ext_mic_present[] = {
1972                 /* enable external mic, port B */
1973                 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, spec->ext_mic_bias},
1974
1975                 /* switch to external mic input */
1976                 {0x17, AC_VERB_SET_CONNECT_SEL, 0},
1977
1978                 /* disable internal mic, port C */
1979                 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
1980                 {}
1981         };
1982         static struct hda_verb ext_mic_absent[] = {
1983                 /* enable internal mic, port C */
1984                 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1985
1986                 /* switch to internal mic input */
1987                 {0x17, AC_VERB_SET_CONNECT_SEL, 1},
1988
1989                 /* disable external mic, port B */
1990                 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
1991                 {}
1992         };
1993         unsigned int present;
1994
1995         present = snd_hda_jack_detect(codec, 0x1a);
1996         if (present) {
1997                 snd_printdd("CXT5066: external microphone detected\n");
1998                 snd_hda_sequence_write(codec, ext_mic_present);
1999         } else {
2000                 snd_printdd("CXT5066: external microphone absent\n");
2001                 snd_hda_sequence_write(codec, ext_mic_absent);
2002         }
2003 }
2004
2005 /* toggle input of built-in digital mic and mic jack appropriately */
2006 static void cxt5066_vostro_automic(struct hda_codec *codec)
2007 {
2008         struct conexant_spec *spec = codec->spec;
2009         unsigned int present;
2010
2011         struct hda_verb ext_mic_present[] = {
2012                 /* enable external mic, port B */
2013                 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, spec->ext_mic_bias},
2014
2015                 /* switch to external mic input */
2016                 {0x17, AC_VERB_SET_CONNECT_SEL, 0},
2017                 {0x14, AC_VERB_SET_CONNECT_SEL, 0},
2018
2019                 /* disable internal digital mic */
2020                 {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2021                 {}
2022         };
2023         static struct hda_verb ext_mic_absent[] = {
2024                 /* enable internal mic, port C */
2025                 {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2026
2027                 /* switch to internal mic input */
2028                 {0x14, AC_VERB_SET_CONNECT_SEL, 2},
2029
2030                 /* disable external mic, port B */
2031                 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2032                 {}
2033         };
2034
2035         present = snd_hda_jack_detect(codec, 0x1a);
2036         if (present) {
2037                 snd_printdd("CXT5066: external microphone detected\n");
2038                 snd_hda_sequence_write(codec, ext_mic_present);
2039         } else {
2040                 snd_printdd("CXT5066: external microphone absent\n");
2041                 snd_hda_sequence_write(codec, ext_mic_absent);
2042         }
2043 }
2044
2045 /* mute internal speaker if HP is plugged */
2046 static void cxt5066_hp_automute(struct hda_codec *codec)
2047 {
2048         struct conexant_spec *spec = codec->spec;
2049         unsigned int portA, portD;
2050
2051         /* Port A */
2052         portA = snd_hda_jack_detect(codec, 0x19);
2053
2054         /* Port D */
2055         portD = snd_hda_jack_detect(codec, 0x1c);
2056
2057         spec->hp_present = !!(portA | portD);
2058         snd_printdd("CXT5066: hp automute portA=%x portD=%x present=%d\n",
2059                 portA, portD, spec->hp_present);
2060         cxt5066_update_speaker(codec);
2061 }
2062
2063 /* unsolicited event for jack sensing */
2064 static void cxt5066_unsol_event(struct hda_codec *codec, unsigned int res)
2065 {
2066         snd_printdd("CXT5066: unsol event %x (%x)\n", res, res >> 26);
2067         switch (res >> 26) {
2068         case CONEXANT_HP_EVENT:
2069                 cxt5066_hp_automute(codec);
2070                 break;
2071         case CONEXANT_MIC_EVENT:
2072                 cxt5066_automic(codec);
2073                 break;
2074         }
2075 }
2076
2077 /* unsolicited event for jack sensing */
2078 static void cxt5066_vostro_event(struct hda_codec *codec, unsigned int res)
2079 {
2080         snd_printdd("CXT5066_vostro: unsol event %x (%x)\n", res, res >> 26);
2081         switch (res >> 26) {
2082         case CONEXANT_HP_EVENT:
2083                 cxt5066_hp_automute(codec);
2084                 break;
2085         case CONEXANT_MIC_EVENT:
2086                 cxt5066_vostro_automic(codec);
2087                 break;
2088         }
2089 }
2090
2091 static const struct hda_input_mux cxt5066_analog_mic_boost = {
2092         .num_items = 5,
2093         .items = {
2094                 { "0dB",  0 },
2095                 { "10dB", 1 },
2096                 { "20dB", 2 },
2097                 { "30dB", 3 },
2098                 { "40dB", 4 },
2099         },
2100 };
2101
2102 static int cxt5066_mic_boost_mux_enum_info(struct snd_kcontrol *kcontrol,
2103                                            struct snd_ctl_elem_info *uinfo)
2104 {
2105         return snd_hda_input_mux_info(&cxt5066_analog_mic_boost, uinfo);
2106 }
2107
2108 static int cxt5066_mic_boost_mux_enum_get(struct snd_kcontrol *kcontrol,
2109                                           struct snd_ctl_elem_value *ucontrol)
2110 {
2111         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2112         int val;
2113         hda_nid_t nid = kcontrol->private_value & 0xff;
2114         int inout = (kcontrol->private_value & 0x100) ?
2115                 AC_AMP_GET_INPUT : AC_AMP_GET_OUTPUT;
2116
2117         val = snd_hda_codec_read(codec, nid, 0,
2118                 AC_VERB_GET_AMP_GAIN_MUTE, inout);
2119
2120         ucontrol->value.enumerated.item[0] = val & AC_AMP_GAIN;
2121         return 0;
2122 }
2123
2124 static int cxt5066_mic_boost_mux_enum_put(struct snd_kcontrol *kcontrol,
2125                                           struct snd_ctl_elem_value *ucontrol)
2126 {
2127         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2128         const struct hda_input_mux *imux = &cxt5066_analog_mic_boost;
2129         unsigned int idx;
2130         hda_nid_t nid = kcontrol->private_value & 0xff;
2131         int inout = (kcontrol->private_value & 0x100) ?
2132                 AC_AMP_SET_INPUT : AC_AMP_SET_OUTPUT;
2133
2134         if (!imux->num_items)
2135                 return 0;
2136         idx = ucontrol->value.enumerated.item[0];
2137         if (idx >= imux->num_items)
2138                 idx = imux->num_items - 1;
2139
2140         snd_hda_codec_write_cache(codec, nid, 0,
2141                 AC_VERB_SET_AMP_GAIN_MUTE,
2142                 AC_AMP_SET_RIGHT | AC_AMP_SET_LEFT | inout |
2143                         imux->items[idx].index);
2144
2145         return 1;
2146 }
2147
2148 static struct hda_input_mux cxt5066_capture_source = {
2149         .num_items = 4,
2150         .items = {
2151                 { "Mic B", 0 },
2152                 { "Mic C", 1 },
2153                 { "Mic E", 2 },
2154                 { "Mic F", 3 },
2155         },
2156 };
2157
2158 static struct hda_bind_ctls cxt5066_bind_capture_vol_others = {
2159         .ops = &snd_hda_bind_vol,
2160         .values = {
2161                 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_INPUT),
2162                 HDA_COMPOSE_AMP_VAL(0x14, 3, 2, HDA_INPUT),
2163                 0
2164         },
2165 };
2166
2167 static struct hda_bind_ctls cxt5066_bind_capture_sw_others = {
2168         .ops = &snd_hda_bind_sw,
2169         .values = {
2170                 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_INPUT),
2171                 HDA_COMPOSE_AMP_VAL(0x14, 3, 2, HDA_INPUT),
2172                 0
2173         },
2174 };
2175
2176 static struct snd_kcontrol_new cxt5066_mixer_master[] = {
2177         HDA_CODEC_VOLUME("Master Playback Volume", 0x10, 0x00, HDA_OUTPUT),
2178         {}
2179 };
2180
2181 static struct snd_kcontrol_new cxt5066_mixer_master_olpc[] = {
2182         {
2183                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2184                 .name = "Master Playback Volume",
2185                 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
2186                                   SNDRV_CTL_ELEM_ACCESS_TLV_READ |
2187                                   SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK,
2188                 .info = snd_hda_mixer_amp_volume_info,
2189                 .get = snd_hda_mixer_amp_volume_get,
2190                 .put = snd_hda_mixer_amp_volume_put,
2191                 .tlv = { .c = snd_hda_mixer_amp_tlv },
2192                 /* offset by 28 volume steps to limit minimum gain to -46dB */
2193                 .private_value =
2194                         HDA_COMPOSE_AMP_VAL_OFS(0x10, 3, 0, HDA_OUTPUT, 28),
2195         },
2196         {}
2197 };
2198
2199 static struct snd_kcontrol_new cxt5066_mixers[] = {
2200         {
2201                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2202                 .name = "Master Playback Switch",
2203                 .info = cxt_eapd_info,
2204                 .get = cxt_eapd_get,
2205                 .put = cxt5066_hp_master_sw_put,
2206                 .private_value = 0x1d,
2207         },
2208
2209         {
2210                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2211                 .name = "Ext Mic Boost Capture Enum",
2212                 .info = cxt5066_mic_boost_mux_enum_info,
2213                 .get = cxt5066_mic_boost_mux_enum_get,
2214                 .put = cxt5066_mic_boost_mux_enum_put,
2215                 .private_value = 0x17,
2216         },
2217
2218         HDA_BIND_VOL("Capture Volume", &cxt5066_bind_capture_vol_others),
2219         HDA_BIND_SW("Capture Switch", &cxt5066_bind_capture_sw_others),
2220         {}
2221 };
2222
2223 static struct snd_kcontrol_new cxt5066_vostro_mixers[] = {
2224         {
2225                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2226                 .name = "Int Mic Boost Capture Enum",
2227                 .info = cxt5066_mic_boost_mux_enum_info,
2228                 .get = cxt5066_mic_boost_mux_enum_get,
2229                 .put = cxt5066_mic_boost_mux_enum_put,
2230                 .private_value = 0x23 | 0x100,
2231         },
2232         {}
2233 };
2234
2235 static struct hda_verb cxt5066_init_verbs[] = {
2236         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, /* Port B */
2237         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, /* Port C */
2238         {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Port F */
2239         {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Port E */
2240
2241         /* Speakers  */
2242         {0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2243         {0x1f, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
2244
2245         /* HP, Amp  */
2246         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2247         {0x19, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
2248
2249         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2250         {0x1c, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
2251
2252         /* DAC1 */
2253         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2254
2255         /* Node 14 connections: 0x17 0x18 0x23 0x24 0x27 */
2256         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x50},
2257         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2258         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2) | 0x50},
2259         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2260         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2261
2262         /* no digital microphone support yet */
2263         {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2264
2265         /* Audio input selector */
2266         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x3},
2267
2268         /* SPDIF route: PCM */
2269         {0x20, AC_VERB_SET_CONNECT_SEL, 0x0},
2270         {0x22, AC_VERB_SET_CONNECT_SEL, 0x0},
2271
2272         {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2273         {0x22, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2274
2275         /* EAPD */
2276         {0x1d, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
2277
2278         /* not handling these yet */
2279         {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, 0},
2280         {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, 0},
2281         {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, 0},
2282         {0x1c, AC_VERB_SET_UNSOLICITED_ENABLE, 0},
2283         {0x1d, AC_VERB_SET_UNSOLICITED_ENABLE, 0},
2284         {0x1e, AC_VERB_SET_UNSOLICITED_ENABLE, 0},
2285         {0x20, AC_VERB_SET_UNSOLICITED_ENABLE, 0},
2286         {0x22, AC_VERB_SET_UNSOLICITED_ENABLE, 0},
2287         { } /* end */
2288 };
2289
2290 static struct hda_verb cxt5066_init_verbs_olpc[] = {
2291         /* Port A: headphones */
2292         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2293         {0x19, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
2294
2295         /* Port B: external microphone */
2296         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, CXT5066_OLPC_EXT_MIC_BIAS},
2297
2298         /* Port C: internal microphone */
2299         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2300
2301         /* Port D: unused */
2302         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2303
2304         /* Port E: unused, but has primary EAPD */
2305         {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2306         {0x1d, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
2307
2308         /* Port F: unused */
2309         {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2310
2311         /* Port G: internal speakers */
2312         {0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2313         {0x1f, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
2314
2315         /* DAC1 */
2316         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2317
2318         /* DAC2: unused */
2319         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2320
2321         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x50},
2322         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2323         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2324         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2325         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2326         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2327         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2328         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2329         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2330         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2331         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2332         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2333
2334         /* Disable digital microphone port */
2335         {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2336
2337         /* Audio input selectors */
2338         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x3},
2339         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2340
2341         /* Disable SPDIF */
2342         {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2343         {0x22, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2344
2345         /* enable unsolicited events for Port A and B */
2346         {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT},
2347         {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT},
2348         { } /* end */
2349 };
2350
2351 static struct hda_verb cxt5066_init_verbs_vostro[] = {
2352         /* Port A: headphones */
2353         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2354         {0x19, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
2355
2356         /* Port B: external microphone */
2357         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2358
2359         /* Port C: unused */
2360         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2361
2362         /* Port D: unused */
2363         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2364
2365         /* Port E: unused, but has primary EAPD */
2366         {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2367         {0x1d, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
2368
2369         /* Port F: unused */
2370         {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2371
2372         /* Port G: internal speakers */
2373         {0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2374         {0x1f, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
2375
2376         /* DAC1 */
2377         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2378
2379         /* DAC2: unused */
2380         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2381
2382         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2383         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2384         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2385         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2386         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2387         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2388         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2389         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2390         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2391         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2392         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2393         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2394
2395         /* Digital microphone port */
2396         {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2397
2398         /* Audio input selectors */
2399         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x3},
2400         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2401
2402         /* Disable SPDIF */
2403         {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2404         {0x22, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2405
2406         /* enable unsolicited events for Port A and B */
2407         {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT},
2408         {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT},
2409         { } /* end */
2410 };
2411
2412 static struct hda_verb cxt5066_init_verbs_portd_lo[] = {
2413         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2414         { } /* end */
2415 };
2416
2417 /* initialize jack-sensing, too */
2418 static int cxt5066_init(struct hda_codec *codec)
2419 {
2420         struct conexant_spec *spec = codec->spec;
2421
2422         snd_printdd("CXT5066: init\n");
2423         conexant_init(codec);
2424         if (codec->patch_ops.unsol_event) {
2425                 cxt5066_hp_automute(codec);
2426                 if (spec->dell_vostro)
2427                         cxt5066_vostro_automic(codec);
2428                 else
2429                         cxt5066_automic(codec);
2430         }
2431         return 0;
2432 }
2433
2434 enum {
2435         CXT5066_LAPTOP,                 /* Laptops w/ EAPD support */
2436         CXT5066_DELL_LAPTOP,    /* Dell Laptop */
2437         CXT5066_OLPC_XO_1_5,    /* OLPC XO 1.5 */
2438         CXT5066_DELL_VOSTO,     /* Dell Vostro 1015i */
2439         CXT5066_MODELS
2440 };
2441
2442 static const char *cxt5066_models[CXT5066_MODELS] = {
2443         [CXT5066_LAPTOP]                = "laptop",
2444         [CXT5066_DELL_LAPTOP]   = "dell-laptop",
2445         [CXT5066_OLPC_XO_1_5]   = "olpc-xo-1_5",
2446         [CXT5066_DELL_VOSTO]    = "dell-vostro"
2447 };
2448
2449 static struct snd_pci_quirk cxt5066_cfg_tbl[] = {
2450         SND_PCI_QUIRK(0x14f1, 0x0101, "Conexant Reference board",
2451                       CXT5066_LAPTOP),
2452         SND_PCI_QUIRK(0x1028, 0x02f5, "Dell",
2453                       CXT5066_DELL_LAPTOP),
2454         SND_PCI_QUIRK(0x152d, 0x0833, "OLPC XO-1.5", CXT5066_OLPC_XO_1_5),
2455         SND_PCI_QUIRK(0x1028, 0x0402, "Dell Vostro", CXT5066_DELL_VOSTO),
2456         {}
2457 };
2458
2459 static int patch_cxt5066(struct hda_codec *codec)
2460 {
2461         struct conexant_spec *spec;
2462         int board_config;
2463
2464         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
2465         if (!spec)
2466                 return -ENOMEM;
2467         codec->spec = spec;
2468
2469         codec->patch_ops = conexant_patch_ops;
2470         codec->patch_ops.init = cxt5066_init;
2471
2472         spec->dell_automute = 0;
2473         spec->multiout.max_channels = 2;
2474         spec->multiout.num_dacs = ARRAY_SIZE(cxt5066_dac_nids);
2475         spec->multiout.dac_nids = cxt5066_dac_nids;
2476         spec->multiout.dig_out_nid = CXT5066_SPDIF_OUT;
2477         spec->num_adc_nids = 1;
2478         spec->adc_nids = cxt5066_adc_nids;
2479         spec->capsrc_nids = cxt5066_capsrc_nids;
2480         spec->input_mux = &cxt5066_capture_source;
2481
2482         spec->port_d_mode = PIN_HP;
2483         spec->ext_mic_bias = PIN_VREF80;
2484
2485         spec->num_init_verbs = 1;
2486         spec->init_verbs[0] = cxt5066_init_verbs;
2487         spec->num_channel_mode = ARRAY_SIZE(cxt5066_modes);
2488         spec->channel_mode = cxt5066_modes;
2489         spec->cur_adc = 0;
2490         spec->cur_adc_idx = 0;
2491
2492         board_config = snd_hda_check_board_config(codec, CXT5066_MODELS,
2493                                                   cxt5066_models, cxt5066_cfg_tbl);
2494         switch (board_config) {
2495         default:
2496         case CXT5066_LAPTOP:
2497                 spec->mixers[spec->num_mixers++] = cxt5066_mixer_master;
2498                 spec->mixers[spec->num_mixers++] = cxt5066_mixers;
2499                 break;
2500         case CXT5066_DELL_LAPTOP:
2501                 spec->mixers[spec->num_mixers++] = cxt5066_mixer_master;
2502                 spec->mixers[spec->num_mixers++] = cxt5066_mixers;
2503
2504                 spec->port_d_mode = PIN_OUT;
2505                 spec->init_verbs[spec->num_init_verbs] = cxt5066_init_verbs_portd_lo;
2506                 spec->num_init_verbs++;
2507                 spec->dell_automute = 1;
2508                 break;
2509         case CXT5066_OLPC_XO_1_5:
2510                 codec->patch_ops.unsol_event = cxt5066_unsol_event;
2511                 spec->init_verbs[0] = cxt5066_init_verbs_olpc;
2512                 spec->mixers[spec->num_mixers++] = cxt5066_mixer_master_olpc;
2513                 spec->mixers[spec->num_mixers++] = cxt5066_mixers;
2514                 spec->port_d_mode = 0;
2515                 spec->ext_mic_bias = CXT5066_OLPC_EXT_MIC_BIAS;
2516
2517                 /* no S/PDIF out */
2518                 spec->multiout.dig_out_nid = 0;
2519
2520                 /* input source automatically selected */
2521                 spec->input_mux = NULL;
2522                 break;
2523         case CXT5066_DELL_VOSTO:
2524                 codec->patch_ops.unsol_event = cxt5066_vostro_event;
2525                 spec->init_verbs[0] = cxt5066_init_verbs_vostro;
2526                 spec->mixers[spec->num_mixers++] = cxt5066_mixer_master_olpc;
2527                 spec->mixers[spec->num_mixers++] = cxt5066_mixers;
2528                 spec->mixers[spec->num_mixers++] = cxt5066_vostro_mixers;
2529                 spec->port_d_mode = 0;
2530                 spec->dell_vostro = 1;
2531
2532                 /* no S/PDIF out */
2533                 spec->multiout.dig_out_nid = 0;
2534
2535                 /* input source automatically selected */
2536                 spec->input_mux = NULL;
2537                 break;
2538         }
2539
2540         return 0;
2541 }
2542
2543 /*
2544  */
2545
2546 static struct hda_codec_preset snd_hda_preset_conexant[] = {
2547         { .id = 0x14f15045, .name = "CX20549 (Venice)",
2548           .patch = patch_cxt5045 },
2549         { .id = 0x14f15047, .name = "CX20551 (Waikiki)",
2550           .patch = patch_cxt5047 },
2551         { .id = 0x14f15051, .name = "CX20561 (Hermosa)",
2552           .patch = patch_cxt5051 },
2553         { .id = 0x14f15066, .name = "CX20582 (Pebble)",
2554           .patch = patch_cxt5066 },
2555         { .id = 0x14f15067, .name = "CX20583 (Pebble HSF)",
2556           .patch = patch_cxt5066 },
2557         {} /* terminator */
2558 };
2559
2560 MODULE_ALIAS("snd-hda-codec-id:14f15045");
2561 MODULE_ALIAS("snd-hda-codec-id:14f15047");
2562 MODULE_ALIAS("snd-hda-codec-id:14f15051");
2563 MODULE_ALIAS("snd-hda-codec-id:14f15066");
2564 MODULE_ALIAS("snd-hda-codec-id:14f15067");
2565
2566 MODULE_LICENSE("GPL");
2567 MODULE_DESCRIPTION("Conexant HD-audio codec");
2568
2569 static struct hda_codec_preset_list conexant_list = {
2570         .preset = snd_hda_preset_conexant,
2571         .owner = THIS_MODULE,
2572 };
2573
2574 static int __init patch_conexant_init(void)
2575 {
2576         return snd_hda_add_codec_preset(&conexant_list);
2577 }
2578
2579 static void __exit patch_conexant_exit(void)
2580 {
2581         snd_hda_delete_codec_preset(&conexant_list);
2582 }
2583
2584 module_init(patch_conexant_init)
2585 module_exit(patch_conexant_exit)