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