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