sound/pci/hda/patch_via.c: work around gcc-4.0.2 ICE
[~shefty/rdma-dev.git] / sound / pci / hda / patch_conexant.c
1 /*
2  * HD audio interface patch for Conexant HDA audio codec
3  *
4  * Copyright (c) 2006 Pototskiy Akex <alex.pototskiy@gmail.com>
5  *                    Takashi Iwai <tiwai@suse.de>
6  *                    Tobin Davis  <tdavis@dsl-only.net>
7  *
8  *  This driver is free software; you can redistribute it and/or modify
9  *  it under the terms of the GNU General Public License as published by
10  *  the Free Software Foundation; either version 2 of the License, or
11  *  (at your option) any later version.
12  *
13  *  This driver is distributed in the hope that it will be useful,
14  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  *  GNU General Public License for more details.
17  *
18  *  You should have received a copy of the GNU General Public License
19  *  along with this program; if not, write to the Free Software
20  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
21  */
22
23 #include <linux/init.h>
24 #include <linux/delay.h>
25 #include <linux/slab.h>
26 #include <linux/pci.h>
27 #include <sound/core.h>
28 #include <sound/jack.h>
29
30 #include "hda_codec.h"
31 #include "hda_local.h"
32
33 #define CXT_PIN_DIR_IN              0x00
34 #define CXT_PIN_DIR_OUT             0x01
35 #define CXT_PIN_DIR_INOUT           0x02
36 #define CXT_PIN_DIR_IN_NOMICBIAS    0x03
37 #define CXT_PIN_DIR_INOUT_NOMICBIAS 0x04
38
39 #define CONEXANT_HP_EVENT       0x37
40 #define CONEXANT_MIC_EVENT      0x38
41
42 /* Conexant 5051 specific */
43
44 #define CXT5051_SPDIF_OUT       0x1C
45 #define CXT5051_PORTB_EVENT     0x38
46 #define CXT5051_PORTC_EVENT     0x39
47
48
49 struct conexant_jack {
50
51         hda_nid_t nid;
52         int type;
53         struct snd_jack *jack;
54
55 };
56
57 struct conexant_spec {
58
59         struct snd_kcontrol_new *mixers[5];
60         int num_mixers;
61         hda_nid_t vmaster_nid;
62
63         const struct hda_verb *init_verbs[5];   /* initialization verbs
64                                                  * don't forget NULL
65                                                  * termination!
66                                                  */
67         unsigned int num_init_verbs;
68
69         /* playback */
70         struct hda_multi_out multiout;  /* playback set-up
71                                          * max_channels, dacs must be set
72                                          * dig_out_nid and hp_nid are optional
73                                          */
74         unsigned int cur_eapd;
75         unsigned int hp_present;
76         unsigned int no_auto_mic;
77         unsigned int need_dac_fix;
78
79         /* capture */
80         unsigned int num_adc_nids;
81         hda_nid_t *adc_nids;
82         hda_nid_t dig_in_nid;           /* digital-in NID; optional */
83
84         unsigned int cur_adc_idx;
85         hda_nid_t cur_adc;
86         unsigned int cur_adc_stream_tag;
87         unsigned int cur_adc_format;
88
89         /* capture source */
90         const struct hda_input_mux *input_mux;
91         hda_nid_t *capsrc_nids;
92         unsigned int cur_mux[3];
93
94         /* channel model */
95         const struct hda_channel_mode *channel_mode;
96         int num_channel_mode;
97
98         /* PCM information */
99         struct hda_pcm pcm_rec[2];      /* used in build_pcms() */
100
101         unsigned int spdif_route;
102
103         /* jack detection */
104         struct snd_array jacks;
105
106         /* dynamic controls, init_verbs and input_mux */
107         struct auto_pin_cfg autocfg;
108         struct hda_input_mux private_imux;
109         hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
110
111         unsigned int dell_automute;
112         unsigned int port_d_mode;
113 };
114
115 static int conexant_playback_pcm_open(struct hda_pcm_stream *hinfo,
116                                       struct hda_codec *codec,
117                                       struct snd_pcm_substream *substream)
118 {
119         struct conexant_spec *spec = codec->spec;
120         return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
121                                              hinfo);
122 }
123
124 static int conexant_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
125                                          struct hda_codec *codec,
126                                          unsigned int stream_tag,
127                                          unsigned int format,
128                                          struct snd_pcm_substream *substream)
129 {
130         struct conexant_spec *spec = codec->spec;
131         return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
132                                                 stream_tag,
133                                                 format, substream);
134 }
135
136 static int conexant_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
137                                          struct hda_codec *codec,
138                                          struct snd_pcm_substream *substream)
139 {
140         struct conexant_spec *spec = codec->spec;
141         return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
142 }
143
144 /*
145  * Digital out
146  */
147 static int conexant_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
148                                           struct hda_codec *codec,
149                                           struct snd_pcm_substream *substream)
150 {
151         struct conexant_spec *spec = codec->spec;
152         return snd_hda_multi_out_dig_open(codec, &spec->multiout);
153 }
154
155 static int conexant_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
156                                          struct hda_codec *codec,
157                                          struct snd_pcm_substream *substream)
158 {
159         struct conexant_spec *spec = codec->spec;
160         return snd_hda_multi_out_dig_close(codec, &spec->multiout);
161 }
162
163 static int conexant_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
164                                          struct hda_codec *codec,
165                                          unsigned int stream_tag,
166                                          unsigned int format,
167                                          struct snd_pcm_substream *substream)
168 {
169         struct conexant_spec *spec = codec->spec;
170         return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
171                                              stream_tag,
172                                              format, substream);
173 }
174
175 /*
176  * Analog capture
177  */
178 static int conexant_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
179                                       struct hda_codec *codec,
180                                       unsigned int stream_tag,
181                                       unsigned int format,
182                                       struct snd_pcm_substream *substream)
183 {
184         struct conexant_spec *spec = codec->spec;
185         snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
186                                    stream_tag, 0, format);
187         return 0;
188 }
189
190 static int conexant_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
191                                       struct hda_codec *codec,
192                                       struct snd_pcm_substream *substream)
193 {
194         struct conexant_spec *spec = codec->spec;
195         snd_hda_codec_cleanup_stream(codec, spec->adc_nids[substream->number]);
196         return 0;
197 }
198
199
200
201 static struct hda_pcm_stream conexant_pcm_analog_playback = {
202         .substreams = 1,
203         .channels_min = 2,
204         .channels_max = 2,
205         .nid = 0, /* fill later */
206         .ops = {
207                 .open = conexant_playback_pcm_open,
208                 .prepare = conexant_playback_pcm_prepare,
209                 .cleanup = conexant_playback_pcm_cleanup
210         },
211 };
212
213 static struct hda_pcm_stream conexant_pcm_analog_capture = {
214         .substreams = 1,
215         .channels_min = 2,
216         .channels_max = 2,
217         .nid = 0, /* fill later */
218         .ops = {
219                 .prepare = conexant_capture_pcm_prepare,
220                 .cleanup = conexant_capture_pcm_cleanup
221         },
222 };
223
224
225 static struct hda_pcm_stream conexant_pcm_digital_playback = {
226         .substreams = 1,
227         .channels_min = 2,
228         .channels_max = 2,
229         .nid = 0, /* fill later */
230         .ops = {
231                 .open = conexant_dig_playback_pcm_open,
232                 .close = conexant_dig_playback_pcm_close,
233                 .prepare = conexant_dig_playback_pcm_prepare
234         },
235 };
236
237 static struct hda_pcm_stream conexant_pcm_digital_capture = {
238         .substreams = 1,
239         .channels_min = 2,
240         .channels_max = 2,
241         /* NID is set in alc_build_pcms */
242 };
243
244 static int cx5051_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
245                                       struct hda_codec *codec,
246                                       unsigned int stream_tag,
247                                       unsigned int format,
248                                       struct snd_pcm_substream *substream)
249 {
250         struct conexant_spec *spec = codec->spec;
251         spec->cur_adc = spec->adc_nids[spec->cur_adc_idx];
252         spec->cur_adc_stream_tag = stream_tag;
253         spec->cur_adc_format = format;
254         snd_hda_codec_setup_stream(codec, spec->cur_adc, stream_tag, 0, format);
255         return 0;
256 }
257
258 static int cx5051_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
259                                       struct hda_codec *codec,
260                                       struct snd_pcm_substream *substream)
261 {
262         struct conexant_spec *spec = codec->spec;
263         snd_hda_codec_cleanup_stream(codec, spec->cur_adc);
264         spec->cur_adc = 0;
265         return 0;
266 }
267
268 static struct hda_pcm_stream cx5051_pcm_analog_capture = {
269         .substreams = 1,
270         .channels_min = 2,
271         .channels_max = 2,
272         .nid = 0, /* fill later */
273         .ops = {
274                 .prepare = cx5051_capture_pcm_prepare,
275                 .cleanup = cx5051_capture_pcm_cleanup
276         },
277 };
278
279 static int conexant_build_pcms(struct hda_codec *codec)
280 {
281         struct conexant_spec *spec = codec->spec;
282         struct hda_pcm *info = spec->pcm_rec;
283
284         codec->num_pcms = 1;
285         codec->pcm_info = info;
286
287         info->name = "CONEXANT Analog";
288         info->stream[SNDRV_PCM_STREAM_PLAYBACK] = conexant_pcm_analog_playback;
289         info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max =
290                 spec->multiout.max_channels;
291         info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
292                 spec->multiout.dac_nids[0];
293         if (codec->vendor_id == 0x14f15051)
294                 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
295                         cx5051_pcm_analog_capture;
296         else
297                 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
298                         conexant_pcm_analog_capture;
299         info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = spec->num_adc_nids;
300         info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
301
302         if (spec->multiout.dig_out_nid) {
303                 info++;
304                 codec->num_pcms++;
305                 info->name = "Conexant Digital";
306                 info->pcm_type = HDA_PCM_TYPE_SPDIF;
307                 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
308                         conexant_pcm_digital_playback;
309                 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
310                         spec->multiout.dig_out_nid;
311                 if (spec->dig_in_nid) {
312                         info->stream[SNDRV_PCM_STREAM_CAPTURE] =
313                                 conexant_pcm_digital_capture;
314                         info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
315                                 spec->dig_in_nid;
316                 }
317         }
318
319         return 0;
320 }
321
322 static int conexant_mux_enum_info(struct snd_kcontrol *kcontrol,
323                                   struct snd_ctl_elem_info *uinfo)
324 {
325         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
326         struct conexant_spec *spec = codec->spec;
327
328         return snd_hda_input_mux_info(spec->input_mux, uinfo);
329 }
330
331 static int conexant_mux_enum_get(struct snd_kcontrol *kcontrol,
332                                  struct snd_ctl_elem_value *ucontrol)
333 {
334         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
335         struct conexant_spec *spec = codec->spec;
336         unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
337
338         ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
339         return 0;
340 }
341
342 static int conexant_mux_enum_put(struct snd_kcontrol *kcontrol,
343                                  struct snd_ctl_elem_value *ucontrol)
344 {
345         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
346         struct conexant_spec *spec = codec->spec;
347         unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
348
349         return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol,
350                                      spec->capsrc_nids[adc_idx],
351                                      &spec->cur_mux[adc_idx]);
352 }
353
354 #ifdef CONFIG_SND_HDA_INPUT_JACK
355 static void conexant_free_jack_priv(struct snd_jack *jack)
356 {
357         struct conexant_jack *jacks = jack->private_data;
358         jacks->nid = 0;
359         jacks->jack = NULL;
360 }
361
362 static int conexant_add_jack(struct hda_codec *codec,
363                 hda_nid_t nid, int type)
364 {
365         struct conexant_spec *spec;
366         struct conexant_jack *jack;
367         const char *name;
368         int err;
369
370         spec = codec->spec;
371         snd_array_init(&spec->jacks, sizeof(*jack), 32);
372         jack = snd_array_new(&spec->jacks);
373         name = (type == SND_JACK_HEADPHONE) ? "Headphone" : "Mic" ;
374
375         if (!jack)
376                 return -ENOMEM;
377
378         jack->nid = nid;
379         jack->type = type;
380
381         err = snd_jack_new(codec->bus->card, name, type, &jack->jack);
382         if (err < 0)
383                 return err;
384         jack->jack->private_data = jack;
385         jack->jack->private_free = conexant_free_jack_priv;
386         return 0;
387 }
388
389 static void conexant_report_jack(struct hda_codec *codec, hda_nid_t nid)
390 {
391         struct conexant_spec *spec = codec->spec;
392         struct conexant_jack *jacks = spec->jacks.list;
393
394         if (jacks) {
395                 int i;
396                 for (i = 0; i < spec->jacks.used; i++) {
397                         if (jacks->nid == nid) {
398                                 unsigned int present;
399                                 present = snd_hda_codec_read(codec, nid, 0,
400                                                 AC_VERB_GET_PIN_SENSE, 0) &
401                                         AC_PINSENSE_PRESENCE;
402
403                                 present = (present) ? jacks->type : 0 ;
404
405                                 snd_jack_report(jacks->jack,
406                                                 present);
407                         }
408                         jacks++;
409                 }
410         }
411 }
412
413 static int conexant_init_jacks(struct hda_codec *codec)
414 {
415         struct conexant_spec *spec = codec->spec;
416         int i;
417
418         for (i = 0; i < spec->num_init_verbs; i++) {
419                 const struct hda_verb *hv;
420
421                 hv = spec->init_verbs[i];
422                 while (hv->nid) {
423                         int err = 0;
424                         switch (hv->param ^ AC_USRSP_EN) {
425                         case CONEXANT_HP_EVENT:
426                                 err = conexant_add_jack(codec, hv->nid,
427                                                 SND_JACK_HEADPHONE);
428                                 conexant_report_jack(codec, hv->nid);
429                                 break;
430                         case CXT5051_PORTC_EVENT:
431                         case CONEXANT_MIC_EVENT:
432                                 err = conexant_add_jack(codec, hv->nid,
433                                                 SND_JACK_MICROPHONE);
434                                 conexant_report_jack(codec, hv->nid);
435                                 break;
436                         }
437                         if (err < 0)
438                                 return err;
439                         ++hv;
440                 }
441         }
442         return 0;
443
444 }
445 #else
446 static inline void conexant_report_jack(struct hda_codec *codec, hda_nid_t nid)
447 {
448 }
449
450 static inline int conexant_init_jacks(struct hda_codec *codec)
451 {
452         return 0;
453 }
454 #endif
455
456 static int conexant_init(struct hda_codec *codec)
457 {
458         struct conexant_spec *spec = codec->spec;
459         int i;
460
461         for (i = 0; i < spec->num_init_verbs; i++)
462                 snd_hda_sequence_write(codec, spec->init_verbs[i]);
463         return 0;
464 }
465
466 static void conexant_free(struct hda_codec *codec)
467 {
468 #ifdef CONFIG_SND_HDA_INPUT_JACK
469         struct conexant_spec *spec = codec->spec;
470         if (spec->jacks.list) {
471                 struct conexant_jack *jacks = spec->jacks.list;
472                 int i;
473                 for (i = 0; i < spec->jacks.used; i++, jacks++) {
474                         if (jacks->jack)
475                                 snd_device_free(codec->bus->card, jacks->jack);
476                 }
477                 snd_array_free(&spec->jacks);
478         }
479 #endif
480         kfree(codec->spec);
481 }
482
483 static struct snd_kcontrol_new cxt_capture_mixers[] = {
484         {
485                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
486                 .name = "Capture Source",
487                 .info = conexant_mux_enum_info,
488                 .get = conexant_mux_enum_get,
489                 .put = conexant_mux_enum_put
490         },
491         {}
492 };
493
494 static const char *slave_vols[] = {
495         "Headphone Playback Volume",
496         "Speaker Playback Volume",
497         NULL
498 };
499
500 static const char *slave_sws[] = {
501         "Headphone Playback Switch",
502         "Speaker Playback Switch",
503         NULL
504 };
505
506 static int conexant_build_controls(struct hda_codec *codec)
507 {
508         struct conexant_spec *spec = codec->spec;
509         unsigned int i;
510         int err;
511
512         for (i = 0; i < spec->num_mixers; i++) {
513                 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
514                 if (err < 0)
515                         return err;
516         }
517         if (spec->multiout.dig_out_nid) {
518                 err = snd_hda_create_spdif_out_ctls(codec,
519                                                     spec->multiout.dig_out_nid);
520                 if (err < 0)
521                         return err;
522                 err = snd_hda_create_spdif_share_sw(codec,
523                                                     &spec->multiout);
524                 if (err < 0)
525                         return err;
526                 spec->multiout.share_spdif = 1;
527         } 
528         if (spec->dig_in_nid) {
529                 err = snd_hda_create_spdif_in_ctls(codec,spec->dig_in_nid);
530                 if (err < 0)
531                         return err;
532         }
533
534         /* if we have no master control, let's create it */
535         if (spec->vmaster_nid &&
536             !snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
537                 unsigned int vmaster_tlv[4];
538                 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
539                                         HDA_OUTPUT, vmaster_tlv);
540                 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
541                                           vmaster_tlv, slave_vols);
542                 if (err < 0)
543                         return err;
544         }
545         if (spec->vmaster_nid &&
546             !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
547                 err = snd_hda_add_vmaster(codec, "Master Playback Switch",
548                                           NULL, slave_sws);
549                 if (err < 0)
550                         return err;
551         }
552
553         if (spec->input_mux) {
554                 err = snd_hda_add_new_ctls(codec, cxt_capture_mixers);
555                 if (err < 0)
556                         return err;
557         }
558
559         return 0;
560 }
561
562 static struct hda_codec_ops conexant_patch_ops = {
563         .build_controls = conexant_build_controls,
564         .build_pcms = conexant_build_pcms,
565         .init = conexant_init,
566         .free = conexant_free,
567 };
568
569 /*
570  * EAPD control
571  * the private value = nid | (invert << 8)
572  */
573
574 #define cxt_eapd_info           snd_ctl_boolean_mono_info
575
576 static int cxt_eapd_get(struct snd_kcontrol *kcontrol,
577                              struct snd_ctl_elem_value *ucontrol)
578 {
579         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
580         struct conexant_spec *spec = codec->spec;
581         int invert = (kcontrol->private_value >> 8) & 1;
582         if (invert)
583                 ucontrol->value.integer.value[0] = !spec->cur_eapd;
584         else
585                 ucontrol->value.integer.value[0] = spec->cur_eapd;
586         return 0;
587
588 }
589
590 static int cxt_eapd_put(struct snd_kcontrol *kcontrol,
591                              struct snd_ctl_elem_value *ucontrol)
592 {
593         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
594         struct conexant_spec *spec = codec->spec;
595         int invert = (kcontrol->private_value >> 8) & 1;
596         hda_nid_t nid = kcontrol->private_value & 0xff;
597         unsigned int eapd;
598
599         eapd = !!ucontrol->value.integer.value[0];
600         if (invert)
601                 eapd = !eapd;
602         if (eapd == spec->cur_eapd)
603                 return 0;
604         
605         spec->cur_eapd = eapd;
606         snd_hda_codec_write_cache(codec, nid,
607                                   0, AC_VERB_SET_EAPD_BTLENABLE,
608                                   eapd ? 0x02 : 0x00);
609         return 1;
610 }
611
612 /* controls for test mode */
613 #ifdef CONFIG_SND_DEBUG
614
615 #define CXT_EAPD_SWITCH(xname, nid, mask) \
616         { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
617           .info = cxt_eapd_info, \
618           .get = cxt_eapd_get, \
619           .put = cxt_eapd_put, \
620           .private_value = nid | (mask<<16) }
621
622
623
624 static int conexant_ch_mode_info(struct snd_kcontrol *kcontrol,
625                                  struct snd_ctl_elem_info *uinfo)
626 {
627         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
628         struct conexant_spec *spec = codec->spec;
629         return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
630                                     spec->num_channel_mode);
631 }
632
633 static int conexant_ch_mode_get(struct snd_kcontrol *kcontrol,
634                                 struct snd_ctl_elem_value *ucontrol)
635 {
636         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
637         struct conexant_spec *spec = codec->spec;
638         return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
639                                    spec->num_channel_mode,
640                                    spec->multiout.max_channels);
641 }
642
643 static int conexant_ch_mode_put(struct snd_kcontrol *kcontrol,
644                                 struct snd_ctl_elem_value *ucontrol)
645 {
646         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
647         struct conexant_spec *spec = codec->spec;
648         int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
649                                       spec->num_channel_mode,
650                                       &spec->multiout.max_channels);
651         if (err >= 0 && spec->need_dac_fix)
652                 spec->multiout.num_dacs = spec->multiout.max_channels / 2;
653         return err;
654 }
655
656 #define CXT_PIN_MODE(xname, nid, dir) \
657         { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
658           .info = conexant_ch_mode_info, \
659           .get = conexant_ch_mode_get, \
660           .put = conexant_ch_mode_put, \
661           .private_value = nid | (dir<<16) }
662
663 #endif /* CONFIG_SND_DEBUG */
664
665 /* Conexant 5045 specific */
666
667 static hda_nid_t cxt5045_dac_nids[1] = { 0x19 };
668 static hda_nid_t cxt5045_adc_nids[1] = { 0x1a };
669 static hda_nid_t cxt5045_capsrc_nids[1] = { 0x1a };
670 #define CXT5045_SPDIF_OUT       0x18
671
672 static struct hda_channel_mode cxt5045_modes[1] = {
673         { 2, NULL },
674 };
675
676 static struct hda_input_mux cxt5045_capture_source = {
677         .num_items = 2,
678         .items = {
679                 { "IntMic", 0x1 },
680                 { "ExtMic", 0x2 },
681         }
682 };
683
684 static struct hda_input_mux cxt5045_capture_source_benq = {
685         .num_items = 5,
686         .items = {
687                 { "IntMic", 0x1 },
688                 { "ExtMic", 0x2 },
689                 { "LineIn", 0x3 },
690                 { "CD",     0x4 },
691                 { "Mixer",  0x0 },
692         }
693 };
694
695 static struct hda_input_mux cxt5045_capture_source_hp530 = {
696         .num_items = 2,
697         .items = {
698                 { "ExtMic", 0x1 },
699                 { "IntMic", 0x2 },
700         }
701 };
702
703 /* turn on/off EAPD (+ mute HP) as a master switch */
704 static int cxt5045_hp_master_sw_put(struct snd_kcontrol *kcontrol,
705                                     struct snd_ctl_elem_value *ucontrol)
706 {
707         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
708         struct conexant_spec *spec = codec->spec;
709         unsigned int bits;
710
711         if (!cxt_eapd_put(kcontrol, ucontrol))
712                 return 0;
713
714         /* toggle internal speakers mute depending of presence of
715          * the headphone jack
716          */
717         bits = (!spec->hp_present && spec->cur_eapd) ? 0 : HDA_AMP_MUTE;
718         snd_hda_codec_amp_stereo(codec, 0x10, HDA_OUTPUT, 0,
719                                  HDA_AMP_MUTE, bits);
720
721         bits = spec->cur_eapd ? 0 : HDA_AMP_MUTE;
722         snd_hda_codec_amp_stereo(codec, 0x11, HDA_OUTPUT, 0,
723                                  HDA_AMP_MUTE, bits);
724         return 1;
725 }
726
727 /* bind volumes of both NID 0x10 and 0x11 */
728 static struct hda_bind_ctls cxt5045_hp_bind_master_vol = {
729         .ops = &snd_hda_bind_vol,
730         .values = {
731                 HDA_COMPOSE_AMP_VAL(0x10, 3, 0, HDA_OUTPUT),
732                 HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT),
733                 0
734         },
735 };
736
737 /* toggle input of built-in and mic jack appropriately */
738 static void cxt5045_hp_automic(struct hda_codec *codec)
739 {
740         static struct hda_verb mic_jack_on[] = {
741                 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
742                 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
743                 {}
744         };
745         static struct hda_verb mic_jack_off[] = {
746                 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
747                 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
748                 {}
749         };
750         unsigned int present;
751
752         present = snd_hda_codec_read(codec, 0x12, 0,
753                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
754         if (present)
755                 snd_hda_sequence_write(codec, mic_jack_on);
756         else
757                 snd_hda_sequence_write(codec, mic_jack_off);
758 }
759
760
761 /* mute internal speaker if HP is plugged */
762 static void cxt5045_hp_automute(struct hda_codec *codec)
763 {
764         struct conexant_spec *spec = codec->spec;
765         unsigned int bits;
766
767         spec->hp_present = snd_hda_codec_read(codec, 0x11, 0,
768                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
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                 /* HP laptop has a really bad sound over 0dB on NID 0x17.
1178                  * Fix max PCM level to 0 dB
1179                  * (originall it has 0x2b steps with 0dB offset 0x14)
1180                  */
1181                 snd_hda_override_amp_caps(codec, 0x17, HDA_INPUT,
1182                                           (0x14 << AC_AMPCAP_OFFSET_SHIFT) |
1183                                           (0x14 << AC_AMPCAP_NUM_STEPS_SHIFT) |
1184                                           (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) |
1185                                           (1 << AC_AMPCAP_MUTE_SHIFT));
1186                 break;
1187         }
1188
1189         return 0;
1190 }
1191
1192
1193 /* Conexant 5047 specific */
1194 #define CXT5047_SPDIF_OUT       0x11
1195
1196 static hda_nid_t cxt5047_dac_nids[1] = { 0x10 }; /* 0x1c */
1197 static hda_nid_t cxt5047_adc_nids[1] = { 0x12 };
1198 static hda_nid_t cxt5047_capsrc_nids[1] = { 0x1a };
1199
1200 static struct hda_channel_mode cxt5047_modes[1] = {
1201         { 2, NULL },
1202 };
1203
1204 static struct hda_input_mux cxt5047_toshiba_capture_source = {
1205         .num_items = 2,
1206         .items = {
1207                 { "ExtMic", 0x2 },
1208                 { "Line-In", 0x1 },
1209         }
1210 };
1211
1212 /* turn on/off EAPD (+ mute HP) as a master switch */
1213 static int cxt5047_hp_master_sw_put(struct snd_kcontrol *kcontrol,
1214                                     struct snd_ctl_elem_value *ucontrol)
1215 {
1216         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1217         struct conexant_spec *spec = codec->spec;
1218         unsigned int bits;
1219
1220         if (!cxt_eapd_put(kcontrol, ucontrol))
1221                 return 0;
1222
1223         /* toggle internal speakers mute depending of presence of
1224          * the headphone jack
1225          */
1226         bits = (!spec->hp_present && spec->cur_eapd) ? 0 : HDA_AMP_MUTE;
1227         /* NOTE: Conexat codec needs the index for *OUTPUT* amp of
1228          * pin widgets unlike other codecs.  In this case, we need to
1229          * set index 0x01 for the volume from the mixer amp 0x19.
1230          */
1231         snd_hda_codec_amp_stereo(codec, 0x1d, HDA_OUTPUT, 0x01,
1232                                  HDA_AMP_MUTE, bits);
1233         bits = spec->cur_eapd ? 0 : HDA_AMP_MUTE;
1234         snd_hda_codec_amp_stereo(codec, 0x13, HDA_OUTPUT, 0,
1235                                  HDA_AMP_MUTE, bits);
1236         return 1;
1237 }
1238
1239 /* mute internal speaker if HP is plugged */
1240 static void cxt5047_hp_automute(struct hda_codec *codec)
1241 {
1242         struct conexant_spec *spec = codec->spec;
1243         unsigned int bits;
1244
1245         spec->hp_present = snd_hda_codec_read(codec, 0x13, 0,
1246                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
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_codec_read(codec, 0x15, 0,
1270                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1271         if (present)
1272                 snd_hda_sequence_write(codec, mic_jack_on);
1273         else
1274                 snd_hda_sequence_write(codec, mic_jack_off);
1275 }
1276
1277 /* unsolicited event for HP jack sensing */
1278 static void cxt5047_hp_unsol_event(struct hda_codec *codec,
1279                                   unsigned int res)
1280 {
1281         switch (res >> 26) {
1282         case CONEXANT_HP_EVENT:
1283                 cxt5047_hp_automute(codec);
1284                 break;
1285         case CONEXANT_MIC_EVENT:
1286                 cxt5047_hp_automic(codec);
1287                 break;
1288         }
1289 }
1290
1291 static struct snd_kcontrol_new cxt5047_base_mixers[] = {
1292         HDA_CODEC_VOLUME("Mic Playback Volume", 0x19, 0x02, HDA_INPUT),
1293         HDA_CODEC_MUTE("Mic Playback Switch", 0x19, 0x02, HDA_INPUT),
1294         HDA_CODEC_VOLUME("Mic Boost", 0x1a, 0x0, HDA_OUTPUT),
1295         HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x03, HDA_INPUT),
1296         HDA_CODEC_MUTE("Capture Switch", 0x12, 0x03, HDA_INPUT),
1297         HDA_CODEC_VOLUME("PCM Volume", 0x10, 0x00, HDA_OUTPUT),
1298         HDA_CODEC_MUTE("PCM Switch", 0x10, 0x00, HDA_OUTPUT),
1299         {
1300                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1301                 .name = "Master Playback Switch",
1302                 .info = cxt_eapd_info,
1303                 .get = cxt_eapd_get,
1304                 .put = cxt5047_hp_master_sw_put,
1305                 .private_value = 0x13,
1306         },
1307
1308         {}
1309 };
1310
1311 static struct snd_kcontrol_new cxt5047_hp_spk_mixers[] = {
1312         /* See the note in cxt5047_hp_master_sw_put */
1313         HDA_CODEC_VOLUME("Speaker Playback Volume", 0x1d, 0x01, HDA_OUTPUT),
1314         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x13, 0x00, HDA_OUTPUT),
1315         {}
1316 };
1317
1318 static struct snd_kcontrol_new cxt5047_hp_only_mixers[] = {
1319         HDA_CODEC_VOLUME("Master Playback Volume", 0x13, 0x00, HDA_OUTPUT),
1320         { } /* end */
1321 };
1322
1323 static struct hda_verb cxt5047_init_verbs[] = {
1324         /* Line in, Mic, Built-in Mic */
1325         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1326         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_50 },
1327         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_50 },
1328         /* HP, Speaker  */
1329         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
1330         {0x13, AC_VERB_SET_CONNECT_SEL, 0x0}, /* mixer(0x19) */
1331         {0x1d, AC_VERB_SET_CONNECT_SEL, 0x1}, /* mixer(0x19) */
1332         /* Record selector: Mic */
1333         {0x12, AC_VERB_SET_CONNECT_SEL,0x03},
1334         {0x19, AC_VERB_SET_AMP_GAIN_MUTE,
1335          AC_AMP_SET_INPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x17},
1336         {0x1A, AC_VERB_SET_CONNECT_SEL,0x02},
1337         {0x1A, AC_VERB_SET_AMP_GAIN_MUTE,
1338          AC_AMP_SET_OUTPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x00},
1339         {0x1A, AC_VERB_SET_AMP_GAIN_MUTE,
1340          AC_AMP_SET_OUTPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x03},
1341         /* SPDIF route: PCM */
1342         { 0x18, AC_VERB_SET_CONNECT_SEL, 0x0 },
1343         /* Enable unsolicited events */
1344         {0x13, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT},
1345         {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT},
1346         { } /* end */
1347 };
1348
1349 /* configuration for Toshiba Laptops */
1350 static struct hda_verb cxt5047_toshiba_init_verbs[] = {
1351         {0x13, AC_VERB_SET_EAPD_BTLENABLE, 0x0}, /* default off */
1352         {}
1353 };
1354
1355 /* Test configuration for debugging, modelled after the ALC260 test
1356  * configuration.
1357  */
1358 #ifdef CONFIG_SND_DEBUG
1359 static struct hda_input_mux cxt5047_test_capture_source = {
1360         .num_items = 4,
1361         .items = {
1362                 { "LINE1 pin", 0x0 },
1363                 { "MIC1 pin", 0x1 },
1364                 { "MIC2 pin", 0x2 },
1365                 { "CD pin", 0x3 },
1366         },
1367 };
1368
1369 static struct snd_kcontrol_new cxt5047_test_mixer[] = {
1370
1371         /* Output only controls */
1372         HDA_CODEC_VOLUME("OutAmp-1 Volume", 0x10, 0x0, HDA_OUTPUT),
1373         HDA_CODEC_MUTE("OutAmp-1 Switch", 0x10,0x0, HDA_OUTPUT),
1374         HDA_CODEC_VOLUME("OutAmp-2 Volume", 0x1c, 0x0, HDA_OUTPUT),
1375         HDA_CODEC_MUTE("OutAmp-2 Switch", 0x1c, 0x0, HDA_OUTPUT),
1376         HDA_CODEC_VOLUME("Speaker Playback Volume", 0x1d, 0x0, HDA_OUTPUT),
1377         HDA_CODEC_MUTE("Speaker Playback Switch", 0x1d, 0x0, HDA_OUTPUT),
1378         HDA_CODEC_VOLUME("HeadPhone Playback Volume", 0x13, 0x0, HDA_OUTPUT),
1379         HDA_CODEC_MUTE("HeadPhone Playback Switch", 0x13, 0x0, HDA_OUTPUT),
1380         HDA_CODEC_VOLUME("Line1-Out Playback Volume", 0x14, 0x0, HDA_OUTPUT),
1381         HDA_CODEC_MUTE("Line1-Out Playback Switch", 0x14, 0x0, HDA_OUTPUT),
1382         HDA_CODEC_VOLUME("Line2-Out Playback Volume", 0x15, 0x0, HDA_OUTPUT),
1383         HDA_CODEC_MUTE("Line2-Out Playback Switch", 0x15, 0x0, HDA_OUTPUT),
1384
1385         /* Modes for retasking pin widgets */
1386         CXT_PIN_MODE("LINE1 pin mode", 0x14, CXT_PIN_DIR_INOUT),
1387         CXT_PIN_MODE("MIC1 pin mode", 0x15, CXT_PIN_DIR_INOUT),
1388
1389         /* EAPD Switch Control */
1390         CXT_EAPD_SWITCH("External Amplifier", 0x13, 0x0),
1391
1392         /* Loopback mixer controls */
1393         HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x12, 0x01, HDA_INPUT),
1394         HDA_CODEC_MUTE("MIC1 Playback Switch", 0x12, 0x01, HDA_INPUT),
1395         HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x12, 0x02, HDA_INPUT),
1396         HDA_CODEC_MUTE("MIC2 Playback Switch", 0x12, 0x02, HDA_INPUT),
1397         HDA_CODEC_VOLUME("LINE Playback Volume", 0x12, 0x0, HDA_INPUT),
1398         HDA_CODEC_MUTE("LINE Playback Switch", 0x12, 0x0, HDA_INPUT),
1399         HDA_CODEC_VOLUME("CD Playback Volume", 0x12, 0x04, HDA_INPUT),
1400         HDA_CODEC_MUTE("CD Playback Switch", 0x12, 0x04, HDA_INPUT),
1401
1402         HDA_CODEC_VOLUME("Capture-1 Volume", 0x19, 0x0, HDA_INPUT),
1403         HDA_CODEC_MUTE("Capture-1 Switch", 0x19, 0x0, HDA_INPUT),
1404         HDA_CODEC_VOLUME("Capture-2 Volume", 0x19, 0x1, HDA_INPUT),
1405         HDA_CODEC_MUTE("Capture-2 Switch", 0x19, 0x1, HDA_INPUT),
1406         HDA_CODEC_VOLUME("Capture-3 Volume", 0x19, 0x2, HDA_INPUT),
1407         HDA_CODEC_MUTE("Capture-3 Switch", 0x19, 0x2, HDA_INPUT),
1408         HDA_CODEC_VOLUME("Capture-4 Volume", 0x19, 0x3, HDA_INPUT),
1409         HDA_CODEC_MUTE("Capture-4 Switch", 0x19, 0x3, HDA_INPUT),
1410         {
1411                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1412                 .name = "Input Source",
1413                 .info = conexant_mux_enum_info,
1414                 .get = conexant_mux_enum_get,
1415                 .put = conexant_mux_enum_put,
1416         },
1417         HDA_CODEC_VOLUME("Input-1 Volume", 0x1a, 0x0, HDA_INPUT),
1418         HDA_CODEC_MUTE("Input-1 Switch", 0x1a, 0x0, HDA_INPUT),
1419         HDA_CODEC_VOLUME("Input-2 Volume", 0x1a, 0x1, HDA_INPUT),
1420         HDA_CODEC_MUTE("Input-2 Switch", 0x1a, 0x1, HDA_INPUT),
1421         HDA_CODEC_VOLUME("Input-3 Volume", 0x1a, 0x2, HDA_INPUT),
1422         HDA_CODEC_MUTE("Input-3 Switch", 0x1a, 0x2, HDA_INPUT),
1423         HDA_CODEC_VOLUME("Input-4 Volume", 0x1a, 0x3, HDA_INPUT),
1424         HDA_CODEC_MUTE("Input-4 Switch", 0x1a, 0x3, HDA_INPUT),
1425         HDA_CODEC_VOLUME("Input-5 Volume", 0x1a, 0x4, HDA_INPUT),
1426         HDA_CODEC_MUTE("Input-5 Switch", 0x1a, 0x4, HDA_INPUT),
1427
1428         { } /* end */
1429 };
1430
1431 static struct hda_verb cxt5047_test_init_verbs[] = {
1432         /* Enable retasking pins as output, initially without power amp */
1433         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1434         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1435         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1436
1437         /* Disable digital (SPDIF) pins initially, but users can enable
1438          * them via a mixer switch.  In the case of SPDIF-out, this initverb
1439          * payload also sets the generation to 0, output to be in "consumer"
1440          * PCM format, copyright asserted, no pre-emphasis and no validity
1441          * control.
1442          */
1443         {0x18, AC_VERB_SET_DIGI_CONVERT_1, 0},
1444
1445         /* Ensure mic1, mic2, line1 pin widgets take input from the 
1446          * OUT1 sum bus when acting as an output.
1447          */
1448         {0x1a, AC_VERB_SET_CONNECT_SEL, 0},
1449         {0x1b, AC_VERB_SET_CONNECT_SEL, 0},
1450
1451         /* Start with output sum widgets muted and their output gains at min */
1452         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1453         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1454
1455         /* Unmute retasking pin widget output buffers since the default
1456          * state appears to be output.  As the pin mode is changed by the
1457          * user the pin mode control will take care of enabling the pin's
1458          * input/output buffers as needed.
1459          */
1460         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1461         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1462         {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1463
1464         /* Mute capture amp left and right */
1465         {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1466
1467         /* Set ADC connection select to match default mixer setting (mic1
1468          * pin)
1469          */
1470         {0x12, AC_VERB_SET_CONNECT_SEL, 0x00},
1471
1472         /* Mute all inputs to mixer widget (even unconnected ones) */
1473         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
1474         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
1475         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
1476         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
1477         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
1478         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
1479         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
1480         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
1481
1482         { }
1483 };
1484 #endif
1485
1486
1487 /* initialize jack-sensing, too */
1488 static int cxt5047_hp_init(struct hda_codec *codec)
1489 {
1490         conexant_init(codec);
1491         cxt5047_hp_automute(codec);
1492         return 0;
1493 }
1494
1495
1496 enum {
1497         CXT5047_LAPTOP,         /* Laptops w/o EAPD support */
1498         CXT5047_LAPTOP_HP,      /* Some HP laptops */
1499         CXT5047_LAPTOP_EAPD,    /* Laptops with EAPD support */
1500 #ifdef CONFIG_SND_DEBUG
1501         CXT5047_TEST,
1502 #endif
1503         CXT5047_MODELS
1504 };
1505
1506 static const char *cxt5047_models[CXT5047_MODELS] = {
1507         [CXT5047_LAPTOP]        = "laptop",
1508         [CXT5047_LAPTOP_HP]     = "laptop-hp",
1509         [CXT5047_LAPTOP_EAPD]   = "laptop-eapd",
1510 #ifdef CONFIG_SND_DEBUG
1511         [CXT5047_TEST]          = "test",
1512 #endif
1513 };
1514
1515 static struct snd_pci_quirk cxt5047_cfg_tbl[] = {
1516         SND_PCI_QUIRK(0x103c, 0x30a5, "HP DV5200T/DV8000T", CXT5047_LAPTOP_HP),
1517         SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3000, "HP DV Series",
1518                            CXT5047_LAPTOP),
1519         SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba P100", CXT5047_LAPTOP_EAPD),
1520         {}
1521 };
1522
1523 static int patch_cxt5047(struct hda_codec *codec)
1524 {
1525         struct conexant_spec *spec;
1526         int board_config;
1527
1528         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1529         if (!spec)
1530                 return -ENOMEM;
1531         codec->spec = spec;
1532         codec->pin_amp_workaround = 1;
1533
1534         spec->multiout.max_channels = 2;
1535         spec->multiout.num_dacs = ARRAY_SIZE(cxt5047_dac_nids);
1536         spec->multiout.dac_nids = cxt5047_dac_nids;
1537         spec->multiout.dig_out_nid = CXT5047_SPDIF_OUT;
1538         spec->num_adc_nids = 1;
1539         spec->adc_nids = cxt5047_adc_nids;
1540         spec->capsrc_nids = cxt5047_capsrc_nids;
1541         spec->num_mixers = 1;
1542         spec->mixers[0] = cxt5047_base_mixers;
1543         spec->num_init_verbs = 1;
1544         spec->init_verbs[0] = cxt5047_init_verbs;
1545         spec->spdif_route = 0;
1546         spec->num_channel_mode = ARRAY_SIZE(cxt5047_modes),
1547         spec->channel_mode = cxt5047_modes,
1548
1549         codec->patch_ops = conexant_patch_ops;
1550
1551         board_config = snd_hda_check_board_config(codec, CXT5047_MODELS,
1552                                                   cxt5047_models,
1553                                                   cxt5047_cfg_tbl);
1554         switch (board_config) {
1555         case CXT5047_LAPTOP:
1556                 spec->num_mixers = 2;
1557                 spec->mixers[1] = cxt5047_hp_spk_mixers;
1558                 codec->patch_ops.unsol_event = cxt5047_hp_unsol_event;
1559                 break;
1560         case CXT5047_LAPTOP_HP:
1561                 spec->num_mixers = 2;
1562                 spec->mixers[1] = cxt5047_hp_only_mixers;
1563                 codec->patch_ops.unsol_event = cxt5047_hp_unsol_event;
1564                 codec->patch_ops.init = cxt5047_hp_init;
1565                 break;
1566         case CXT5047_LAPTOP_EAPD:
1567                 spec->input_mux = &cxt5047_toshiba_capture_source;
1568                 spec->num_mixers = 2;
1569                 spec->mixers[1] = cxt5047_hp_spk_mixers;
1570                 spec->num_init_verbs = 2;
1571                 spec->init_verbs[1] = cxt5047_toshiba_init_verbs;
1572                 codec->patch_ops.unsol_event = cxt5047_hp_unsol_event;
1573                 break;
1574 #ifdef CONFIG_SND_DEBUG
1575         case CXT5047_TEST:
1576                 spec->input_mux = &cxt5047_test_capture_source;
1577                 spec->mixers[0] = cxt5047_test_mixer;
1578                 spec->init_verbs[0] = cxt5047_test_init_verbs;
1579                 codec->patch_ops.unsol_event = cxt5047_hp_unsol_event;
1580 #endif  
1581         }
1582         spec->vmaster_nid = 0x13;
1583         return 0;
1584 }
1585
1586 /* Conexant 5051 specific */
1587 static hda_nid_t cxt5051_dac_nids[1] = { 0x10 };
1588 static hda_nid_t cxt5051_adc_nids[2] = { 0x14, 0x15 };
1589
1590 static struct hda_channel_mode cxt5051_modes[1] = {
1591         { 2, NULL },
1592 };
1593
1594 static void cxt5051_update_speaker(struct hda_codec *codec)
1595 {
1596         struct conexant_spec *spec = codec->spec;
1597         unsigned int pinctl;
1598         pinctl = (!spec->hp_present && spec->cur_eapd) ? PIN_OUT : 0;
1599         snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
1600                             pinctl);
1601 }
1602
1603 /* turn on/off EAPD (+ mute HP) as a master switch */
1604 static int cxt5051_hp_master_sw_put(struct snd_kcontrol *kcontrol,
1605                                     struct snd_ctl_elem_value *ucontrol)
1606 {
1607         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1608
1609         if (!cxt_eapd_put(kcontrol, ucontrol))
1610                 return 0;
1611         cxt5051_update_speaker(codec);
1612         return 1;
1613 }
1614
1615 /* toggle input of built-in and mic jack appropriately */
1616 static void cxt5051_portb_automic(struct hda_codec *codec)
1617 {
1618         struct conexant_spec *spec = codec->spec;
1619         unsigned int present;
1620
1621         if (spec->no_auto_mic)
1622                 return;
1623         present = snd_hda_codec_read(codec, 0x17, 0,
1624                                      AC_VERB_GET_PIN_SENSE, 0) &
1625                 AC_PINSENSE_PRESENCE;
1626         snd_hda_codec_write(codec, 0x14, 0,
1627                             AC_VERB_SET_CONNECT_SEL,
1628                             present ? 0x01 : 0x00);
1629 }
1630
1631 /* switch the current ADC according to the jack state */
1632 static void cxt5051_portc_automic(struct hda_codec *codec)
1633 {
1634         struct conexant_spec *spec = codec->spec;
1635         unsigned int present;
1636         hda_nid_t new_adc;
1637
1638         if (spec->no_auto_mic)
1639                 return;
1640         present = snd_hda_codec_read(codec, 0x18, 0,
1641                                      AC_VERB_GET_PIN_SENSE, 0) &
1642                 AC_PINSENSE_PRESENCE;
1643         if (present)
1644                 spec->cur_adc_idx = 1;
1645         else
1646                 spec->cur_adc_idx = 0;
1647         new_adc = spec->adc_nids[spec->cur_adc_idx];
1648         if (spec->cur_adc && spec->cur_adc != new_adc) {
1649                 /* stream is running, let's swap the current ADC */
1650                 snd_hda_codec_cleanup_stream(codec, spec->cur_adc);
1651                 spec->cur_adc = new_adc;
1652                 snd_hda_codec_setup_stream(codec, new_adc,
1653                                            spec->cur_adc_stream_tag, 0,
1654                                            spec->cur_adc_format);
1655         }
1656 }
1657
1658 /* mute internal speaker if HP is plugged */
1659 static void cxt5051_hp_automute(struct hda_codec *codec)
1660 {
1661         struct conexant_spec *spec = codec->spec;
1662
1663         spec->hp_present = snd_hda_codec_read(codec, 0x16, 0,
1664                                      AC_VERB_GET_PIN_SENSE, 0) &
1665                 AC_PINSENSE_PRESENCE;
1666         cxt5051_update_speaker(codec);
1667 }
1668
1669 /* unsolicited event for HP jack sensing */
1670 static void cxt5051_hp_unsol_event(struct hda_codec *codec,
1671                                    unsigned int res)
1672 {
1673         int nid = (res & AC_UNSOL_RES_SUBTAG) >> 20;
1674         switch (res >> 26) {
1675         case CONEXANT_HP_EVENT:
1676                 cxt5051_hp_automute(codec);
1677                 break;
1678         case CXT5051_PORTB_EVENT:
1679                 cxt5051_portb_automic(codec);
1680                 break;
1681         case CXT5051_PORTC_EVENT:
1682                 cxt5051_portc_automic(codec);
1683                 break;
1684         }
1685         conexant_report_jack(codec, nid);
1686 }
1687
1688 static struct snd_kcontrol_new cxt5051_mixers[] = {
1689         HDA_CODEC_VOLUME("Internal Mic Volume", 0x14, 0x00, HDA_INPUT),
1690         HDA_CODEC_MUTE("Internal Mic Switch", 0x14, 0x00, HDA_INPUT),
1691         HDA_CODEC_VOLUME("External Mic Volume", 0x14, 0x01, HDA_INPUT),
1692         HDA_CODEC_MUTE("External Mic Switch", 0x14, 0x01, HDA_INPUT),
1693         HDA_CODEC_VOLUME("Docking Mic Volume", 0x15, 0x00, HDA_INPUT),
1694         HDA_CODEC_MUTE("Docking Mic Switch", 0x15, 0x00, HDA_INPUT),
1695         HDA_CODEC_VOLUME("Master Playback Volume", 0x10, 0x00, HDA_OUTPUT),
1696         {
1697                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1698                 .name = "Master Playback Switch",
1699                 .info = cxt_eapd_info,
1700                 .get = cxt_eapd_get,
1701                 .put = cxt5051_hp_master_sw_put,
1702                 .private_value = 0x1a,
1703         },
1704
1705         {}
1706 };
1707
1708 static struct snd_kcontrol_new cxt5051_hp_mixers[] = {
1709         HDA_CODEC_VOLUME("Internal Mic Volume", 0x14, 0x00, HDA_INPUT),
1710         HDA_CODEC_MUTE("Internal Mic Switch", 0x14, 0x00, HDA_INPUT),
1711         HDA_CODEC_VOLUME("External Mic Volume", 0x15, 0x00, HDA_INPUT),
1712         HDA_CODEC_MUTE("External Mic Switch", 0x15, 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_hp_dv6736_mixers[] = {
1727         HDA_CODEC_VOLUME("Mic Volume", 0x14, 0x00, HDA_INPUT),
1728         HDA_CODEC_MUTE("Mic Switch", 0x14, 0x00, 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 /* initialize jack-sensing, too */
1833 static int cxt5051_init(struct hda_codec *codec)
1834 {
1835         conexant_init(codec);
1836         conexant_init_jacks(codec);
1837         if (codec->patch_ops.unsol_event) {
1838                 cxt5051_hp_automute(codec);
1839                 cxt5051_portb_automic(codec);
1840                 cxt5051_portc_automic(codec);
1841         }
1842         return 0;
1843 }
1844
1845
1846 enum {
1847         CXT5051_LAPTOP,  /* Laptops w/ EAPD support */
1848         CXT5051_HP,     /* no docking */
1849         CXT5051_HP_DV6736,      /* HP without mic switch */
1850         CXT5051_LENOVO_X200,    /* Lenovo X200 laptop */
1851         CXT5051_MODELS
1852 };
1853
1854 static const char *cxt5051_models[CXT5051_MODELS] = {
1855         [CXT5051_LAPTOP]        = "laptop",
1856         [CXT5051_HP]            = "hp",
1857         [CXT5051_HP_DV6736]     = "hp-dv6736",
1858         [CXT5051_LENOVO_X200]   = "lenovo-x200",
1859 };
1860
1861 static struct snd_pci_quirk cxt5051_cfg_tbl[] = {
1862         SND_PCI_QUIRK(0x103c, 0x30cf, "HP DV6736", CXT5051_HP_DV6736),
1863         SND_PCI_QUIRK(0x103c, 0x360b, "Compaq Presario CQ60", CXT5051_HP),
1864         SND_PCI_QUIRK(0x14f1, 0x0101, "Conexant Reference board",
1865                       CXT5051_LAPTOP),
1866         SND_PCI_QUIRK(0x14f1, 0x5051, "HP Spartan 1.1", CXT5051_HP),
1867         SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo X200", CXT5051_LENOVO_X200),
1868         {}
1869 };
1870
1871 static int patch_cxt5051(struct hda_codec *codec)
1872 {
1873         struct conexant_spec *spec;
1874         int board_config;
1875
1876         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1877         if (!spec)
1878                 return -ENOMEM;
1879         codec->spec = spec;
1880         codec->pin_amp_workaround = 1;
1881
1882         codec->patch_ops = conexant_patch_ops;
1883         codec->patch_ops.init = cxt5051_init;
1884
1885         spec->multiout.max_channels = 2;
1886         spec->multiout.num_dacs = ARRAY_SIZE(cxt5051_dac_nids);
1887         spec->multiout.dac_nids = cxt5051_dac_nids;
1888         spec->multiout.dig_out_nid = CXT5051_SPDIF_OUT;
1889         spec->num_adc_nids = 1; /* not 2; via auto-mic switch */
1890         spec->adc_nids = cxt5051_adc_nids;
1891         spec->num_mixers = 1;
1892         spec->mixers[0] = cxt5051_mixers;
1893         spec->num_init_verbs = 1;
1894         spec->init_verbs[0] = cxt5051_init_verbs;
1895         spec->spdif_route = 0;
1896         spec->num_channel_mode = ARRAY_SIZE(cxt5051_modes);
1897         spec->channel_mode = cxt5051_modes;
1898         spec->cur_adc = 0;
1899         spec->cur_adc_idx = 0;
1900
1901         codec->patch_ops.unsol_event = cxt5051_hp_unsol_event;
1902
1903         board_config = snd_hda_check_board_config(codec, CXT5051_MODELS,
1904                                                   cxt5051_models,
1905                                                   cxt5051_cfg_tbl);
1906         switch (board_config) {
1907         case CXT5051_HP:
1908                 spec->mixers[0] = cxt5051_hp_mixers;
1909                 break;
1910         case CXT5051_HP_DV6736:
1911                 spec->init_verbs[0] = cxt5051_hp_dv6736_init_verbs;
1912                 spec->mixers[0] = cxt5051_hp_dv6736_mixers;
1913                 spec->no_auto_mic = 1;
1914                 break;
1915         case CXT5051_LENOVO_X200:
1916                 spec->init_verbs[0] = cxt5051_lenovo_x200_init_verbs;
1917                 break;
1918         }
1919
1920         return 0;
1921 }
1922
1923 /* Conexant 5066 specific */
1924
1925 static hda_nid_t cxt5066_dac_nids[1] = { 0x10 };
1926 static hda_nid_t cxt5066_adc_nids[3] = { 0x14, 0x15, 0x16 };
1927 static hda_nid_t cxt5066_capsrc_nids[1] = { 0x17 };
1928 #define CXT5066_SPDIF_OUT       0x21
1929
1930 static struct hda_channel_mode cxt5066_modes[1] = {
1931         { 2, NULL },
1932 };
1933
1934 static void cxt5066_update_speaker(struct hda_codec *codec)
1935 {
1936         struct conexant_spec *spec = codec->spec;
1937         unsigned int pinctl;
1938
1939         snd_printdd("CXT5066: update speaker, hp_present=%d\n",
1940                 spec->hp_present);
1941
1942         /* Port A (HP) */
1943         pinctl = ((spec->hp_present & 1) && spec->cur_eapd) ? PIN_HP : 0;
1944         snd_hda_codec_write(codec, 0x19, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
1945                         pinctl);
1946
1947         /* Port D (HP/LO) */
1948         pinctl = ((spec->hp_present & 2) && spec->cur_eapd)
1949                 ? spec->port_d_mode : 0;
1950         snd_hda_codec_write(codec, 0x1c, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
1951                         pinctl);
1952
1953         /* CLASS_D AMP */
1954         pinctl = (!spec->hp_present && spec->cur_eapd) ? PIN_OUT : 0;
1955         snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
1956                         pinctl);
1957
1958         if (spec->dell_automute) {
1959                 /* DELL AIO Port Rule: PortA > PortD > IntSpk */
1960                 pinctl = (!(spec->hp_present & 1) && spec->cur_eapd)
1961                         ? PIN_OUT : 0;
1962                 snd_hda_codec_write(codec, 0x1c, 0,
1963                         AC_VERB_SET_PIN_WIDGET_CONTROL, pinctl);
1964         }
1965 }
1966
1967 /* turn on/off EAPD (+ mute HP) as a master switch */
1968 static int cxt5066_hp_master_sw_put(struct snd_kcontrol *kcontrol,
1969                                     struct snd_ctl_elem_value *ucontrol)
1970 {
1971         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1972
1973         if (!cxt_eapd_put(kcontrol, ucontrol))
1974                 return 0;
1975
1976         cxt5066_update_speaker(codec);
1977         return 1;
1978 }
1979
1980 /* toggle input of built-in and mic jack appropriately */
1981 static void cxt5066_automic(struct hda_codec *codec)
1982 {
1983         static struct hda_verb ext_mic_present[] = {
1984                 /* enable external mic, port B */
1985                 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1986
1987                 /* switch to external mic input */
1988                 {0x17, AC_VERB_SET_CONNECT_SEL, 0},
1989
1990                 /* disable internal mic, port C */
1991                 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
1992                 {}
1993         };
1994         static struct hda_verb ext_mic_absent[] = {
1995                 /* enable internal mic, port C */
1996                 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1997
1998                 /* switch to internal mic input */
1999                 {0x17, AC_VERB_SET_CONNECT_SEL, 1},
2000
2001                 /* disable external mic, port B */
2002                 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2003                 {}
2004         };
2005         unsigned int present;
2006
2007         present = snd_hda_codec_read(codec, 0x1a, 0,
2008                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2009         if (present) {
2010                 snd_printdd("CXT5066: external microphone detected\n");
2011                 snd_hda_sequence_write(codec, ext_mic_present);
2012         } else {
2013                 snd_printdd("CXT5066: external microphone absent\n");
2014                 snd_hda_sequence_write(codec, ext_mic_absent);
2015         }
2016 }
2017
2018 /* mute internal speaker if HP is plugged */
2019 static void cxt5066_hp_automute(struct hda_codec *codec)
2020 {
2021         struct conexant_spec *spec = codec->spec;
2022         unsigned int portA, portD;
2023
2024         /* Port A */
2025         portA = snd_hda_codec_read(codec, 0x19, 0, AC_VERB_GET_PIN_SENSE, 0)
2026                 & AC_PINSENSE_PRESENCE;
2027
2028         /* Port D */
2029         portD = (snd_hda_codec_read(codec, 0x1c, 0, AC_VERB_GET_PIN_SENSE, 0)
2030                 & AC_PINSENSE_PRESENCE) << 1;
2031
2032         spec->hp_present = !!(portA | portD);
2033         snd_printdd("CXT5066: hp automute portA=%x portD=%x present=%d\n",
2034                 portA, portD, spec->hp_present);
2035         cxt5066_update_speaker(codec);
2036 }
2037
2038 /* unsolicited event for jack sensing */
2039 static void cxt5066_unsol_event(struct hda_codec *codec, unsigned int res)
2040 {
2041         snd_printdd("CXT5066: unsol event %x (%x)\n", res, res >> 26);
2042         switch (res >> 26) {
2043         case CONEXANT_HP_EVENT:
2044                 cxt5066_hp_automute(codec);
2045                 break;
2046         case CONEXANT_MIC_EVENT:
2047                 cxt5066_automic(codec);
2048                 break;
2049         }
2050 }
2051
2052 static const struct hda_input_mux cxt5066_analog_mic_boost = {
2053         .num_items = 5,
2054         .items = {
2055                 { "0dB",  0 },
2056                 { "10dB", 1 },
2057                 { "20dB", 2 },
2058                 { "30dB", 3 },
2059                 { "40dB", 4 },
2060         },
2061 };
2062
2063 static int cxt5066_mic_boost_mux_enum_info(struct snd_kcontrol *kcontrol,
2064                                            struct snd_ctl_elem_info *uinfo)
2065 {
2066         return snd_hda_input_mux_info(&cxt5066_analog_mic_boost, uinfo);
2067 }
2068
2069 static int cxt5066_mic_boost_mux_enum_get(struct snd_kcontrol *kcontrol,
2070                                           struct snd_ctl_elem_value *ucontrol)
2071 {
2072         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2073         int val;
2074
2075         val = snd_hda_codec_read(codec, 0x17, 0,
2076                 AC_VERB_GET_AMP_GAIN_MUTE, AC_AMP_GET_OUTPUT);
2077
2078         ucontrol->value.enumerated.item[0] = val & AC_AMP_GAIN;
2079         return 0;
2080 }
2081
2082 static int cxt5066_mic_boost_mux_enum_put(struct snd_kcontrol *kcontrol,
2083                                           struct snd_ctl_elem_value *ucontrol)
2084 {
2085         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2086         const struct hda_input_mux *imux = &cxt5066_analog_mic_boost;
2087         unsigned int idx;
2088
2089         if (!imux->num_items)
2090                 return 0;
2091         idx = ucontrol->value.enumerated.item[0];
2092         if (idx >= imux->num_items)
2093                 idx = imux->num_items - 1;
2094
2095         snd_hda_codec_write_cache(codec, 0x17, 0,
2096                 AC_VERB_SET_AMP_GAIN_MUTE,
2097                 AC_AMP_SET_RIGHT | AC_AMP_SET_LEFT | AC_AMP_SET_OUTPUT |
2098                         imux->items[idx].index);
2099
2100         return 1;
2101 }
2102
2103 static struct hda_input_mux cxt5066_capture_source = {
2104         .num_items = 4,
2105         .items = {
2106                 { "Mic B", 0 },
2107                 { "Mic C", 1 },
2108                 { "Mic E", 2 },
2109                 { "Mic F", 3 },
2110         },
2111 };
2112
2113 static struct hda_bind_ctls cxt5066_bind_capture_vol_others = {
2114         .ops = &snd_hda_bind_vol,
2115         .values = {
2116                 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_INPUT),
2117                 HDA_COMPOSE_AMP_VAL(0x14, 3, 2, HDA_INPUT),
2118                 0
2119         },
2120 };
2121
2122 static struct hda_bind_ctls cxt5066_bind_capture_sw_others = {
2123         .ops = &snd_hda_bind_sw,
2124         .values = {
2125                 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_INPUT),
2126                 HDA_COMPOSE_AMP_VAL(0x14, 3, 2, HDA_INPUT),
2127                 0
2128         },
2129 };
2130
2131 static struct snd_kcontrol_new cxt5066_mixer_master[] = {
2132         HDA_CODEC_VOLUME("Master Playback Volume", 0x10, 0x00, HDA_OUTPUT),
2133         {}
2134 };
2135
2136 static struct snd_kcontrol_new cxt5066_mixer_master_olpc[] = {
2137         {
2138                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2139                 .name = "Master Playback Volume",
2140                 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
2141                                   SNDRV_CTL_ELEM_ACCESS_TLV_READ |
2142                                   SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK,
2143                 .info = snd_hda_mixer_amp_volume_info,
2144                 .get = snd_hda_mixer_amp_volume_get,
2145                 .put = snd_hda_mixer_amp_volume_put,
2146                 .tlv = { .c = snd_hda_mixer_amp_tlv },
2147                 /* offset by 28 volume steps to limit minimum gain to -46dB */
2148                 .private_value =
2149                         HDA_COMPOSE_AMP_VAL_OFS(0x10, 3, 0, HDA_OUTPUT, 28),
2150         },
2151         {}
2152 };
2153
2154 static struct snd_kcontrol_new cxt5066_mixers[] = {
2155         {
2156                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2157                 .name = "Master Playback Switch",
2158                 .info = cxt_eapd_info,
2159                 .get = cxt_eapd_get,
2160                 .put = cxt5066_hp_master_sw_put,
2161                 .private_value = 0x1d,
2162         },
2163
2164         {
2165                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2166                 .name = "Analog Mic Boost Capture Enum",
2167                 .info = cxt5066_mic_boost_mux_enum_info,
2168                 .get = cxt5066_mic_boost_mux_enum_get,
2169                 .put = cxt5066_mic_boost_mux_enum_put,
2170         },
2171
2172         HDA_BIND_VOL("Capture Volume", &cxt5066_bind_capture_vol_others),
2173         HDA_BIND_SW("Capture Switch", &cxt5066_bind_capture_sw_others),
2174         {}
2175 };
2176
2177 static struct hda_verb cxt5066_init_verbs[] = {
2178         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, /* Port B */
2179         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, /* Port C */
2180         {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Port F */
2181         {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Port E */
2182
2183         /* Speakers  */
2184         {0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2185         {0x1f, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
2186
2187         /* HP, Amp  */
2188         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2189         {0x19, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
2190
2191         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2192         {0x1c, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
2193
2194         /* DAC1 */
2195         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2196
2197         /* Node 14 connections: 0x17 0x18 0x23 0x24 0x27 */
2198         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x50},
2199         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2200         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2) | 0x50},
2201         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2202         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2203
2204         /* no digital microphone support yet */
2205         {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2206
2207         /* Audio input selector */
2208         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x3},
2209
2210         /* SPDIF route: PCM */
2211         {0x20, AC_VERB_SET_CONNECT_SEL, 0x0},
2212         {0x22, AC_VERB_SET_CONNECT_SEL, 0x0},
2213
2214         {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2215         {0x22, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2216
2217         /* EAPD */
2218         {0x1d, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
2219
2220         /* not handling these yet */
2221         {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, 0},
2222         {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, 0},
2223         {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, 0},
2224         {0x1c, AC_VERB_SET_UNSOLICITED_ENABLE, 0},
2225         {0x1d, AC_VERB_SET_UNSOLICITED_ENABLE, 0},
2226         {0x1e, AC_VERB_SET_UNSOLICITED_ENABLE, 0},
2227         {0x20, AC_VERB_SET_UNSOLICITED_ENABLE, 0},
2228         {0x22, AC_VERB_SET_UNSOLICITED_ENABLE, 0},
2229         { } /* end */
2230 };
2231
2232 static struct hda_verb cxt5066_init_verbs_olpc[] = {
2233         /* Port A: headphones */
2234         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2235         {0x19, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
2236
2237         /* Port B: external microphone */
2238         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2239
2240         /* Port C: internal microphone */
2241         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2242
2243         /* Port D: unused */
2244         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2245
2246         /* Port E: unused, but has primary EAPD */
2247         {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2248         {0x1d, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
2249
2250         /* Port F: unused */
2251         {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2252
2253         /* Port G: internal speakers */
2254         {0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2255         {0x1f, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
2256
2257         /* DAC1 */
2258         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2259
2260         /* DAC2: unused */
2261         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2262
2263         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x50},
2264         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2265         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2266         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2267         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2268         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2269         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2270         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2271         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2272         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2273         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2274         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2275
2276         /* Disable digital microphone port */
2277         {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2278
2279         /* Audio input selectors */
2280         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x3},
2281         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2282
2283         /* Disable SPDIF */
2284         {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2285         {0x22, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2286
2287         /* enable unsolicited events for Port A and B */
2288         {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT},
2289         {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT},
2290         { } /* end */
2291 };
2292
2293 static struct hda_verb cxt5066_init_verbs_portd_lo[] = {
2294         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2295         { } /* end */
2296 };
2297
2298 /* initialize jack-sensing, too */
2299 static int cxt5066_init(struct hda_codec *codec)
2300 {
2301         snd_printdd("CXT5066: init\n");
2302         conexant_init(codec);
2303         if (codec->patch_ops.unsol_event) {
2304                 cxt5066_hp_automute(codec);
2305                 cxt5066_automic(codec);
2306         }
2307         return 0;
2308 }
2309
2310 enum {
2311         CXT5066_LAPTOP,                 /* Laptops w/ EAPD support */
2312         CXT5066_DELL_LAPTOP,    /* Dell Laptop */
2313         CXT5066_OLPC_XO_1_5,    /* OLPC XO 1.5 */
2314         CXT5066_MODELS
2315 };
2316
2317 static const char *cxt5066_models[CXT5066_MODELS] = {
2318         [CXT5066_LAPTOP]                = "laptop",
2319         [CXT5066_DELL_LAPTOP]   = "dell-laptop",
2320         [CXT5066_OLPC_XO_1_5]   = "olpc-xo-1_5",
2321 };
2322
2323 static struct snd_pci_quirk cxt5066_cfg_tbl[] = {
2324         SND_PCI_QUIRK(0x14f1, 0x0101, "Conexant Reference board",
2325                       CXT5066_LAPTOP),
2326         SND_PCI_QUIRK(0x1028, 0x02f5, "Dell",
2327                       CXT5066_DELL_LAPTOP),
2328         SND_PCI_QUIRK(0x152d, 0x0833, "OLPC XO-1.5", CXT5066_OLPC_XO_1_5),
2329         {}
2330 };
2331
2332 static int patch_cxt5066(struct hda_codec *codec)
2333 {
2334         struct conexant_spec *spec;
2335         int board_config;
2336
2337         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
2338         if (!spec)
2339                 return -ENOMEM;
2340         codec->spec = spec;
2341
2342         codec->patch_ops = conexant_patch_ops;
2343         codec->patch_ops.init = cxt5066_init;
2344
2345         spec->dell_automute = 0;
2346         spec->multiout.max_channels = 2;
2347         spec->multiout.num_dacs = ARRAY_SIZE(cxt5066_dac_nids);
2348         spec->multiout.dac_nids = cxt5066_dac_nids;
2349         spec->multiout.dig_out_nid = CXT5066_SPDIF_OUT;
2350         spec->num_adc_nids = 1;
2351         spec->adc_nids = cxt5066_adc_nids;
2352         spec->capsrc_nids = cxt5066_capsrc_nids;
2353         spec->input_mux = &cxt5066_capture_source;
2354
2355         spec->port_d_mode = PIN_HP;
2356
2357         spec->num_init_verbs = 1;
2358         spec->init_verbs[0] = cxt5066_init_verbs;
2359         spec->num_channel_mode = ARRAY_SIZE(cxt5066_modes);
2360         spec->channel_mode = cxt5066_modes;
2361         spec->cur_adc = 0;
2362         spec->cur_adc_idx = 0;
2363
2364         board_config = snd_hda_check_board_config(codec, CXT5066_MODELS,
2365                                                   cxt5066_models, cxt5066_cfg_tbl);
2366         switch (board_config) {
2367         default:
2368         case CXT5066_LAPTOP:
2369                 spec->mixers[spec->num_mixers++] = cxt5066_mixer_master;
2370                 spec->mixers[spec->num_mixers++] = cxt5066_mixers;
2371                 break;
2372         case CXT5066_DELL_LAPTOP:
2373                 spec->mixers[spec->num_mixers++] = cxt5066_mixer_master;
2374                 spec->mixers[spec->num_mixers++] = cxt5066_mixers;
2375
2376                 spec->port_d_mode = PIN_OUT;
2377                 spec->init_verbs[spec->num_init_verbs] = cxt5066_init_verbs_portd_lo;
2378                 spec->num_init_verbs++;
2379                 spec->dell_automute = 1;
2380                 break;
2381         case CXT5066_OLPC_XO_1_5:
2382                 codec->patch_ops.unsol_event = cxt5066_unsol_event;
2383                 spec->init_verbs[0] = cxt5066_init_verbs_olpc;
2384                 spec->mixers[spec->num_mixers++] = cxt5066_mixer_master_olpc;
2385                 spec->mixers[spec->num_mixers++] = cxt5066_mixers;
2386                 spec->port_d_mode = 0;
2387
2388                 /* no S/PDIF out */
2389                 spec->multiout.dig_out_nid = 0;
2390
2391                 /* input source automatically selected */
2392                 spec->input_mux = NULL;
2393                 break;
2394         }
2395
2396         return 0;
2397 }
2398
2399 /*
2400  */
2401
2402 static struct hda_codec_preset snd_hda_preset_conexant[] = {
2403         { .id = 0x14f15045, .name = "CX20549 (Venice)",
2404           .patch = patch_cxt5045 },
2405         { .id = 0x14f15047, .name = "CX20551 (Waikiki)",
2406           .patch = patch_cxt5047 },
2407         { .id = 0x14f15051, .name = "CX20561 (Hermosa)",
2408           .patch = patch_cxt5051 },
2409         { .id = 0x14f15066, .name = "CX20582 (Pebble)",
2410           .patch = patch_cxt5066 },
2411         {} /* terminator */
2412 };
2413
2414 MODULE_ALIAS("snd-hda-codec-id:14f15045");
2415 MODULE_ALIAS("snd-hda-codec-id:14f15047");
2416 MODULE_ALIAS("snd-hda-codec-id:14f15051");
2417 MODULE_ALIAS("snd-hda-codec-id:14f15066");
2418
2419 MODULE_LICENSE("GPL");
2420 MODULE_DESCRIPTION("Conexant HD-audio codec");
2421
2422 static struct hda_codec_preset_list conexant_list = {
2423         .preset = snd_hda_preset_conexant,
2424         .owner = THIS_MODULE,
2425 };
2426
2427 static int __init patch_conexant_init(void)
2428 {
2429         return snd_hda_add_codec_preset(&conexant_list);
2430 }
2431
2432 static void __exit patch_conexant_exit(void)
2433 {
2434         snd_hda_delete_codec_preset(&conexant_list);
2435 }
2436
2437 module_init(patch_conexant_init)
2438 module_exit(patch_conexant_exit)