]> pilppa.org Git - linux-2.6-omap-h63xx.git/blob - sound/pci/hda/patch_conexant.c
ALSA: hda - Create vmaster for conexant codecs
[linux-2.6-omap-h63xx.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 };
112
113 static int conexant_playback_pcm_open(struct hda_pcm_stream *hinfo,
114                                       struct hda_codec *codec,
115                                       struct snd_pcm_substream *substream)
116 {
117         struct conexant_spec *spec = codec->spec;
118         return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
119                                              hinfo);
120 }
121
122 static int conexant_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
123                                          struct hda_codec *codec,
124                                          unsigned int stream_tag,
125                                          unsigned int format,
126                                          struct snd_pcm_substream *substream)
127 {
128         struct conexant_spec *spec = codec->spec;
129         return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
130                                                 stream_tag,
131                                                 format, substream);
132 }
133
134 static int conexant_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
135                                          struct hda_codec *codec,
136                                          struct snd_pcm_substream *substream)
137 {
138         struct conexant_spec *spec = codec->spec;
139         return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
140 }
141
142 /*
143  * Digital out
144  */
145 static int conexant_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
146                                           struct hda_codec *codec,
147                                           struct snd_pcm_substream *substream)
148 {
149         struct conexant_spec *spec = codec->spec;
150         return snd_hda_multi_out_dig_open(codec, &spec->multiout);
151 }
152
153 static int conexant_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
154                                          struct hda_codec *codec,
155                                          struct snd_pcm_substream *substream)
156 {
157         struct conexant_spec *spec = codec->spec;
158         return snd_hda_multi_out_dig_close(codec, &spec->multiout);
159 }
160
161 static int conexant_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
162                                          struct hda_codec *codec,
163                                          unsigned int stream_tag,
164                                          unsigned int format,
165                                          struct snd_pcm_substream *substream)
166 {
167         struct conexant_spec *spec = codec->spec;
168         return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
169                                              stream_tag,
170                                              format, substream);
171 }
172
173 /*
174  * Analog capture
175  */
176 static int conexant_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
177                                       struct hda_codec *codec,
178                                       unsigned int stream_tag,
179                                       unsigned int format,
180                                       struct snd_pcm_substream *substream)
181 {
182         struct conexant_spec *spec = codec->spec;
183         snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
184                                    stream_tag, 0, format);
185         return 0;
186 }
187
188 static int conexant_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
189                                       struct hda_codec *codec,
190                                       struct snd_pcm_substream *substream)
191 {
192         struct conexant_spec *spec = codec->spec;
193         snd_hda_codec_cleanup_stream(codec, spec->adc_nids[substream->number]);
194         return 0;
195 }
196
197
198
199 static struct hda_pcm_stream conexant_pcm_analog_playback = {
200         .substreams = 1,
201         .channels_min = 2,
202         .channels_max = 2,
203         .nid = 0, /* fill later */
204         .ops = {
205                 .open = conexant_playback_pcm_open,
206                 .prepare = conexant_playback_pcm_prepare,
207                 .cleanup = conexant_playback_pcm_cleanup
208         },
209 };
210
211 static struct hda_pcm_stream conexant_pcm_analog_capture = {
212         .substreams = 1,
213         .channels_min = 2,
214         .channels_max = 2,
215         .nid = 0, /* fill later */
216         .ops = {
217                 .prepare = conexant_capture_pcm_prepare,
218                 .cleanup = conexant_capture_pcm_cleanup
219         },
220 };
221
222
223 static struct hda_pcm_stream conexant_pcm_digital_playback = {
224         .substreams = 1,
225         .channels_min = 2,
226         .channels_max = 2,
227         .nid = 0, /* fill later */
228         .ops = {
229                 .open = conexant_dig_playback_pcm_open,
230                 .close = conexant_dig_playback_pcm_close,
231                 .prepare = conexant_dig_playback_pcm_prepare
232         },
233 };
234
235 static struct hda_pcm_stream conexant_pcm_digital_capture = {
236         .substreams = 1,
237         .channels_min = 2,
238         .channels_max = 2,
239         /* NID is set in alc_build_pcms */
240 };
241
242 static int cx5051_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
243                                       struct hda_codec *codec,
244                                       unsigned int stream_tag,
245                                       unsigned int format,
246                                       struct snd_pcm_substream *substream)
247 {
248         struct conexant_spec *spec = codec->spec;
249         spec->cur_adc = spec->adc_nids[spec->cur_adc_idx];
250         spec->cur_adc_stream_tag = stream_tag;
251         spec->cur_adc_format = format;
252         snd_hda_codec_setup_stream(codec, spec->cur_adc, stream_tag, 0, format);
253         return 0;
254 }
255
256 static int cx5051_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
257                                       struct hda_codec *codec,
258                                       struct snd_pcm_substream *substream)
259 {
260         struct conexant_spec *spec = codec->spec;
261         snd_hda_codec_cleanup_stream(codec, spec->cur_adc);
262         spec->cur_adc = 0;
263         return 0;
264 }
265
266 static struct hda_pcm_stream cx5051_pcm_analog_capture = {
267         .substreams = 1,
268         .channels_min = 2,
269         .channels_max = 2,
270         .nid = 0, /* fill later */
271         .ops = {
272                 .prepare = cx5051_capture_pcm_prepare,
273                 .cleanup = cx5051_capture_pcm_cleanup
274         },
275 };
276
277 static int conexant_build_pcms(struct hda_codec *codec)
278 {
279         struct conexant_spec *spec = codec->spec;
280         struct hda_pcm *info = spec->pcm_rec;
281
282         codec->num_pcms = 1;
283         codec->pcm_info = info;
284
285         info->name = "CONEXANT Analog";
286         info->stream[SNDRV_PCM_STREAM_PLAYBACK] = conexant_pcm_analog_playback;
287         info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max =
288                 spec->multiout.max_channels;
289         info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
290                 spec->multiout.dac_nids[0];
291         if (codec->vendor_id == 0x14f15051)
292                 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
293                         cx5051_pcm_analog_capture;
294         else
295                 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
296                         conexant_pcm_analog_capture;
297         info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = spec->num_adc_nids;
298         info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
299
300         if (spec->multiout.dig_out_nid) {
301                 info++;
302                 codec->num_pcms++;
303                 info->name = "Conexant Digital";
304                 info->pcm_type = HDA_PCM_TYPE_SPDIF;
305                 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
306                         conexant_pcm_digital_playback;
307                 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
308                         spec->multiout.dig_out_nid;
309                 if (spec->dig_in_nid) {
310                         info->stream[SNDRV_PCM_STREAM_CAPTURE] =
311                                 conexant_pcm_digital_capture;
312                         info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
313                                 spec->dig_in_nid;
314                 }
315         }
316
317         return 0;
318 }
319
320 static int conexant_mux_enum_info(struct snd_kcontrol *kcontrol,
321                                   struct snd_ctl_elem_info *uinfo)
322 {
323         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
324         struct conexant_spec *spec = codec->spec;
325
326         return snd_hda_input_mux_info(spec->input_mux, uinfo);
327 }
328
329 static int conexant_mux_enum_get(struct snd_kcontrol *kcontrol,
330                                  struct snd_ctl_elem_value *ucontrol)
331 {
332         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
333         struct conexant_spec *spec = codec->spec;
334         unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
335
336         ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
337         return 0;
338 }
339
340 static int conexant_mux_enum_put(struct snd_kcontrol *kcontrol,
341                                  struct snd_ctl_elem_value *ucontrol)
342 {
343         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
344         struct conexant_spec *spec = codec->spec;
345         unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
346
347         return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol,
348                                      spec->capsrc_nids[adc_idx],
349                                      &spec->cur_mux[adc_idx]);
350 }
351
352 #ifdef CONFIG_SND_JACK
353 static int conexant_add_jack(struct hda_codec *codec,
354                 hda_nid_t nid, int type)
355 {
356         struct conexant_spec *spec;
357         struct conexant_jack *jack;
358         const char *name;
359
360         spec = codec->spec;
361         snd_array_init(&spec->jacks, sizeof(*jack), 32);
362         jack = snd_array_new(&spec->jacks);
363         name = (type == SND_JACK_HEADPHONE) ? "Headphone" : "Mic" ;
364
365         if (!jack)
366                 return -ENOMEM;
367
368         jack->nid = nid;
369         jack->type = type;
370
371         return snd_jack_new(codec->bus->card, name, type, &jack->jack);
372 }
373
374 static void conexant_report_jack(struct hda_codec *codec, hda_nid_t nid)
375 {
376         struct conexant_spec *spec = codec->spec;
377         struct conexant_jack *jacks = spec->jacks.list;
378
379         if (jacks) {
380                 int i;
381                 for (i = 0; i < spec->jacks.used; i++) {
382                         if (jacks->nid == nid) {
383                                 unsigned int present;
384                                 present = snd_hda_codec_read(codec, nid, 0,
385                                                 AC_VERB_GET_PIN_SENSE, 0) &
386                                         AC_PINSENSE_PRESENCE;
387
388                                 present = (present) ? jacks->type : 0 ;
389
390                                 snd_jack_report(jacks->jack,
391                                                 present);
392                         }
393                         jacks++;
394                 }
395         }
396 }
397
398 static int conexant_init_jacks(struct hda_codec *codec)
399 {
400         struct conexant_spec *spec = codec->spec;
401         int i;
402
403         for (i = 0; i < spec->num_init_verbs; i++) {
404                 const struct hda_verb *hv;
405
406                 hv = spec->init_verbs[i];
407                 while (hv->nid) {
408                         int err = 0;
409                         switch (hv->param ^ AC_USRSP_EN) {
410                         case CONEXANT_HP_EVENT:
411                                 err = conexant_add_jack(codec, hv->nid,
412                                                 SND_JACK_HEADPHONE);
413                                 conexant_report_jack(codec, hv->nid);
414                                 break;
415                         case CXT5051_PORTC_EVENT:
416                         case CONEXANT_MIC_EVENT:
417                                 err = conexant_add_jack(codec, hv->nid,
418                                                 SND_JACK_MICROPHONE);
419                                 conexant_report_jack(codec, hv->nid);
420                                 break;
421                         }
422                         if (err < 0)
423                                 return err;
424                         ++hv;
425                 }
426         }
427         return 0;
428
429 }
430 #else
431 static inline void conexant_report_jack(struct hda_codec *codec, hda_nid_t nid)
432 {
433 }
434
435 static inline int conexant_init_jacks(struct hda_codec *codec)
436 {
437         return 0;
438 }
439 #endif
440
441 static int conexant_init(struct hda_codec *codec)
442 {
443         struct conexant_spec *spec = codec->spec;
444         int i;
445
446         for (i = 0; i < spec->num_init_verbs; i++)
447                 snd_hda_sequence_write(codec, spec->init_verbs[i]);
448         return 0;
449 }
450
451 static void conexant_free(struct hda_codec *codec)
452 {
453 #ifdef CONFIG_SND_JACK
454         struct conexant_spec *spec = codec->spec;
455         if (spec->jacks.list) {
456                 struct conexant_jack *jacks = spec->jacks.list;
457                 int i;
458                 for (i = 0; i < spec->jacks.used; i++)
459                         snd_device_free(codec->bus->card, &jacks[i].jack);
460                 snd_array_free(&spec->jacks);
461         }
462 #endif
463         kfree(codec->spec);
464 }
465
466 static const char *slave_vols[] = {
467         "Headphone Playback Volume",
468         "Speaker Playback Volume",
469         NULL
470 };
471
472 static const char *slave_sws[] = {
473         "Headphone Playback Switch",
474         "Speaker Playback Switch",
475         NULL
476 };
477
478 static int conexant_build_controls(struct hda_codec *codec)
479 {
480         struct conexant_spec *spec = codec->spec;
481         unsigned int i;
482         int err;
483
484         for (i = 0; i < spec->num_mixers; i++) {
485                 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
486                 if (err < 0)
487                         return err;
488         }
489         if (spec->multiout.dig_out_nid) {
490                 err = snd_hda_create_spdif_out_ctls(codec,
491                                                     spec->multiout.dig_out_nid);
492                 if (err < 0)
493                         return err;
494                 err = snd_hda_create_spdif_share_sw(codec,
495                                                     &spec->multiout);
496                 if (err < 0)
497                         return err;
498                 spec->multiout.share_spdif = 1;
499         } 
500         if (spec->dig_in_nid) {
501                 err = snd_hda_create_spdif_in_ctls(codec,spec->dig_in_nid);
502                 if (err < 0)
503                         return err;
504         }
505
506         /* if we have no master control, let's create it */
507         if (spec->vmaster_nid &&
508             !snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
509                 unsigned int vmaster_tlv[4];
510                 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
511                                         HDA_OUTPUT, vmaster_tlv);
512                 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
513                                           vmaster_tlv, slave_vols);
514                 if (err < 0)
515                         return err;
516         }
517         if (spec->vmaster_nid &&
518             !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
519                 err = snd_hda_add_vmaster(codec, "Master Playback Switch",
520                                           NULL, slave_sws);
521                 if (err < 0)
522                         return err;
523         }
524
525         return 0;
526 }
527
528 static struct hda_codec_ops conexant_patch_ops = {
529         .build_controls = conexant_build_controls,
530         .build_pcms = conexant_build_pcms,
531         .init = conexant_init,
532         .free = conexant_free,
533 };
534
535 /*
536  * EAPD control
537  * the private value = nid | (invert << 8)
538  */
539
540 #define cxt_eapd_info           snd_ctl_boolean_mono_info
541
542 static int cxt_eapd_get(struct snd_kcontrol *kcontrol,
543                              struct snd_ctl_elem_value *ucontrol)
544 {
545         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
546         struct conexant_spec *spec = codec->spec;
547         int invert = (kcontrol->private_value >> 8) & 1;
548         if (invert)
549                 ucontrol->value.integer.value[0] = !spec->cur_eapd;
550         else
551                 ucontrol->value.integer.value[0] = spec->cur_eapd;
552         return 0;
553
554 }
555
556 static int cxt_eapd_put(struct snd_kcontrol *kcontrol,
557                              struct snd_ctl_elem_value *ucontrol)
558 {
559         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
560         struct conexant_spec *spec = codec->spec;
561         int invert = (kcontrol->private_value >> 8) & 1;
562         hda_nid_t nid = kcontrol->private_value & 0xff;
563         unsigned int eapd;
564
565         eapd = !!ucontrol->value.integer.value[0];
566         if (invert)
567                 eapd = !eapd;
568         if (eapd == spec->cur_eapd)
569                 return 0;
570         
571         spec->cur_eapd = eapd;
572         snd_hda_codec_write_cache(codec, nid,
573                                   0, AC_VERB_SET_EAPD_BTLENABLE,
574                                   eapd ? 0x02 : 0x00);
575         return 1;
576 }
577
578 /* controls for test mode */
579 #ifdef CONFIG_SND_DEBUG
580
581 #define CXT_EAPD_SWITCH(xname, nid, mask) \
582         { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
583           .info = cxt_eapd_info, \
584           .get = cxt_eapd_get, \
585           .put = cxt_eapd_put, \
586           .private_value = nid | (mask<<16) }
587
588
589
590 static int conexant_ch_mode_info(struct snd_kcontrol *kcontrol,
591                                  struct snd_ctl_elem_info *uinfo)
592 {
593         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
594         struct conexant_spec *spec = codec->spec;
595         return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
596                                     spec->num_channel_mode);
597 }
598
599 static int conexant_ch_mode_get(struct snd_kcontrol *kcontrol,
600                                 struct snd_ctl_elem_value *ucontrol)
601 {
602         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
603         struct conexant_spec *spec = codec->spec;
604         return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
605                                    spec->num_channel_mode,
606                                    spec->multiout.max_channels);
607 }
608
609 static int conexant_ch_mode_put(struct snd_kcontrol *kcontrol,
610                                 struct snd_ctl_elem_value *ucontrol)
611 {
612         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
613         struct conexant_spec *spec = codec->spec;
614         int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
615                                       spec->num_channel_mode,
616                                       &spec->multiout.max_channels);
617         if (err >= 0 && spec->need_dac_fix)
618                 spec->multiout.num_dacs = spec->multiout.max_channels / 2;
619         return err;
620 }
621
622 #define CXT_PIN_MODE(xname, nid, dir) \
623         { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
624           .info = conexant_ch_mode_info, \
625           .get = conexant_ch_mode_get, \
626           .put = conexant_ch_mode_put, \
627           .private_value = nid | (dir<<16) }
628
629 #endif /* CONFIG_SND_DEBUG */
630
631 /* Conexant 5045 specific */
632
633 static hda_nid_t cxt5045_dac_nids[1] = { 0x19 };
634 static hda_nid_t cxt5045_adc_nids[1] = { 0x1a };
635 static hda_nid_t cxt5045_capsrc_nids[1] = { 0x1a };
636 #define CXT5045_SPDIF_OUT       0x18
637
638 static struct hda_channel_mode cxt5045_modes[1] = {
639         { 2, NULL },
640 };
641
642 static struct hda_input_mux cxt5045_capture_source = {
643         .num_items = 2,
644         .items = {
645                 { "IntMic", 0x1 },
646                 { "ExtMic", 0x2 },
647         }
648 };
649
650 static struct hda_input_mux cxt5045_capture_source_benq = {
651         .num_items = 3,
652         .items = {
653                 { "IntMic", 0x1 },
654                 { "ExtMic", 0x2 },
655                 { "LineIn", 0x3 },
656         }
657 };
658
659 static struct hda_input_mux cxt5045_capture_source_hp530 = {
660         .num_items = 2,
661         .items = {
662                 { "ExtMic", 0x1 },
663                 { "IntMic", 0x2 },
664         }
665 };
666
667 /* turn on/off EAPD (+ mute HP) as a master switch */
668 static int cxt5045_hp_master_sw_put(struct snd_kcontrol *kcontrol,
669                                     struct snd_ctl_elem_value *ucontrol)
670 {
671         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
672         struct conexant_spec *spec = codec->spec;
673         unsigned int bits;
674
675         if (!cxt_eapd_put(kcontrol, ucontrol))
676                 return 0;
677
678         /* toggle internal speakers mute depending of presence of
679          * the headphone jack
680          */
681         bits = (!spec->hp_present && spec->cur_eapd) ? 0 : HDA_AMP_MUTE;
682         snd_hda_codec_amp_stereo(codec, 0x10, HDA_OUTPUT, 0,
683                                  HDA_AMP_MUTE, bits);
684
685         bits = spec->cur_eapd ? 0 : HDA_AMP_MUTE;
686         snd_hda_codec_amp_stereo(codec, 0x11, HDA_OUTPUT, 0,
687                                  HDA_AMP_MUTE, bits);
688         return 1;
689 }
690
691 /* bind volumes of both NID 0x10 and 0x11 */
692 static struct hda_bind_ctls cxt5045_hp_bind_master_vol = {
693         .ops = &snd_hda_bind_vol,
694         .values = {
695                 HDA_COMPOSE_AMP_VAL(0x10, 3, 0, HDA_OUTPUT),
696                 HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT),
697                 0
698         },
699 };
700
701 /* toggle input of built-in and mic jack appropriately */
702 static void cxt5045_hp_automic(struct hda_codec *codec)
703 {
704         static struct hda_verb mic_jack_on[] = {
705                 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
706                 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
707                 {}
708         };
709         static struct hda_verb mic_jack_off[] = {
710                 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
711                 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
712                 {}
713         };
714         unsigned int present;
715
716         present = snd_hda_codec_read(codec, 0x12, 0,
717                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
718         if (present)
719                 snd_hda_sequence_write(codec, mic_jack_on);
720         else
721                 snd_hda_sequence_write(codec, mic_jack_off);
722 }
723
724
725 /* mute internal speaker if HP is plugged */
726 static void cxt5045_hp_automute(struct hda_codec *codec)
727 {
728         struct conexant_spec *spec = codec->spec;
729         unsigned int bits;
730
731         spec->hp_present = snd_hda_codec_read(codec, 0x11, 0,
732                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
733
734         bits = (spec->hp_present || !spec->cur_eapd) ? HDA_AMP_MUTE : 0; 
735         snd_hda_codec_amp_stereo(codec, 0x10, HDA_OUTPUT, 0,
736                                  HDA_AMP_MUTE, bits);
737 }
738
739 /* unsolicited event for HP jack sensing */
740 static void cxt5045_hp_unsol_event(struct hda_codec *codec,
741                                    unsigned int res)
742 {
743         res >>= 26;
744         switch (res) {
745         case CONEXANT_HP_EVENT:
746                 cxt5045_hp_automute(codec);
747                 break;
748         case CONEXANT_MIC_EVENT:
749                 cxt5045_hp_automic(codec);
750                 break;
751
752         }
753 }
754
755 static struct snd_kcontrol_new cxt5045_mixers[] = {
756         {
757                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
758                 .name = "Capture Source",
759                 .info = conexant_mux_enum_info,
760                 .get = conexant_mux_enum_get,
761                 .put = conexant_mux_enum_put
762         },
763         HDA_CODEC_VOLUME("Int Mic Capture Volume", 0x1a, 0x01, HDA_INPUT),
764         HDA_CODEC_MUTE("Int Mic Capture Switch", 0x1a, 0x01, HDA_INPUT),
765         HDA_CODEC_VOLUME("Ext Mic Capture Volume", 0x1a, 0x02, HDA_INPUT),
766         HDA_CODEC_MUTE("Ext Mic Capture Switch", 0x1a, 0x02, HDA_INPUT),
767         HDA_CODEC_VOLUME("PCM Playback Volume", 0x17, 0x0, HDA_INPUT),
768         HDA_CODEC_MUTE("PCM Playback Switch", 0x17, 0x0, HDA_INPUT),
769         HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x17, 0x1, HDA_INPUT),
770         HDA_CODEC_MUTE("Int Mic Playback Switch", 0x17, 0x1, HDA_INPUT),
771         HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x17, 0x2, HDA_INPUT),
772         HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x17, 0x2, HDA_INPUT),
773         HDA_BIND_VOL("Master Playback Volume", &cxt5045_hp_bind_master_vol),
774         {
775                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
776                 .name = "Master Playback Switch",
777                 .info = cxt_eapd_info,
778                 .get = cxt_eapd_get,
779                 .put = cxt5045_hp_master_sw_put,
780                 .private_value = 0x10,
781         },
782
783         {}
784 };
785
786 static struct snd_kcontrol_new cxt5045_benq_mixers[] = {
787         HDA_CODEC_VOLUME("Line In Capture Volume", 0x1a, 0x03, HDA_INPUT),
788         HDA_CODEC_MUTE("Line In Capture Switch", 0x1a, 0x03, HDA_INPUT),
789         HDA_CODEC_VOLUME("Line In Playback Volume", 0x17, 0x3, HDA_INPUT),
790         HDA_CODEC_MUTE("Line In Playback Switch", 0x17, 0x3, HDA_INPUT),
791
792         {}
793 };
794
795 static struct snd_kcontrol_new cxt5045_mixers_hp530[] = {
796         {
797                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
798                 .name = "Capture Source",
799                 .info = conexant_mux_enum_info,
800                 .get = conexant_mux_enum_get,
801                 .put = conexant_mux_enum_put
802         },
803         HDA_CODEC_VOLUME("Int Mic Capture Volume", 0x1a, 0x02, HDA_INPUT),
804         HDA_CODEC_MUTE("Int Mic Capture Switch", 0x1a, 0x02, HDA_INPUT),
805         HDA_CODEC_VOLUME("Ext Mic Capture Volume", 0x1a, 0x01, HDA_INPUT),
806         HDA_CODEC_MUTE("Ext Mic Capture Switch", 0x1a, 0x01, HDA_INPUT),
807         HDA_CODEC_VOLUME("PCM Playback Volume", 0x17, 0x0, HDA_INPUT),
808         HDA_CODEC_MUTE("PCM Playback Switch", 0x17, 0x0, HDA_INPUT),
809         HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x17, 0x2, HDA_INPUT),
810         HDA_CODEC_MUTE("Int Mic Playback Switch", 0x17, 0x2, HDA_INPUT),
811         HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x17, 0x1, HDA_INPUT),
812         HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x17, 0x1, HDA_INPUT),
813         HDA_BIND_VOL("Master Playback Volume", &cxt5045_hp_bind_master_vol),
814         {
815                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
816                 .name = "Master Playback Switch",
817                 .info = cxt_eapd_info,
818                 .get = cxt_eapd_get,
819                 .put = cxt5045_hp_master_sw_put,
820                 .private_value = 0x10,
821         },
822
823         {}
824 };
825
826 static struct hda_verb cxt5045_init_verbs[] = {
827         /* Line in, Mic */
828         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_80 },
829         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_80 },
830         /* HP, Amp  */
831         {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
832         {0x10, AC_VERB_SET_CONNECT_SEL, 0x1},
833         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
834         {0x11, AC_VERB_SET_CONNECT_SEL, 0x1},
835         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
836         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
837         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
838         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
839         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
840         /* Record selector: Int mic */
841         {0x1a, AC_VERB_SET_CONNECT_SEL,0x1},
842         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE,
843          AC_AMP_SET_INPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x17},
844         /* SPDIF route: PCM */
845         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
846         { 0x13, AC_VERB_SET_CONNECT_SEL, 0x0 },
847         /* EAPD */
848         {0x10, AC_VERB_SET_EAPD_BTLENABLE, 0x2 }, /* default on */ 
849         { } /* end */
850 };
851
852 static struct hda_verb cxt5045_benq_init_verbs[] = {
853         /* Int Mic, Mic */
854         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_80 },
855         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_80 },
856         /* Line In,HP, Amp  */
857         {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
858         {0x10, AC_VERB_SET_CONNECT_SEL, 0x1},
859         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
860         {0x11, AC_VERB_SET_CONNECT_SEL, 0x1},
861         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
862         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
863         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
864         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
865         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
866         /* Record selector: Int mic */
867         {0x1a, AC_VERB_SET_CONNECT_SEL, 0x1},
868         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE,
869          AC_AMP_SET_INPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x17},
870         /* SPDIF route: PCM */
871         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
872         {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
873         /* EAPD */
874         {0x10, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
875         { } /* end */
876 };
877
878 static struct hda_verb cxt5045_hp_sense_init_verbs[] = {
879         /* pin sensing on HP jack */
880         {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT},
881         { } /* end */
882 };
883
884 static struct hda_verb cxt5045_mic_sense_init_verbs[] = {
885         /* pin sensing on HP jack */
886         {0x12, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT},
887         { } /* end */
888 };
889
890 #ifdef CONFIG_SND_DEBUG
891 /* Test configuration for debugging, modelled after the ALC260 test
892  * configuration.
893  */
894 static struct hda_input_mux cxt5045_test_capture_source = {
895         .num_items = 5,
896         .items = {
897                 { "MIXER", 0x0 },
898                 { "MIC1 pin", 0x1 },
899                 { "LINE1 pin", 0x2 },
900                 { "HP-OUT pin", 0x3 },
901                 { "CD pin", 0x4 },
902         },
903 };
904
905 static struct snd_kcontrol_new cxt5045_test_mixer[] = {
906
907         /* Output controls */
908         HDA_CODEC_VOLUME("Speaker Playback Volume", 0x10, 0x0, HDA_OUTPUT),
909         HDA_CODEC_MUTE("Speaker Playback Switch", 0x10, 0x0, HDA_OUTPUT),
910         HDA_CODEC_VOLUME("Node 11 Playback Volume", 0x11, 0x0, HDA_OUTPUT),
911         HDA_CODEC_MUTE("Node 11 Playback Switch", 0x11, 0x0, HDA_OUTPUT),
912         HDA_CODEC_VOLUME("Node 12 Playback Volume", 0x12, 0x0, HDA_OUTPUT),
913         HDA_CODEC_MUTE("Node 12 Playback Switch", 0x12, 0x0, HDA_OUTPUT),
914         
915         /* Modes for retasking pin widgets */
916         CXT_PIN_MODE("HP-OUT pin mode", 0x11, CXT_PIN_DIR_INOUT),
917         CXT_PIN_MODE("LINE1 pin mode", 0x12, CXT_PIN_DIR_INOUT),
918
919         /* EAPD Switch Control */
920         CXT_EAPD_SWITCH("External Amplifier", 0x10, 0x0),
921
922         /* Loopback mixer controls */
923
924         HDA_CODEC_VOLUME("Mixer-1 Volume", 0x17, 0x0, HDA_INPUT),
925         HDA_CODEC_MUTE("Mixer-1 Switch", 0x17, 0x0, HDA_INPUT),
926         HDA_CODEC_VOLUME("Mixer-2 Volume", 0x17, 0x1, HDA_INPUT),
927         HDA_CODEC_MUTE("Mixer-2 Switch", 0x17, 0x1, HDA_INPUT),
928         HDA_CODEC_VOLUME("Mixer-3 Volume", 0x17, 0x2, HDA_INPUT),
929         HDA_CODEC_MUTE("Mixer-3 Switch", 0x17, 0x2, HDA_INPUT),
930         HDA_CODEC_VOLUME("Mixer-4 Volume", 0x17, 0x3, HDA_INPUT),
931         HDA_CODEC_MUTE("Mixer-4 Switch", 0x17, 0x3, HDA_INPUT),
932         HDA_CODEC_VOLUME("Mixer-5 Volume", 0x17, 0x4, HDA_INPUT),
933         HDA_CODEC_MUTE("Mixer-5 Switch", 0x17, 0x4, HDA_INPUT),
934         {
935                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
936                 .name = "Input Source",
937                 .info = conexant_mux_enum_info,
938                 .get = conexant_mux_enum_get,
939                 .put = conexant_mux_enum_put,
940         },
941         /* Audio input controls */
942         HDA_CODEC_VOLUME("Input-1 Volume", 0x1a, 0x0, HDA_INPUT),
943         HDA_CODEC_MUTE("Input-1 Switch", 0x1a, 0x0, HDA_INPUT),
944         HDA_CODEC_VOLUME("Input-2 Volume", 0x1a, 0x1, HDA_INPUT),
945         HDA_CODEC_MUTE("Input-2 Switch", 0x1a, 0x1, HDA_INPUT),
946         HDA_CODEC_VOLUME("Input-3 Volume", 0x1a, 0x2, HDA_INPUT),
947         HDA_CODEC_MUTE("Input-3 Switch", 0x1a, 0x2, HDA_INPUT),
948         HDA_CODEC_VOLUME("Input-4 Volume", 0x1a, 0x3, HDA_INPUT),
949         HDA_CODEC_MUTE("Input-4 Switch", 0x1a, 0x3, HDA_INPUT),
950         HDA_CODEC_VOLUME("Input-5 Volume", 0x1a, 0x4, HDA_INPUT),
951         HDA_CODEC_MUTE("Input-5 Switch", 0x1a, 0x4, HDA_INPUT),
952         { } /* end */
953 };
954
955 static struct hda_verb cxt5045_test_init_verbs[] = {
956         /* Set connections */
957         { 0x10, AC_VERB_SET_CONNECT_SEL, 0x0 },
958         { 0x11, AC_VERB_SET_CONNECT_SEL, 0x0 },
959         { 0x12, AC_VERB_SET_CONNECT_SEL, 0x0 },
960         /* Enable retasking pins as output, initially without power amp */
961         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
962         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
963
964         /* Disable digital (SPDIF) pins initially, but users can enable
965          * them via a mixer switch.  In the case of SPDIF-out, this initverb
966          * payload also sets the generation to 0, output to be in "consumer"
967          * PCM format, copyright asserted, no pre-emphasis and no validity
968          * control.
969          */
970         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
971         {0x18, AC_VERB_SET_DIGI_CONVERT_1, 0},
972
973         /* Start with output sum widgets muted and their output gains at min */
974         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
975         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
976
977         /* Unmute retasking pin widget output buffers since the default
978          * state appears to be output.  As the pin mode is changed by the
979          * user the pin mode control will take care of enabling the pin's
980          * input/output buffers as needed.
981          */
982         {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
983         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
984
985         /* Mute capture amp left and right */
986         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
987
988         /* Set ADC connection select to match default mixer setting (mic1
989          * pin)
990          */
991         {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
992         {0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
993
994         /* Mute all inputs to mixer widget (even unconnected ones) */
995         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* Mixer pin */
996         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* Mic1 pin */
997         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* Line pin */
998         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* HP pin */
999         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
1000
1001         { }
1002 };
1003 #endif
1004
1005
1006 /* initialize jack-sensing, too */
1007 static int cxt5045_init(struct hda_codec *codec)
1008 {
1009         conexant_init(codec);
1010         cxt5045_hp_automute(codec);
1011         return 0;
1012 }
1013
1014
1015 enum {
1016         CXT5045_LAPTOP_HPSENSE,
1017         CXT5045_LAPTOP_MICSENSE,
1018         CXT5045_LAPTOP_HPMICSENSE,
1019         CXT5045_BENQ,
1020         CXT5045_LAPTOP_HP530,
1021 #ifdef CONFIG_SND_DEBUG
1022         CXT5045_TEST,
1023 #endif
1024         CXT5045_MODELS
1025 };
1026
1027 static const char *cxt5045_models[CXT5045_MODELS] = {
1028         [CXT5045_LAPTOP_HPSENSE]        = "laptop-hpsense",
1029         [CXT5045_LAPTOP_MICSENSE]       = "laptop-micsense",
1030         [CXT5045_LAPTOP_HPMICSENSE]     = "laptop-hpmicsense",
1031         [CXT5045_BENQ]                  = "benq",
1032         [CXT5045_LAPTOP_HP530]          = "laptop-hp530",
1033 #ifdef CONFIG_SND_DEBUG
1034         [CXT5045_TEST]          = "test",
1035 #endif
1036 };
1037
1038 static struct snd_pci_quirk cxt5045_cfg_tbl[] = {
1039         SND_PCI_QUIRK(0x103c, 0x30d5, "HP 530", CXT5045_LAPTOP_HP530),
1040         SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3000, "HP DV Series",
1041                            CXT5045_LAPTOP_HPSENSE),
1042         SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba P105", CXT5045_LAPTOP_MICSENSE),
1043         SND_PCI_QUIRK(0x152d, 0x0753, "Benq R55E", CXT5045_BENQ),
1044         SND_PCI_QUIRK(0x1734, 0x10ad, "Fujitsu Si1520", CXT5045_LAPTOP_MICSENSE),
1045         SND_PCI_QUIRK(0x1734, 0x10cb, "Fujitsu Si3515", CXT5045_LAPTOP_HPMICSENSE),
1046         SND_PCI_QUIRK(0x1734, 0x110e, "Fujitsu V5505",
1047                       CXT5045_LAPTOP_HPMICSENSE),
1048         SND_PCI_QUIRK(0x1509, 0x1e40, "FIC", CXT5045_LAPTOP_HPMICSENSE),
1049         SND_PCI_QUIRK(0x1509, 0x2f05, "FIC", CXT5045_LAPTOP_HPMICSENSE),
1050         SND_PCI_QUIRK(0x1509, 0x2f06, "FIC", CXT5045_LAPTOP_HPMICSENSE),
1051         SND_PCI_QUIRK_MASK(0x1631, 0xff00, 0xc100, "Packard Bell",
1052                            CXT5045_LAPTOP_HPMICSENSE),
1053         SND_PCI_QUIRK(0x8086, 0x2111, "Conexant Reference board", CXT5045_LAPTOP_HPSENSE),
1054         {}
1055 };
1056
1057 static int patch_cxt5045(struct hda_codec *codec)
1058 {
1059         struct conexant_spec *spec;
1060         int board_config;
1061
1062         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1063         if (!spec)
1064                 return -ENOMEM;
1065         codec->spec = spec;
1066
1067         spec->multiout.max_channels = 2;
1068         spec->multiout.num_dacs = ARRAY_SIZE(cxt5045_dac_nids);
1069         spec->multiout.dac_nids = cxt5045_dac_nids;
1070         spec->multiout.dig_out_nid = CXT5045_SPDIF_OUT;
1071         spec->num_adc_nids = 1;
1072         spec->adc_nids = cxt5045_adc_nids;
1073         spec->capsrc_nids = cxt5045_capsrc_nids;
1074         spec->input_mux = &cxt5045_capture_source;
1075         spec->num_mixers = 1;
1076         spec->mixers[0] = cxt5045_mixers;
1077         spec->num_init_verbs = 1;
1078         spec->init_verbs[0] = cxt5045_init_verbs;
1079         spec->spdif_route = 0;
1080         spec->num_channel_mode = ARRAY_SIZE(cxt5045_modes),
1081         spec->channel_mode = cxt5045_modes,
1082
1083
1084         codec->patch_ops = conexant_patch_ops;
1085
1086         board_config = snd_hda_check_board_config(codec, CXT5045_MODELS,
1087                                                   cxt5045_models,
1088                                                   cxt5045_cfg_tbl);
1089         switch (board_config) {
1090         case CXT5045_LAPTOP_HPSENSE:
1091                 codec->patch_ops.unsol_event = cxt5045_hp_unsol_event;
1092                 spec->input_mux = &cxt5045_capture_source;
1093                 spec->num_init_verbs = 2;
1094                 spec->init_verbs[1] = cxt5045_hp_sense_init_verbs;
1095                 spec->mixers[0] = cxt5045_mixers;
1096                 codec->patch_ops.init = cxt5045_init;
1097                 break;
1098         case CXT5045_LAPTOP_MICSENSE:
1099                 codec->patch_ops.unsol_event = cxt5045_hp_unsol_event;
1100                 spec->input_mux = &cxt5045_capture_source;
1101                 spec->num_init_verbs = 2;
1102                 spec->init_verbs[1] = cxt5045_mic_sense_init_verbs;
1103                 spec->mixers[0] = cxt5045_mixers;
1104                 codec->patch_ops.init = cxt5045_init;
1105                 break;
1106         default:
1107         case CXT5045_LAPTOP_HPMICSENSE:
1108                 codec->patch_ops.unsol_event = cxt5045_hp_unsol_event;
1109                 spec->input_mux = &cxt5045_capture_source;
1110                 spec->num_init_verbs = 3;
1111                 spec->init_verbs[1] = cxt5045_hp_sense_init_verbs;
1112                 spec->init_verbs[2] = cxt5045_mic_sense_init_verbs;
1113                 spec->mixers[0] = cxt5045_mixers;
1114                 codec->patch_ops.init = cxt5045_init;
1115                 break;
1116         case CXT5045_BENQ:
1117                 codec->patch_ops.unsol_event = cxt5045_hp_unsol_event;
1118                 spec->input_mux = &cxt5045_capture_source_benq;
1119                 spec->num_init_verbs = 1;
1120                 spec->init_verbs[0] = cxt5045_benq_init_verbs;
1121                 spec->mixers[0] = cxt5045_mixers;
1122                 spec->mixers[1] = cxt5045_benq_mixers;
1123                 spec->num_mixers = 2;
1124                 codec->patch_ops.init = cxt5045_init;
1125                 break;
1126         case CXT5045_LAPTOP_HP530:
1127                 codec->patch_ops.unsol_event = cxt5045_hp_unsol_event;
1128                 spec->input_mux = &cxt5045_capture_source_hp530;
1129                 spec->num_init_verbs = 2;
1130                 spec->init_verbs[1] = cxt5045_hp_sense_init_verbs;
1131                 spec->mixers[0] = cxt5045_mixers_hp530;
1132                 codec->patch_ops.init = cxt5045_init;
1133                 break;
1134 #ifdef CONFIG_SND_DEBUG
1135         case CXT5045_TEST:
1136                 spec->input_mux = &cxt5045_test_capture_source;
1137                 spec->mixers[0] = cxt5045_test_mixer;
1138                 spec->init_verbs[0] = cxt5045_test_init_verbs;
1139                 break;
1140                 
1141 #endif  
1142         }
1143
1144         switch (codec->subsystem_id >> 16) {
1145         case 0x103c:
1146                 /* HP laptop has a really bad sound over 0dB on NID 0x17.
1147                  * Fix max PCM level to 0 dB
1148                  * (originall it has 0x2b steps with 0dB offset 0x14)
1149                  */
1150                 snd_hda_override_amp_caps(codec, 0x17, HDA_INPUT,
1151                                           (0x14 << AC_AMPCAP_OFFSET_SHIFT) |
1152                                           (0x14 << AC_AMPCAP_NUM_STEPS_SHIFT) |
1153                                           (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) |
1154                                           (1 << AC_AMPCAP_MUTE_SHIFT));
1155                 break;
1156         }
1157
1158         return 0;
1159 }
1160
1161
1162 /* Conexant 5047 specific */
1163 #define CXT5047_SPDIF_OUT       0x11
1164
1165 static hda_nid_t cxt5047_dac_nids[2] = { 0x10, 0x1c };
1166 static hda_nid_t cxt5047_adc_nids[1] = { 0x12 };
1167 static hda_nid_t cxt5047_capsrc_nids[1] = { 0x1a };
1168
1169 static struct hda_channel_mode cxt5047_modes[1] = {
1170         { 2, NULL },
1171 };
1172
1173 static struct hda_input_mux cxt5047_capture_source = {
1174         .num_items = 1,
1175         .items = {
1176                 { "Mic", 0x2 },
1177         }
1178 };
1179
1180 static struct hda_input_mux cxt5047_hp_capture_source = {
1181         .num_items = 1,
1182         .items = {
1183                 { "ExtMic", 0x2 },
1184         }
1185 };
1186
1187 static struct hda_input_mux cxt5047_toshiba_capture_source = {
1188         .num_items = 2,
1189         .items = {
1190                 { "ExtMic", 0x2 },
1191                 { "Line-In", 0x1 },
1192         }
1193 };
1194
1195 /* turn on/off EAPD (+ mute HP) as a master switch */
1196 static int cxt5047_hp_master_sw_put(struct snd_kcontrol *kcontrol,
1197                                     struct snd_ctl_elem_value *ucontrol)
1198 {
1199         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1200         struct conexant_spec *spec = codec->spec;
1201         unsigned int bits;
1202
1203         if (!cxt_eapd_put(kcontrol, ucontrol))
1204                 return 0;
1205
1206         /* toggle internal speakers mute depending of presence of
1207          * the headphone jack
1208          */
1209         bits = (!spec->hp_present && spec->cur_eapd) ? 0 : HDA_AMP_MUTE;
1210         snd_hda_codec_amp_stereo(codec, 0x1d, HDA_OUTPUT, 0,
1211                                  HDA_AMP_MUTE, bits);
1212         bits = spec->cur_eapd ? 0 : HDA_AMP_MUTE;
1213         snd_hda_codec_amp_stereo(codec, 0x13, HDA_OUTPUT, 0,
1214                                  HDA_AMP_MUTE, bits);
1215         return 1;
1216 }
1217
1218 /* mute internal speaker if HP is plugged */
1219 static void cxt5047_hp_automute(struct hda_codec *codec)
1220 {
1221         struct conexant_spec *spec = codec->spec;
1222         unsigned int bits;
1223
1224         spec->hp_present = snd_hda_codec_read(codec, 0x13, 0,
1225                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1226
1227         bits = (spec->hp_present || !spec->cur_eapd) ? HDA_AMP_MUTE : 0;
1228         snd_hda_codec_amp_stereo(codec, 0x1d, HDA_OUTPUT, 0,
1229                                  HDA_AMP_MUTE, bits);
1230         /* Mute/Unmute PCM 2 for good measure - some systems need this */
1231         snd_hda_codec_amp_stereo(codec, 0x1c, HDA_OUTPUT, 0,
1232                                  HDA_AMP_MUTE, bits);
1233 }
1234
1235 /* mute internal speaker if HP is plugged */
1236 static void cxt5047_hp2_automute(struct hda_codec *codec)
1237 {
1238         struct conexant_spec *spec = codec->spec;
1239         unsigned int bits;
1240
1241         spec->hp_present = snd_hda_codec_read(codec, 0x13, 0,
1242                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1243
1244         bits = spec->hp_present ? HDA_AMP_MUTE : 0;
1245         snd_hda_codec_amp_stereo(codec, 0x1d, HDA_OUTPUT, 0,
1246                                  HDA_AMP_MUTE, bits);
1247         /* Mute/Unmute PCM 2 for good measure - some systems need this */
1248         snd_hda_codec_amp_stereo(codec, 0x1c, HDA_OUTPUT, 0,
1249                                  HDA_AMP_MUTE, bits);
1250 }
1251
1252 /* toggle input of built-in and mic jack appropriately */
1253 static void cxt5047_hp_automic(struct hda_codec *codec)
1254 {
1255         static struct hda_verb mic_jack_on[] = {
1256                 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1257                 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1258                 {}
1259         };
1260         static struct hda_verb mic_jack_off[] = {
1261                 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1262                 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1263                 {}
1264         };
1265         unsigned int present;
1266
1267         present = snd_hda_codec_read(codec, 0x15, 0,
1268                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1269         if (present)
1270                 snd_hda_sequence_write(codec, mic_jack_on);
1271         else
1272                 snd_hda_sequence_write(codec, mic_jack_off);
1273 }
1274
1275 /* unsolicited event for HP jack sensing */
1276 static void cxt5047_hp_unsol_event(struct hda_codec *codec,
1277                                   unsigned int res)
1278 {
1279         switch (res >> 26) {
1280         case CONEXANT_HP_EVENT:
1281                 cxt5047_hp_automute(codec);
1282                 break;
1283         case CONEXANT_MIC_EVENT:
1284                 cxt5047_hp_automic(codec);
1285                 break;
1286         }
1287 }
1288
1289 /* unsolicited event for HP jack sensing - non-EAPD systems */
1290 static void cxt5047_hp2_unsol_event(struct hda_codec *codec,
1291                                   unsigned int res)
1292 {
1293         res >>= 26;
1294         switch (res) {
1295         case CONEXANT_HP_EVENT:
1296                 cxt5047_hp2_automute(codec);
1297                 break;
1298         case CONEXANT_MIC_EVENT:
1299                 cxt5047_hp_automic(codec);
1300                 break;
1301         }
1302 }
1303
1304 static struct snd_kcontrol_new cxt5047_mixers[] = {
1305         HDA_CODEC_VOLUME("Mic Bypass Capture Volume", 0x19, 0x02, HDA_INPUT),
1306         HDA_CODEC_MUTE("Mic Bypass Capture Switch", 0x19, 0x02, HDA_INPUT),
1307         HDA_CODEC_VOLUME("Mic Gain Volume", 0x1a, 0x0, HDA_OUTPUT),
1308         HDA_CODEC_MUTE("Mic Gain Switch", 0x1a, 0x0, HDA_OUTPUT),
1309         HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x03, HDA_INPUT),
1310         HDA_CODEC_MUTE("Capture Switch", 0x12, 0x03, HDA_INPUT),
1311         HDA_CODEC_VOLUME("PCM Volume", 0x10, 0x00, HDA_OUTPUT),
1312         HDA_CODEC_MUTE("PCM Switch", 0x10, 0x00, HDA_OUTPUT),
1313         HDA_CODEC_VOLUME("PCM-2 Volume", 0x1c, 0x00, HDA_OUTPUT),
1314         HDA_CODEC_MUTE("PCM-2 Switch", 0x1c, 0x00, HDA_OUTPUT),
1315         HDA_CODEC_VOLUME("Speaker Playback Volume", 0x1d, 0x00, HDA_OUTPUT),
1316         HDA_CODEC_MUTE("Speaker Playback Switch", 0x1d, 0x00, HDA_OUTPUT),
1317         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x13, 0x00, HDA_OUTPUT),
1318         HDA_CODEC_MUTE("Headphone Playback Switch", 0x13, 0x00, HDA_OUTPUT),
1319
1320         {}
1321 };
1322
1323 static struct snd_kcontrol_new cxt5047_toshiba_mixers[] = {
1324         {
1325                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1326                 .name = "Capture Source",
1327                 .info = conexant_mux_enum_info,
1328                 .get = conexant_mux_enum_get,
1329                 .put = conexant_mux_enum_put
1330         },
1331         HDA_CODEC_VOLUME("Mic Bypass Capture Volume", 0x19, 0x02, HDA_INPUT),
1332         HDA_CODEC_MUTE("Mic Bypass Capture Switch", 0x19, 0x02, HDA_INPUT),
1333         HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x03, HDA_INPUT),
1334         HDA_CODEC_MUTE("Capture Switch", 0x12, 0x03, HDA_INPUT),
1335         HDA_CODEC_VOLUME("PCM Volume", 0x10, 0x00, HDA_OUTPUT),
1336         HDA_CODEC_MUTE("PCM Switch", 0x10, 0x00, HDA_OUTPUT),
1337         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x13, 0x00, HDA_OUTPUT),
1338         HDA_CODEC_VOLUME("Speaker Playback Volume", 0x1d, 0x00, HDA_OUTPUT),
1339         {
1340                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1341                 .name = "Master Playback Switch",
1342                 .info = cxt_eapd_info,
1343                 .get = cxt_eapd_get,
1344                 .put = cxt5047_hp_master_sw_put,
1345                 .private_value = 0x13,
1346         },
1347
1348         {}
1349 };
1350
1351 static struct snd_kcontrol_new cxt5047_hp_mixers[] = {
1352         {
1353                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1354                 .name = "Capture Source",
1355                 .info = conexant_mux_enum_info,
1356                 .get = conexant_mux_enum_get,
1357                 .put = conexant_mux_enum_put
1358         },
1359         HDA_CODEC_VOLUME("Mic Bypass Capture Volume", 0x19, 0x02, HDA_INPUT),
1360         HDA_CODEC_MUTE("Mic Bypass Capture Switch", 0x19,0x02,HDA_INPUT),
1361         HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x03, HDA_INPUT),
1362         HDA_CODEC_MUTE("Capture Switch", 0x12, 0x03, HDA_INPUT),
1363         HDA_CODEC_VOLUME("PCM Volume", 0x10, 0x00, HDA_OUTPUT),
1364         HDA_CODEC_MUTE("PCM Switch", 0x10, 0x00, HDA_OUTPUT),
1365         HDA_CODEC_VOLUME("Master Playback Volume", 0x13, 0x00, HDA_OUTPUT),
1366         {
1367                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1368                 .name = "Master Playback Switch",
1369                 .info = cxt_eapd_info,
1370                 .get = cxt_eapd_get,
1371                 .put = cxt5047_hp_master_sw_put,
1372                 .private_value = 0x13,
1373         },
1374         { } /* end */
1375 };
1376
1377 static struct hda_verb cxt5047_init_verbs[] = {
1378         /* Line in, Mic, Built-in Mic */
1379         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1380         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_50 },
1381         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_50 },
1382         /* HP, Speaker  */
1383         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
1384         {0x13, AC_VERB_SET_CONNECT_SEL,0x1},
1385         {0x1d, AC_VERB_SET_CONNECT_SEL,0x0},
1386         /* Record selector: Mic */
1387         {0x12, AC_VERB_SET_CONNECT_SEL,0x03},
1388         {0x19, AC_VERB_SET_AMP_GAIN_MUTE,
1389          AC_AMP_SET_INPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x17},
1390         {0x1A, AC_VERB_SET_CONNECT_SEL,0x02},
1391         {0x1A, AC_VERB_SET_AMP_GAIN_MUTE,
1392          AC_AMP_SET_OUTPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x00},
1393         {0x1A, AC_VERB_SET_AMP_GAIN_MUTE,
1394          AC_AMP_SET_OUTPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x03},
1395         /* SPDIF route: PCM */
1396         { 0x18, AC_VERB_SET_CONNECT_SEL, 0x0 },
1397         /* Enable unsolicited events */
1398         {0x13, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT},
1399         {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT},
1400         { } /* end */
1401 };
1402
1403 /* configuration for Toshiba Laptops */
1404 static struct hda_verb cxt5047_toshiba_init_verbs[] = {
1405         {0x13, AC_VERB_SET_EAPD_BTLENABLE, 0x0 }, /* default on */
1406         /* pin sensing on HP and Mic jacks */
1407         {0x13, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT},
1408         {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT},
1409         /* Speaker routing */
1410         {0x1d, AC_VERB_SET_CONNECT_SEL,0x1},
1411         {}
1412 };
1413
1414 /* configuration for HP Laptops */
1415 static struct hda_verb cxt5047_hp_init_verbs[] = {
1416         /* pin sensing on HP jack */
1417         {0x13, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT},
1418         /* 0x13 is actually shared by both HP and speaker;
1419          * setting the connection to 0 (=0x19) makes the master volume control
1420          * working mysteriouslly...
1421          */
1422         {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
1423         /* Record selector: Ext Mic */
1424         {0x12, AC_VERB_SET_CONNECT_SEL,0x03},
1425         {0x19, AC_VERB_SET_AMP_GAIN_MUTE,
1426          AC_AMP_SET_INPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x17},
1427         /* Speaker routing */
1428         {0x1d, AC_VERB_SET_CONNECT_SEL,0x1},
1429         {}
1430 };
1431
1432 /* Test configuration for debugging, modelled after the ALC260 test
1433  * configuration.
1434  */
1435 #ifdef CONFIG_SND_DEBUG
1436 static struct hda_input_mux cxt5047_test_capture_source = {
1437         .num_items = 4,
1438         .items = {
1439                 { "LINE1 pin", 0x0 },
1440                 { "MIC1 pin", 0x1 },
1441                 { "MIC2 pin", 0x2 },
1442                 { "CD pin", 0x3 },
1443         },
1444 };
1445
1446 static struct snd_kcontrol_new cxt5047_test_mixer[] = {
1447
1448         /* Output only controls */
1449         HDA_CODEC_VOLUME("OutAmp-1 Volume", 0x10, 0x0, HDA_OUTPUT),
1450         HDA_CODEC_MUTE("OutAmp-1 Switch", 0x10,0x0, HDA_OUTPUT),
1451         HDA_CODEC_VOLUME("OutAmp-2 Volume", 0x1c, 0x0, HDA_OUTPUT),
1452         HDA_CODEC_MUTE("OutAmp-2 Switch", 0x1c, 0x0, HDA_OUTPUT),
1453         HDA_CODEC_VOLUME("Speaker Playback Volume", 0x1d, 0x0, HDA_OUTPUT),
1454         HDA_CODEC_MUTE("Speaker Playback Switch", 0x1d, 0x0, HDA_OUTPUT),
1455         HDA_CODEC_VOLUME("HeadPhone Playback Volume", 0x13, 0x0, HDA_OUTPUT),
1456         HDA_CODEC_MUTE("HeadPhone Playback Switch", 0x13, 0x0, HDA_OUTPUT),
1457         HDA_CODEC_VOLUME("Line1-Out Playback Volume", 0x14, 0x0, HDA_OUTPUT),
1458         HDA_CODEC_MUTE("Line1-Out Playback Switch", 0x14, 0x0, HDA_OUTPUT),
1459         HDA_CODEC_VOLUME("Line2-Out Playback Volume", 0x15, 0x0, HDA_OUTPUT),
1460         HDA_CODEC_MUTE("Line2-Out Playback Switch", 0x15, 0x0, HDA_OUTPUT),
1461
1462         /* Modes for retasking pin widgets */
1463         CXT_PIN_MODE("LINE1 pin mode", 0x14, CXT_PIN_DIR_INOUT),
1464         CXT_PIN_MODE("MIC1 pin mode", 0x15, CXT_PIN_DIR_INOUT),
1465
1466         /* EAPD Switch Control */
1467         CXT_EAPD_SWITCH("External Amplifier", 0x13, 0x0),
1468
1469         /* Loopback mixer controls */
1470         HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x12, 0x01, HDA_INPUT),
1471         HDA_CODEC_MUTE("MIC1 Playback Switch", 0x12, 0x01, HDA_INPUT),
1472         HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x12, 0x02, HDA_INPUT),
1473         HDA_CODEC_MUTE("MIC2 Playback Switch", 0x12, 0x02, HDA_INPUT),
1474         HDA_CODEC_VOLUME("LINE Playback Volume", 0x12, 0x0, HDA_INPUT),
1475         HDA_CODEC_MUTE("LINE Playback Switch", 0x12, 0x0, HDA_INPUT),
1476         HDA_CODEC_VOLUME("CD Playback Volume", 0x12, 0x04, HDA_INPUT),
1477         HDA_CODEC_MUTE("CD Playback Switch", 0x12, 0x04, HDA_INPUT),
1478
1479         HDA_CODEC_VOLUME("Capture-1 Volume", 0x19, 0x0, HDA_INPUT),
1480         HDA_CODEC_MUTE("Capture-1 Switch", 0x19, 0x0, HDA_INPUT),
1481         HDA_CODEC_VOLUME("Capture-2 Volume", 0x19, 0x1, HDA_INPUT),
1482         HDA_CODEC_MUTE("Capture-2 Switch", 0x19, 0x1, HDA_INPUT),
1483         HDA_CODEC_VOLUME("Capture-3 Volume", 0x19, 0x2, HDA_INPUT),
1484         HDA_CODEC_MUTE("Capture-3 Switch", 0x19, 0x2, HDA_INPUT),
1485         HDA_CODEC_VOLUME("Capture-4 Volume", 0x19, 0x3, HDA_INPUT),
1486         HDA_CODEC_MUTE("Capture-4 Switch", 0x19, 0x3, HDA_INPUT),
1487         {
1488                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1489                 .name = "Input Source",
1490                 .info = conexant_mux_enum_info,
1491                 .get = conexant_mux_enum_get,
1492                 .put = conexant_mux_enum_put,
1493         },
1494         HDA_CODEC_VOLUME("Input-1 Volume", 0x1a, 0x0, HDA_INPUT),
1495         HDA_CODEC_MUTE("Input-1 Switch", 0x1a, 0x0, HDA_INPUT),
1496         HDA_CODEC_VOLUME("Input-2 Volume", 0x1a, 0x1, HDA_INPUT),
1497         HDA_CODEC_MUTE("Input-2 Switch", 0x1a, 0x1, HDA_INPUT),
1498         HDA_CODEC_VOLUME("Input-3 Volume", 0x1a, 0x2, HDA_INPUT),
1499         HDA_CODEC_MUTE("Input-3 Switch", 0x1a, 0x2, HDA_INPUT),
1500         HDA_CODEC_VOLUME("Input-4 Volume", 0x1a, 0x3, HDA_INPUT),
1501         HDA_CODEC_MUTE("Input-4 Switch", 0x1a, 0x3, HDA_INPUT),
1502         HDA_CODEC_VOLUME("Input-5 Volume", 0x1a, 0x4, HDA_INPUT),
1503         HDA_CODEC_MUTE("Input-5 Switch", 0x1a, 0x4, HDA_INPUT),
1504
1505         { } /* end */
1506 };
1507
1508 static struct hda_verb cxt5047_test_init_verbs[] = {
1509         /* Enable retasking pins as output, initially without power amp */
1510         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1511         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1512         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1513
1514         /* Disable digital (SPDIF) pins initially, but users can enable
1515          * them via a mixer switch.  In the case of SPDIF-out, this initverb
1516          * payload also sets the generation to 0, output to be in "consumer"
1517          * PCM format, copyright asserted, no pre-emphasis and no validity
1518          * control.
1519          */
1520         {0x18, AC_VERB_SET_DIGI_CONVERT_1, 0},
1521
1522         /* Ensure mic1, mic2, line1 pin widgets take input from the 
1523          * OUT1 sum bus when acting as an output.
1524          */
1525         {0x1a, AC_VERB_SET_CONNECT_SEL, 0},
1526         {0x1b, AC_VERB_SET_CONNECT_SEL, 0},
1527
1528         /* Start with output sum widgets muted and their output gains at min */
1529         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1530         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1531
1532         /* Unmute retasking pin widget output buffers since the default
1533          * state appears to be output.  As the pin mode is changed by the
1534          * user the pin mode control will take care of enabling the pin's
1535          * input/output buffers as needed.
1536          */
1537         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1538         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1539         {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1540
1541         /* Mute capture amp left and right */
1542         {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1543
1544         /* Set ADC connection select to match default mixer setting (mic1
1545          * pin)
1546          */
1547         {0x12, AC_VERB_SET_CONNECT_SEL, 0x00},
1548
1549         /* Mute all inputs to mixer widget (even unconnected ones) */
1550         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
1551         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
1552         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
1553         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
1554         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
1555         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
1556         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
1557         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
1558
1559         { }
1560 };
1561 #endif
1562
1563
1564 /* initialize jack-sensing, too */
1565 static int cxt5047_hp_init(struct hda_codec *codec)
1566 {
1567         conexant_init(codec);
1568         cxt5047_hp_automute(codec);
1569         return 0;
1570 }
1571
1572
1573 enum {
1574         CXT5047_LAPTOP,         /* Laptops w/o EAPD support */
1575         CXT5047_LAPTOP_HP,      /* Some HP laptops */
1576         CXT5047_LAPTOP_EAPD,    /* Laptops with EAPD support */
1577 #ifdef CONFIG_SND_DEBUG
1578         CXT5047_TEST,
1579 #endif
1580         CXT5047_MODELS
1581 };
1582
1583 static const char *cxt5047_models[CXT5047_MODELS] = {
1584         [CXT5047_LAPTOP]        = "laptop",
1585         [CXT5047_LAPTOP_HP]     = "laptop-hp",
1586         [CXT5047_LAPTOP_EAPD]   = "laptop-eapd",
1587 #ifdef CONFIG_SND_DEBUG
1588         [CXT5047_TEST]          = "test",
1589 #endif
1590 };
1591
1592 static struct snd_pci_quirk cxt5047_cfg_tbl[] = {
1593         SND_PCI_QUIRK(0x103c, 0x30a5, "HP DV5200T/DV8000T", CXT5047_LAPTOP_HP),
1594         SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3000, "HP DV Series",
1595                            CXT5047_LAPTOP),
1596         SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba P100", CXT5047_LAPTOP_EAPD),
1597         {}
1598 };
1599
1600 static int patch_cxt5047(struct hda_codec *codec)
1601 {
1602         struct conexant_spec *spec;
1603         int board_config;
1604
1605         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1606         if (!spec)
1607                 return -ENOMEM;
1608         codec->spec = spec;
1609
1610         spec->multiout.max_channels = 2;
1611         spec->multiout.num_dacs = ARRAY_SIZE(cxt5047_dac_nids);
1612         spec->multiout.dac_nids = cxt5047_dac_nids;
1613         spec->multiout.dig_out_nid = CXT5047_SPDIF_OUT;
1614         spec->num_adc_nids = 1;
1615         spec->adc_nids = cxt5047_adc_nids;
1616         spec->capsrc_nids = cxt5047_capsrc_nids;
1617         spec->input_mux = &cxt5047_capture_source;
1618         spec->num_mixers = 1;
1619         spec->mixers[0] = cxt5047_mixers;
1620         spec->num_init_verbs = 1;
1621         spec->init_verbs[0] = cxt5047_init_verbs;
1622         spec->spdif_route = 0;
1623         spec->num_channel_mode = ARRAY_SIZE(cxt5047_modes),
1624         spec->channel_mode = cxt5047_modes,
1625
1626         codec->patch_ops = conexant_patch_ops;
1627
1628         board_config = snd_hda_check_board_config(codec, CXT5047_MODELS,
1629                                                   cxt5047_models,
1630                                                   cxt5047_cfg_tbl);
1631         switch (board_config) {
1632         case CXT5047_LAPTOP:
1633                 codec->patch_ops.unsol_event = cxt5047_hp2_unsol_event;
1634                 break;
1635         case CXT5047_LAPTOP_HP:
1636                 spec->input_mux = &cxt5047_hp_capture_source;
1637                 spec->num_init_verbs = 2;
1638                 spec->init_verbs[1] = cxt5047_hp_init_verbs;
1639                 spec->mixers[0] = cxt5047_hp_mixers;
1640                 codec->patch_ops.unsol_event = cxt5047_hp_unsol_event;
1641                 codec->patch_ops.init = cxt5047_hp_init;
1642                 break;
1643         case CXT5047_LAPTOP_EAPD:
1644                 spec->input_mux = &cxt5047_toshiba_capture_source;
1645                 spec->num_init_verbs = 2;
1646                 spec->init_verbs[1] = cxt5047_toshiba_init_verbs;
1647                 spec->mixers[0] = cxt5047_toshiba_mixers;
1648                 codec->patch_ops.unsol_event = cxt5047_hp_unsol_event;
1649                 break;
1650 #ifdef CONFIG_SND_DEBUG
1651         case CXT5047_TEST:
1652                 spec->input_mux = &cxt5047_test_capture_source;
1653                 spec->mixers[0] = cxt5047_test_mixer;
1654                 spec->init_verbs[0] = cxt5047_test_init_verbs;
1655                 codec->patch_ops.unsol_event = cxt5047_hp_unsol_event;
1656 #endif  
1657         }
1658         spec->vmaster_nid = 0x13;
1659         return 0;
1660 }
1661
1662 /* Conexant 5051 specific */
1663 static hda_nid_t cxt5051_dac_nids[1] = { 0x10 };
1664 static hda_nid_t cxt5051_adc_nids[2] = { 0x14, 0x15 };
1665
1666 static struct hda_channel_mode cxt5051_modes[1] = {
1667         { 2, NULL },
1668 };
1669
1670 static void cxt5051_update_speaker(struct hda_codec *codec)
1671 {
1672         struct conexant_spec *spec = codec->spec;
1673         unsigned int pinctl;
1674         pinctl = (!spec->hp_present && spec->cur_eapd) ? PIN_OUT : 0;
1675         snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
1676                             pinctl);
1677 }
1678
1679 /* turn on/off EAPD (+ mute HP) as a master switch */
1680 static int cxt5051_hp_master_sw_put(struct snd_kcontrol *kcontrol,
1681                                     struct snd_ctl_elem_value *ucontrol)
1682 {
1683         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1684
1685         if (!cxt_eapd_put(kcontrol, ucontrol))
1686                 return 0;
1687         cxt5051_update_speaker(codec);
1688         return 1;
1689 }
1690
1691 /* toggle input of built-in and mic jack appropriately */
1692 static void cxt5051_portb_automic(struct hda_codec *codec)
1693 {
1694         struct conexant_spec *spec = codec->spec;
1695         unsigned int present;
1696
1697         if (spec->no_auto_mic)
1698                 return;
1699         present = snd_hda_codec_read(codec, 0x17, 0,
1700                                      AC_VERB_GET_PIN_SENSE, 0) &
1701                 AC_PINSENSE_PRESENCE;
1702         snd_hda_codec_write(codec, 0x14, 0,
1703                             AC_VERB_SET_CONNECT_SEL,
1704                             present ? 0x01 : 0x00);
1705 }
1706
1707 /* switch the current ADC according to the jack state */
1708 static void cxt5051_portc_automic(struct hda_codec *codec)
1709 {
1710         struct conexant_spec *spec = codec->spec;
1711         unsigned int present;
1712         hda_nid_t new_adc;
1713
1714         if (spec->no_auto_mic)
1715                 return;
1716         present = snd_hda_codec_read(codec, 0x18, 0,
1717                                      AC_VERB_GET_PIN_SENSE, 0) &
1718                 AC_PINSENSE_PRESENCE;
1719         if (present)
1720                 spec->cur_adc_idx = 1;
1721         else
1722                 spec->cur_adc_idx = 0;
1723         new_adc = spec->adc_nids[spec->cur_adc_idx];
1724         if (spec->cur_adc && spec->cur_adc != new_adc) {
1725                 /* stream is running, let's swap the current ADC */
1726                 snd_hda_codec_cleanup_stream(codec, spec->cur_adc);
1727                 spec->cur_adc = new_adc;
1728                 snd_hda_codec_setup_stream(codec, new_adc,
1729                                            spec->cur_adc_stream_tag, 0,
1730                                            spec->cur_adc_format);
1731         }
1732 }
1733
1734 /* mute internal speaker if HP is plugged */
1735 static void cxt5051_hp_automute(struct hda_codec *codec)
1736 {
1737         struct conexant_spec *spec = codec->spec;
1738
1739         spec->hp_present = snd_hda_codec_read(codec, 0x16, 0,
1740                                      AC_VERB_GET_PIN_SENSE, 0) &
1741                 AC_PINSENSE_PRESENCE;
1742         cxt5051_update_speaker(codec);
1743 }
1744
1745 /* unsolicited event for HP jack sensing */
1746 static void cxt5051_hp_unsol_event(struct hda_codec *codec,
1747                                    unsigned int res)
1748 {
1749         int nid = (res & AC_UNSOL_RES_SUBTAG) >> 20;
1750         switch (res >> 26) {
1751         case CONEXANT_HP_EVENT:
1752                 cxt5051_hp_automute(codec);
1753                 break;
1754         case CXT5051_PORTB_EVENT:
1755                 cxt5051_portb_automic(codec);
1756                 break;
1757         case CXT5051_PORTC_EVENT:
1758                 cxt5051_portc_automic(codec);
1759                 break;
1760         }
1761         conexant_report_jack(codec, nid);
1762 }
1763
1764 static struct snd_kcontrol_new cxt5051_mixers[] = {
1765         HDA_CODEC_VOLUME("Internal Mic Volume", 0x14, 0x00, HDA_INPUT),
1766         HDA_CODEC_MUTE("Internal Mic Switch", 0x14, 0x00, HDA_INPUT),
1767         HDA_CODEC_VOLUME("External Mic Volume", 0x14, 0x01, HDA_INPUT),
1768         HDA_CODEC_MUTE("External Mic Switch", 0x14, 0x01, HDA_INPUT),
1769         HDA_CODEC_VOLUME("Docking Mic Volume", 0x15, 0x00, HDA_INPUT),
1770         HDA_CODEC_MUTE("Docking Mic Switch", 0x15, 0x00, HDA_INPUT),
1771         HDA_CODEC_VOLUME("Master Playback Volume", 0x10, 0x00, HDA_OUTPUT),
1772         {
1773                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1774                 .name = "Master Playback Switch",
1775                 .info = cxt_eapd_info,
1776                 .get = cxt_eapd_get,
1777                 .put = cxt5051_hp_master_sw_put,
1778                 .private_value = 0x1a,
1779         },
1780
1781         {}
1782 };
1783
1784 static struct snd_kcontrol_new cxt5051_hp_mixers[] = {
1785         HDA_CODEC_VOLUME("Internal Mic Volume", 0x14, 0x00, HDA_INPUT),
1786         HDA_CODEC_MUTE("Internal Mic Switch", 0x14, 0x00, HDA_INPUT),
1787         HDA_CODEC_VOLUME("External Mic Volume", 0x15, 0x00, HDA_INPUT),
1788         HDA_CODEC_MUTE("External Mic Switch", 0x15, 0x00, HDA_INPUT),
1789         HDA_CODEC_VOLUME("Master Playback Volume", 0x10, 0x00, HDA_OUTPUT),
1790         {
1791                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1792                 .name = "Master Playback Switch",
1793                 .info = cxt_eapd_info,
1794                 .get = cxt_eapd_get,
1795                 .put = cxt5051_hp_master_sw_put,
1796                 .private_value = 0x1a,
1797         },
1798
1799         {}
1800 };
1801
1802 static struct snd_kcontrol_new cxt5051_hp_dv6736_mixers[] = {
1803         HDA_CODEC_VOLUME("Mic Volume", 0x14, 0x00, HDA_INPUT),
1804         HDA_CODEC_MUTE("Mic Switch", 0x14, 0x00, HDA_INPUT),
1805         HDA_CODEC_VOLUME("Master Playback Volume", 0x10, 0x00, HDA_OUTPUT),
1806         {
1807                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1808                 .name = "Master Playback Switch",
1809                 .info = cxt_eapd_info,
1810                 .get = cxt_eapd_get,
1811                 .put = cxt5051_hp_master_sw_put,
1812                 .private_value = 0x1a,
1813         },
1814
1815         {}
1816 };
1817
1818 static struct hda_verb cxt5051_init_verbs[] = {
1819         /* Line in, Mic */
1820         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03},
1821         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1822         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03},
1823         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1824         {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1825         {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03},
1826         /* SPK  */
1827         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1828         {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
1829         /* HP, Amp  */
1830         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1831         {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
1832         /* DAC1 */      
1833         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1834         /* Record selector: Int mic */
1835         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x44},
1836         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1) | 0x44},
1837         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x44},
1838         /* SPDIF route: PCM */
1839         {0x1c, AC_VERB_SET_CONNECT_SEL, 0x0},
1840         /* EAPD */
1841         {0x1a, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */ 
1842         {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CONEXANT_HP_EVENT},
1843         {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CXT5051_PORTB_EVENT},
1844         {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CXT5051_PORTC_EVENT},
1845         { } /* end */
1846 };
1847
1848 static struct hda_verb cxt5051_hp_dv6736_init_verbs[] = {
1849         /* Line in, Mic */
1850         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03},
1851         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1852         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0},
1853         {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0},
1854         /* SPK  */
1855         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1856         {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
1857         /* HP, Amp  */
1858         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1859         {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
1860         /* DAC1 */
1861         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1862         /* Record selector: Int mic */
1863         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1) | 0x44},
1864         {0x14, AC_VERB_SET_CONNECT_SEL, 0x1},
1865         /* SPDIF route: PCM */
1866         {0x1c, AC_VERB_SET_CONNECT_SEL, 0x0},
1867         /* EAPD */
1868         {0x1a, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
1869         {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CONEXANT_HP_EVENT},
1870         {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CXT5051_PORTB_EVENT},
1871         { } /* end */
1872 };
1873
1874 static struct hda_verb cxt5051_lenovo_x200_init_verbs[] = {
1875         /* Line in, Mic */
1876         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03},
1877         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1878         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03},
1879         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1880         {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1881         {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03},
1882         /* SPK  */
1883         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1884         {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
1885         /* HP, Amp  */
1886         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1887         {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
1888         /* Docking HP */
1889         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1890         {0x19, AC_VERB_SET_CONNECT_SEL, 0x00},
1891         /* DAC1 */
1892         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1893         /* Record selector: Int mic */
1894         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x44},
1895         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1) | 0x44},
1896         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x44},
1897         /* SPDIF route: PCM */
1898         {0x1c, AC_VERB_SET_CONNECT_SEL, 0x0},
1899         /* EAPD */
1900         {0x1a, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
1901         {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CONEXANT_HP_EVENT},
1902         {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CXT5051_PORTB_EVENT},
1903         {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CXT5051_PORTC_EVENT},
1904         {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CONEXANT_HP_EVENT},
1905         { } /* end */
1906 };
1907
1908 /* initialize jack-sensing, too */
1909 static int cxt5051_init(struct hda_codec *codec)
1910 {
1911         conexant_init(codec);
1912         conexant_init_jacks(codec);
1913         if (codec->patch_ops.unsol_event) {
1914                 cxt5051_hp_automute(codec);
1915                 cxt5051_portb_automic(codec);
1916                 cxt5051_portc_automic(codec);
1917         }
1918         return 0;
1919 }
1920
1921
1922 enum {
1923         CXT5051_LAPTOP,  /* Laptops w/ EAPD support */
1924         CXT5051_HP,     /* no docking */
1925         CXT5051_HP_DV6736,      /* HP without mic switch */
1926         CXT5051_LENOVO_X200,    /* Lenovo X200 laptop */
1927         CXT5051_MODELS
1928 };
1929
1930 static const char *cxt5051_models[CXT5051_MODELS] = {
1931         [CXT5051_LAPTOP]        = "laptop",
1932         [CXT5051_HP]            = "hp",
1933         [CXT5051_HP_DV6736]     = "hp-dv6736",
1934         [CXT5051_LENOVO_X200]   = "lenovo-x200",
1935 };
1936
1937 static struct snd_pci_quirk cxt5051_cfg_tbl[] = {
1938         SND_PCI_QUIRK(0x103c, 0x30cf, "HP DV6736", CXT5051_HP_DV6736),
1939         SND_PCI_QUIRK(0x14f1, 0x0101, "Conexant Reference board",
1940                       CXT5051_LAPTOP),
1941         SND_PCI_QUIRK(0x14f1, 0x5051, "HP Spartan 1.1", CXT5051_HP),
1942         SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo X200", CXT5051_LENOVO_X200),
1943         {}
1944 };
1945
1946 static int patch_cxt5051(struct hda_codec *codec)
1947 {
1948         struct conexant_spec *spec;
1949         int board_config;
1950
1951         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1952         if (!spec)
1953                 return -ENOMEM;
1954         codec->spec = spec;
1955
1956         codec->patch_ops = conexant_patch_ops;
1957         codec->patch_ops.init = cxt5051_init;
1958
1959         spec->multiout.max_channels = 2;
1960         spec->multiout.num_dacs = ARRAY_SIZE(cxt5051_dac_nids);
1961         spec->multiout.dac_nids = cxt5051_dac_nids;
1962         spec->multiout.dig_out_nid = CXT5051_SPDIF_OUT;
1963         spec->num_adc_nids = 1; /* not 2; via auto-mic switch */
1964         spec->adc_nids = cxt5051_adc_nids;
1965         spec->num_mixers = 1;
1966         spec->mixers[0] = cxt5051_mixers;
1967         spec->num_init_verbs = 1;
1968         spec->init_verbs[0] = cxt5051_init_verbs;
1969         spec->spdif_route = 0;
1970         spec->num_channel_mode = ARRAY_SIZE(cxt5051_modes);
1971         spec->channel_mode = cxt5051_modes;
1972         spec->cur_adc = 0;
1973         spec->cur_adc_idx = 0;
1974
1975         codec->patch_ops.unsol_event = cxt5051_hp_unsol_event;
1976
1977         board_config = snd_hda_check_board_config(codec, CXT5051_MODELS,
1978                                                   cxt5051_models,
1979                                                   cxt5051_cfg_tbl);
1980         switch (board_config) {
1981         case CXT5051_HP:
1982                 spec->mixers[0] = cxt5051_hp_mixers;
1983                 break;
1984         case CXT5051_HP_DV6736:
1985                 spec->init_verbs[0] = cxt5051_hp_dv6736_init_verbs;
1986                 spec->mixers[0] = cxt5051_hp_dv6736_mixers;
1987                 spec->no_auto_mic = 1;
1988                 break;
1989         case CXT5051_LENOVO_X200:
1990                 spec->init_verbs[0] = cxt5051_lenovo_x200_init_verbs;
1991                 break;
1992         }
1993
1994         return 0;
1995 }
1996
1997
1998 /*
1999  */
2000
2001 static struct hda_codec_preset snd_hda_preset_conexant[] = {
2002         { .id = 0x14f15045, .name = "CX20549 (Venice)",
2003           .patch = patch_cxt5045 },
2004         { .id = 0x14f15047, .name = "CX20551 (Waikiki)",
2005           .patch = patch_cxt5047 },
2006         { .id = 0x14f15051, .name = "CX20561 (Hermosa)",
2007           .patch = patch_cxt5051 },
2008         {} /* terminator */
2009 };
2010
2011 MODULE_ALIAS("snd-hda-codec-id:14f15045");
2012 MODULE_ALIAS("snd-hda-codec-id:14f15047");
2013 MODULE_ALIAS("snd-hda-codec-id:14f15051");
2014
2015 MODULE_LICENSE("GPL");
2016 MODULE_DESCRIPTION("Conexant HD-audio codec");
2017
2018 static struct hda_codec_preset_list conexant_list = {
2019         .preset = snd_hda_preset_conexant,
2020         .owner = THIS_MODULE,
2021 };
2022
2023 static int __init patch_conexant_init(void)
2024 {
2025         return snd_hda_add_codec_preset(&conexant_list);
2026 }
2027
2028 static void __exit patch_conexant_exit(void)
2029 {
2030         snd_hda_delete_codec_preset(&conexant_list);
2031 }
2032
2033 module_init(patch_conexant_init)
2034 module_exit(patch_conexant_exit)