]> git.karo-electronics.de Git - mv-sheeva.git/blob - sound/pci/hda/patch_conexant.c
266e5a68bafa54d6924539209b583a548de7d1e6
[mv-sheeva.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 <linux/module.h>
28 #include <sound/core.h>
29 #include <sound/jack.h>
30
31 #include "hda_codec.h"
32 #include "hda_local.h"
33 #include "hda_beep.h"
34 #include "hda_jack.h"
35
36 #define CXT_PIN_DIR_IN              0x00
37 #define CXT_PIN_DIR_OUT             0x01
38 #define CXT_PIN_DIR_INOUT           0x02
39 #define CXT_PIN_DIR_IN_NOMICBIAS    0x03
40 #define CXT_PIN_DIR_INOUT_NOMICBIAS 0x04
41
42 #define CONEXANT_HP_EVENT       0x37
43 #define CONEXANT_MIC_EVENT      0x38
44 #define CONEXANT_LINE_EVENT     0x39
45
46 /* Conexant 5051 specific */
47
48 #define CXT5051_SPDIF_OUT       0x12
49 #define CXT5051_PORTB_EVENT     0x38
50 #define CXT5051_PORTC_EVENT     0x39
51
52 #define AUTO_MIC_PORTB          (1 << 1)
53 #define AUTO_MIC_PORTC          (1 << 2)
54
55 struct pin_dac_pair {
56         hda_nid_t pin;
57         hda_nid_t dac;
58         int type;
59 };
60
61 struct imux_info {
62         hda_nid_t pin;          /* input pin NID */
63         hda_nid_t adc;          /* connected ADC NID */ 
64         hda_nid_t boost;        /* optional boost volume NID */
65         int index;              /* corresponding to autocfg.input */
66 };
67
68 struct conexant_spec {
69
70         const struct snd_kcontrol_new *mixers[5];
71         int num_mixers;
72         hda_nid_t vmaster_nid;
73
74         const struct hda_verb *init_verbs[5];   /* initialization verbs
75                                                  * don't forget NULL
76                                                  * termination!
77                                                  */
78         unsigned int num_init_verbs;
79
80         /* playback */
81         struct hda_multi_out multiout;  /* playback set-up
82                                          * max_channels, dacs must be set
83                                          * dig_out_nid and hp_nid are optional
84                                          */
85         unsigned int cur_eapd;
86         unsigned int hp_present;
87         unsigned int line_present;
88         unsigned int auto_mic;
89         int auto_mic_ext;               /* imux_pins[] index for ext mic */
90         int auto_mic_dock;              /* imux_pins[] index for dock mic */
91         int auto_mic_int;               /* imux_pins[] index for int mic */
92         unsigned int need_dac_fix;
93         hda_nid_t slave_dig_outs[2];
94
95         /* capture */
96         unsigned int num_adc_nids;
97         const hda_nid_t *adc_nids;
98         hda_nid_t dig_in_nid;           /* digital-in NID; optional */
99
100         unsigned int cur_adc_idx;
101         hda_nid_t cur_adc;
102         unsigned int cur_adc_stream_tag;
103         unsigned int cur_adc_format;
104
105         const struct hda_pcm_stream *capture_stream;
106
107         /* capture source */
108         const struct hda_input_mux *input_mux;
109         const hda_nid_t *capsrc_nids;
110         unsigned int cur_mux[3];
111
112         /* channel model */
113         const struct hda_channel_mode *channel_mode;
114         int num_channel_mode;
115
116         /* PCM information */
117         struct hda_pcm pcm_rec[2];      /* used in build_pcms() */
118
119         unsigned int spdif_route;
120
121         /* dynamic controls, init_verbs and input_mux */
122         struct auto_pin_cfg autocfg;
123         struct hda_input_mux private_imux;
124         struct imux_info imux_info[HDA_MAX_NUM_INPUTS];
125         hda_nid_t private_adc_nids[HDA_MAX_NUM_INPUTS];
126         hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
127         struct pin_dac_pair dac_info[8];
128         int dac_info_filled;
129
130         unsigned int port_d_mode;
131         unsigned int auto_mute:1;       /* used in auto-parser */
132         unsigned int detect_line:1;     /* Line-out detection enabled */
133         unsigned int automute_lines:1;  /* automute line-out as well */
134         unsigned int automute_hp_lo:1;  /* both HP and LO available */
135         unsigned int dell_automute:1;
136         unsigned int dell_vostro:1;
137         unsigned int ideapad:1;
138         unsigned int thinkpad:1;
139         unsigned int hp_laptop:1;
140         unsigned int asus:1;
141         unsigned int pin_eapd_ctrls:1;
142         unsigned int single_adc_amp:1;
143
144         unsigned int adc_switching:1;
145
146         unsigned int ext_mic_present;
147         unsigned int recording;
148         void (*capture_prepare)(struct hda_codec *codec);
149         void (*capture_cleanup)(struct hda_codec *codec);
150
151         /* OLPC XO-1.5 supports DC input mode (e.g. for use with analog sensors)
152          * through the microphone jack.
153          * When the user enables this through a mixer switch, both internal and
154          * external microphones are disabled. Gain is fixed at 0dB. In this mode,
155          * we also allow the bias to be configured through a separate mixer
156          * control. */
157         unsigned int dc_enable;
158         unsigned int dc_input_bias; /* offset into cxt5066_olpc_dc_bias */
159         unsigned int mic_boost; /* offset into cxt5066_analog_mic_boost */
160
161         unsigned int beep_amp;
162
163         /* extra EAPD pins */
164         unsigned int num_eapds;
165         hda_nid_t eapds[4];
166 };
167
168 static int conexant_playback_pcm_open(struct hda_pcm_stream *hinfo,
169                                       struct hda_codec *codec,
170                                       struct snd_pcm_substream *substream)
171 {
172         struct conexant_spec *spec = codec->spec;
173         return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
174                                              hinfo);
175 }
176
177 static int conexant_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
178                                          struct hda_codec *codec,
179                                          unsigned int stream_tag,
180                                          unsigned int format,
181                                          struct snd_pcm_substream *substream)
182 {
183         struct conexant_spec *spec = codec->spec;
184         return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
185                                                 stream_tag,
186                                                 format, substream);
187 }
188
189 static int conexant_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
190                                          struct hda_codec *codec,
191                                          struct snd_pcm_substream *substream)
192 {
193         struct conexant_spec *spec = codec->spec;
194         return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
195 }
196
197 /*
198  * Digital out
199  */
200 static int conexant_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
201                                           struct hda_codec *codec,
202                                           struct snd_pcm_substream *substream)
203 {
204         struct conexant_spec *spec = codec->spec;
205         return snd_hda_multi_out_dig_open(codec, &spec->multiout);
206 }
207
208 static int conexant_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
209                                          struct hda_codec *codec,
210                                          struct snd_pcm_substream *substream)
211 {
212         struct conexant_spec *spec = codec->spec;
213         return snd_hda_multi_out_dig_close(codec, &spec->multiout);
214 }
215
216 static int conexant_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
217                                          struct hda_codec *codec,
218                                          unsigned int stream_tag,
219                                          unsigned int format,
220                                          struct snd_pcm_substream *substream)
221 {
222         struct conexant_spec *spec = codec->spec;
223         return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
224                                              stream_tag,
225                                              format, substream);
226 }
227
228 /*
229  * Analog capture
230  */
231 static int conexant_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
232                                       struct hda_codec *codec,
233                                       unsigned int stream_tag,
234                                       unsigned int format,
235                                       struct snd_pcm_substream *substream)
236 {
237         struct conexant_spec *spec = codec->spec;
238         if (spec->capture_prepare)
239                 spec->capture_prepare(codec);
240         snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
241                                    stream_tag, 0, format);
242         return 0;
243 }
244
245 static int conexant_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
246                                       struct hda_codec *codec,
247                                       struct snd_pcm_substream *substream)
248 {
249         struct conexant_spec *spec = codec->spec;
250         snd_hda_codec_cleanup_stream(codec, spec->adc_nids[substream->number]);
251         if (spec->capture_cleanup)
252                 spec->capture_cleanup(codec);
253         return 0;
254 }
255
256
257
258 static const struct hda_pcm_stream conexant_pcm_analog_playback = {
259         .substreams = 1,
260         .channels_min = 2,
261         .channels_max = 2,
262         .nid = 0, /* fill later */
263         .ops = {
264                 .open = conexant_playback_pcm_open,
265                 .prepare = conexant_playback_pcm_prepare,
266                 .cleanup = conexant_playback_pcm_cleanup
267         },
268 };
269
270 static const struct hda_pcm_stream conexant_pcm_analog_capture = {
271         .substreams = 1,
272         .channels_min = 2,
273         .channels_max = 2,
274         .nid = 0, /* fill later */
275         .ops = {
276                 .prepare = conexant_capture_pcm_prepare,
277                 .cleanup = conexant_capture_pcm_cleanup
278         },
279 };
280
281
282 static const struct hda_pcm_stream conexant_pcm_digital_playback = {
283         .substreams = 1,
284         .channels_min = 2,
285         .channels_max = 2,
286         .nid = 0, /* fill later */
287         .ops = {
288                 .open = conexant_dig_playback_pcm_open,
289                 .close = conexant_dig_playback_pcm_close,
290                 .prepare = conexant_dig_playback_pcm_prepare
291         },
292 };
293
294 static const struct hda_pcm_stream conexant_pcm_digital_capture = {
295         .substreams = 1,
296         .channels_min = 2,
297         .channels_max = 2,
298         /* NID is set in alc_build_pcms */
299 };
300
301 static int cx5051_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
302                                       struct hda_codec *codec,
303                                       unsigned int stream_tag,
304                                       unsigned int format,
305                                       struct snd_pcm_substream *substream)
306 {
307         struct conexant_spec *spec = codec->spec;
308         spec->cur_adc = spec->adc_nids[spec->cur_adc_idx];
309         spec->cur_adc_stream_tag = stream_tag;
310         spec->cur_adc_format = format;
311         snd_hda_codec_setup_stream(codec, spec->cur_adc, stream_tag, 0, format);
312         return 0;
313 }
314
315 static int cx5051_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
316                                       struct hda_codec *codec,
317                                       struct snd_pcm_substream *substream)
318 {
319         struct conexant_spec *spec = codec->spec;
320         snd_hda_codec_cleanup_stream(codec, spec->cur_adc);
321         spec->cur_adc = 0;
322         return 0;
323 }
324
325 static const struct hda_pcm_stream cx5051_pcm_analog_capture = {
326         .substreams = 1,
327         .channels_min = 2,
328         .channels_max = 2,
329         .nid = 0, /* fill later */
330         .ops = {
331                 .prepare = cx5051_capture_pcm_prepare,
332                 .cleanup = cx5051_capture_pcm_cleanup
333         },
334 };
335
336 static int conexant_build_pcms(struct hda_codec *codec)
337 {
338         struct conexant_spec *spec = codec->spec;
339         struct hda_pcm *info = spec->pcm_rec;
340
341         codec->num_pcms = 1;
342         codec->pcm_info = info;
343
344         info->name = "CONEXANT Analog";
345         info->stream[SNDRV_PCM_STREAM_PLAYBACK] = conexant_pcm_analog_playback;
346         info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max =
347                 spec->multiout.max_channels;
348         info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
349                 spec->multiout.dac_nids[0];
350         if (spec->capture_stream)
351                 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *spec->capture_stream;
352         else {
353                 if (codec->vendor_id == 0x14f15051)
354                         info->stream[SNDRV_PCM_STREAM_CAPTURE] =
355                                 cx5051_pcm_analog_capture;
356                 else {
357                         info->stream[SNDRV_PCM_STREAM_CAPTURE] =
358                                 conexant_pcm_analog_capture;
359                         info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
360                                 spec->num_adc_nids;
361                 }
362         }
363         info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
364
365         if (spec->multiout.dig_out_nid) {
366                 info++;
367                 codec->num_pcms++;
368                 info->name = "Conexant Digital";
369                 info->pcm_type = HDA_PCM_TYPE_SPDIF;
370                 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
371                         conexant_pcm_digital_playback;
372                 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
373                         spec->multiout.dig_out_nid;
374                 if (spec->dig_in_nid) {
375                         info->stream[SNDRV_PCM_STREAM_CAPTURE] =
376                                 conexant_pcm_digital_capture;
377                         info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
378                                 spec->dig_in_nid;
379                 }
380                 if (spec->slave_dig_outs[0])
381                         codec->slave_dig_outs = spec->slave_dig_outs;
382         }
383
384         return 0;
385 }
386
387 static int conexant_mux_enum_info(struct snd_kcontrol *kcontrol,
388                                   struct snd_ctl_elem_info *uinfo)
389 {
390         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
391         struct conexant_spec *spec = codec->spec;
392
393         return snd_hda_input_mux_info(spec->input_mux, uinfo);
394 }
395
396 static int conexant_mux_enum_get(struct snd_kcontrol *kcontrol,
397                                  struct snd_ctl_elem_value *ucontrol)
398 {
399         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
400         struct conexant_spec *spec = codec->spec;
401         unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
402
403         ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
404         return 0;
405 }
406
407 static int conexant_mux_enum_put(struct snd_kcontrol *kcontrol,
408                                  struct snd_ctl_elem_value *ucontrol)
409 {
410         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
411         struct conexant_spec *spec = codec->spec;
412         unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
413
414         return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol,
415                                      spec->capsrc_nids[adc_idx],
416                                      &spec->cur_mux[adc_idx]);
417 }
418
419 static void conexant_set_power(struct hda_codec *codec, hda_nid_t fg,
420                                unsigned int power_state)
421 {
422         if (power_state == AC_PWRST_D3)
423                 msleep(100);
424         snd_hda_codec_read(codec, fg, 0, AC_VERB_SET_POWER_STATE,
425                             power_state);
426         /* partial workaround for "azx_get_response timeout" */
427         if (power_state == AC_PWRST_D0)
428                 msleep(10);
429         snd_hda_codec_set_power_to_all(codec, fg, power_state, true);
430 }
431
432 static int conexant_init(struct hda_codec *codec)
433 {
434         struct conexant_spec *spec = codec->spec;
435         int i;
436
437         for (i = 0; i < spec->num_init_verbs; i++)
438                 snd_hda_sequence_write(codec, spec->init_verbs[i]);
439         return 0;
440 }
441
442 static void conexant_free(struct hda_codec *codec)
443 {
444         snd_hda_detach_beep_device(codec);
445         kfree(codec->spec);
446 }
447
448 static const struct snd_kcontrol_new cxt_capture_mixers[] = {
449         {
450                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
451                 .name = "Capture Source",
452                 .info = conexant_mux_enum_info,
453                 .get = conexant_mux_enum_get,
454                 .put = conexant_mux_enum_put
455         },
456         {}
457 };
458
459 #ifdef CONFIG_SND_HDA_INPUT_BEEP
460 /* additional beep mixers; the actual parameters are overwritten at build */
461 static const struct snd_kcontrol_new cxt_beep_mixer[] = {
462         HDA_CODEC_VOLUME_MONO("Beep Playback Volume", 0, 1, 0, HDA_OUTPUT),
463         HDA_CODEC_MUTE_BEEP_MONO("Beep Playback Switch", 0, 1, 0, HDA_OUTPUT),
464         { } /* end */
465 };
466 #endif
467
468 static const char * const slave_pfxs[] = {
469         "Headphone", "Speaker", "Front", "Surround", "CLFE",
470         NULL
471 };
472
473 static int conexant_build_controls(struct hda_codec *codec)
474 {
475         struct conexant_spec *spec = codec->spec;
476         unsigned int i;
477         int err;
478
479         for (i = 0; i < spec->num_mixers; i++) {
480                 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
481                 if (err < 0)
482                         return err;
483         }
484         if (spec->multiout.dig_out_nid) {
485                 err = snd_hda_create_spdif_out_ctls(codec,
486                                                     spec->multiout.dig_out_nid,
487                                                     spec->multiout.dig_out_nid);
488                 if (err < 0)
489                         return err;
490                 err = snd_hda_create_spdif_share_sw(codec,
491                                                     &spec->multiout);
492                 if (err < 0)
493                         return err;
494                 spec->multiout.share_spdif = 1;
495         } 
496         if (spec->dig_in_nid) {
497                 err = snd_hda_create_spdif_in_ctls(codec,spec->dig_in_nid);
498                 if (err < 0)
499                         return err;
500         }
501
502         /* if we have no master control, let's create it */
503         if (spec->vmaster_nid &&
504             !snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
505                 unsigned int vmaster_tlv[4];
506                 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
507                                         HDA_OUTPUT, vmaster_tlv);
508                 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
509                                           vmaster_tlv, slave_pfxs,
510                                           "Playback Volume");
511                 if (err < 0)
512                         return err;
513         }
514         if (spec->vmaster_nid &&
515             !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
516                 err = snd_hda_add_vmaster(codec, "Master Playback Switch",
517                                           NULL, slave_pfxs,
518                                           "Playback Switch");
519                 if (err < 0)
520                         return err;
521         }
522
523         if (spec->input_mux) {
524                 err = snd_hda_add_new_ctls(codec, cxt_capture_mixers);
525                 if (err < 0)
526                         return err;
527         }
528
529 #ifdef CONFIG_SND_HDA_INPUT_BEEP
530         /* create beep controls if needed */
531         if (spec->beep_amp) {
532                 const struct snd_kcontrol_new *knew;
533                 for (knew = cxt_beep_mixer; knew->name; knew++) {
534                         struct snd_kcontrol *kctl;
535                         kctl = snd_ctl_new1(knew, codec);
536                         if (!kctl)
537                                 return -ENOMEM;
538                         kctl->private_value = spec->beep_amp;
539                         err = snd_hda_ctl_add(codec, 0, kctl);
540                         if (err < 0)
541                                 return err;
542                 }
543         }
544 #endif
545
546         return 0;
547 }
548
549 #ifdef CONFIG_SND_HDA_POWER_SAVE
550 static int conexant_suspend(struct hda_codec *codec, pm_message_t state)
551 {
552         snd_hda_shutup_pins(codec);
553         return 0;
554 }
555 #endif
556
557 static const struct hda_codec_ops conexant_patch_ops = {
558         .build_controls = conexant_build_controls,
559         .build_pcms = conexant_build_pcms,
560         .init = conexant_init,
561         .free = conexant_free,
562         .set_power_state = conexant_set_power,
563 #ifdef CONFIG_SND_HDA_POWER_SAVE
564         .suspend = conexant_suspend,
565 #endif
566         .reboot_notify = snd_hda_shutup_pins,
567 };
568
569 #ifdef CONFIG_SND_HDA_INPUT_BEEP
570 #define set_beep_amp(spec, nid, idx, dir) \
571         ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 1, idx, dir))
572 #else
573 #define set_beep_amp(spec, nid, idx, dir) /* NOP */
574 #endif
575
576 static int patch_conexant_auto(struct hda_codec *codec);
577 /*
578  * EAPD control
579  * the private value = nid | (invert << 8)
580  */
581
582 #define cxt_eapd_info           snd_ctl_boolean_mono_info
583
584 static int cxt_eapd_get(struct snd_kcontrol *kcontrol,
585                              struct snd_ctl_elem_value *ucontrol)
586 {
587         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
588         struct conexant_spec *spec = codec->spec;
589         int invert = (kcontrol->private_value >> 8) & 1;
590         if (invert)
591                 ucontrol->value.integer.value[0] = !spec->cur_eapd;
592         else
593                 ucontrol->value.integer.value[0] = spec->cur_eapd;
594         return 0;
595
596 }
597
598 static int cxt_eapd_put(struct snd_kcontrol *kcontrol,
599                              struct snd_ctl_elem_value *ucontrol)
600 {
601         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
602         struct conexant_spec *spec = codec->spec;
603         int invert = (kcontrol->private_value >> 8) & 1;
604         hda_nid_t nid = kcontrol->private_value & 0xff;
605         unsigned int eapd;
606
607         eapd = !!ucontrol->value.integer.value[0];
608         if (invert)
609                 eapd = !eapd;
610         if (eapd == spec->cur_eapd)
611                 return 0;
612         
613         spec->cur_eapd = eapd;
614         snd_hda_codec_write_cache(codec, nid,
615                                   0, AC_VERB_SET_EAPD_BTLENABLE,
616                                   eapd ? 0x02 : 0x00);
617         return 1;
618 }
619
620 /* controls for test mode */
621 #ifdef CONFIG_SND_DEBUG
622
623 #define CXT_EAPD_SWITCH(xname, nid, mask) \
624         { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
625           .info = cxt_eapd_info, \
626           .get = cxt_eapd_get, \
627           .put = cxt_eapd_put, \
628           .private_value = nid | (mask<<16) }
629
630
631
632 static int conexant_ch_mode_info(struct snd_kcontrol *kcontrol,
633                                  struct snd_ctl_elem_info *uinfo)
634 {
635         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
636         struct conexant_spec *spec = codec->spec;
637         return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
638                                     spec->num_channel_mode);
639 }
640
641 static int conexant_ch_mode_get(struct snd_kcontrol *kcontrol,
642                                 struct snd_ctl_elem_value *ucontrol)
643 {
644         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
645         struct conexant_spec *spec = codec->spec;
646         return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
647                                    spec->num_channel_mode,
648                                    spec->multiout.max_channels);
649 }
650
651 static int conexant_ch_mode_put(struct snd_kcontrol *kcontrol,
652                                 struct snd_ctl_elem_value *ucontrol)
653 {
654         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
655         struct conexant_spec *spec = codec->spec;
656         int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
657                                       spec->num_channel_mode,
658                                       &spec->multiout.max_channels);
659         if (err >= 0 && spec->need_dac_fix)
660                 spec->multiout.num_dacs = spec->multiout.max_channels / 2;
661         return err;
662 }
663
664 #define CXT_PIN_MODE(xname, nid, dir) \
665         { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
666           .info = conexant_ch_mode_info, \
667           .get = conexant_ch_mode_get, \
668           .put = conexant_ch_mode_put, \
669           .private_value = nid | (dir<<16) }
670
671 #endif /* CONFIG_SND_DEBUG */
672
673 /* Conexant 5045 specific */
674
675 static const hda_nid_t cxt5045_dac_nids[1] = { 0x19 };
676 static const hda_nid_t cxt5045_adc_nids[1] = { 0x1a };
677 static const hda_nid_t cxt5045_capsrc_nids[1] = { 0x1a };
678 #define CXT5045_SPDIF_OUT       0x18
679
680 static const struct hda_channel_mode cxt5045_modes[1] = {
681         { 2, NULL },
682 };
683
684 static const struct hda_input_mux cxt5045_capture_source = {
685         .num_items = 2,
686         .items = {
687                 { "IntMic", 0x1 },
688                 { "ExtMic", 0x2 },
689         }
690 };
691
692 static const struct hda_input_mux cxt5045_capture_source_benq = {
693         .num_items = 5,
694         .items = {
695                 { "IntMic", 0x1 },
696                 { "ExtMic", 0x2 },
697                 { "LineIn", 0x3 },
698                 { "CD",     0x4 },
699                 { "Mixer",  0x0 },
700         }
701 };
702
703 static const struct hda_input_mux cxt5045_capture_source_hp530 = {
704         .num_items = 2,
705         .items = {
706                 { "ExtMic", 0x1 },
707                 { "IntMic", 0x2 },
708         }
709 };
710
711 /* turn on/off EAPD (+ mute HP) as a master switch */
712 static int cxt5045_hp_master_sw_put(struct snd_kcontrol *kcontrol,
713                                     struct snd_ctl_elem_value *ucontrol)
714 {
715         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
716         struct conexant_spec *spec = codec->spec;
717         unsigned int bits;
718
719         if (!cxt_eapd_put(kcontrol, ucontrol))
720                 return 0;
721
722         /* toggle internal speakers mute depending of presence of
723          * the headphone jack
724          */
725         bits = (!spec->hp_present && spec->cur_eapd) ? 0 : HDA_AMP_MUTE;
726         snd_hda_codec_amp_stereo(codec, 0x10, HDA_OUTPUT, 0,
727                                  HDA_AMP_MUTE, bits);
728
729         bits = spec->cur_eapd ? 0 : HDA_AMP_MUTE;
730         snd_hda_codec_amp_stereo(codec, 0x11, HDA_OUTPUT, 0,
731                                  HDA_AMP_MUTE, bits);
732         return 1;
733 }
734
735 /* bind volumes of both NID 0x10 and 0x11 */
736 static const struct hda_bind_ctls cxt5045_hp_bind_master_vol = {
737         .ops = &snd_hda_bind_vol,
738         .values = {
739                 HDA_COMPOSE_AMP_VAL(0x10, 3, 0, HDA_OUTPUT),
740                 HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT),
741                 0
742         },
743 };
744
745 /* toggle input of built-in and mic jack appropriately */
746 static void cxt5045_hp_automic(struct hda_codec *codec)
747 {
748         static const struct hda_verb mic_jack_on[] = {
749                 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
750                 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
751                 {}
752         };
753         static const struct hda_verb mic_jack_off[] = {
754                 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
755                 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
756                 {}
757         };
758         unsigned int present;
759
760         present = snd_hda_jack_detect(codec, 0x12);
761         if (present)
762                 snd_hda_sequence_write(codec, mic_jack_on);
763         else
764                 snd_hda_sequence_write(codec, mic_jack_off);
765 }
766
767
768 /* mute internal speaker if HP is plugged */
769 static void cxt5045_hp_automute(struct hda_codec *codec)
770 {
771         struct conexant_spec *spec = codec->spec;
772         unsigned int bits;
773
774         spec->hp_present = snd_hda_jack_detect(codec, 0x11);
775
776         bits = (spec->hp_present || !spec->cur_eapd) ? HDA_AMP_MUTE : 0; 
777         snd_hda_codec_amp_stereo(codec, 0x10, HDA_OUTPUT, 0,
778                                  HDA_AMP_MUTE, bits);
779 }
780
781 /* unsolicited event for HP jack sensing */
782 static void cxt5045_hp_unsol_event(struct hda_codec *codec,
783                                    unsigned int res)
784 {
785         res >>= 26;
786         switch (res) {
787         case CONEXANT_HP_EVENT:
788                 cxt5045_hp_automute(codec);
789                 break;
790         case CONEXANT_MIC_EVENT:
791                 cxt5045_hp_automic(codec);
792                 break;
793
794         }
795 }
796
797 static const struct snd_kcontrol_new cxt5045_mixers[] = {
798         HDA_CODEC_VOLUME("Internal Mic Capture Volume", 0x1a, 0x01, HDA_INPUT),
799         HDA_CODEC_MUTE("Internal Mic Capture Switch", 0x1a, 0x01, HDA_INPUT),
800         HDA_CODEC_VOLUME("Mic Capture Volume", 0x1a, 0x02, HDA_INPUT),
801         HDA_CODEC_MUTE("Mic Capture Switch", 0x1a, 0x02, HDA_INPUT),
802         HDA_CODEC_VOLUME("PCM Playback Volume", 0x17, 0x0, HDA_INPUT),
803         HDA_CODEC_MUTE("PCM Playback Switch", 0x17, 0x0, HDA_INPUT),
804         HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x17, 0x1, HDA_INPUT),
805         HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x17, 0x1, HDA_INPUT),
806         HDA_CODEC_VOLUME("Mic Playback Volume", 0x17, 0x2, HDA_INPUT),
807         HDA_CODEC_MUTE("Mic Playback Switch", 0x17, 0x2, HDA_INPUT),
808         HDA_BIND_VOL("Master Playback Volume", &cxt5045_hp_bind_master_vol),
809         {
810                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
811                 .name = "Master Playback Switch",
812                 .info = cxt_eapd_info,
813                 .get = cxt_eapd_get,
814                 .put = cxt5045_hp_master_sw_put,
815                 .private_value = 0x10,
816         },
817
818         {}
819 };
820
821 static const struct snd_kcontrol_new cxt5045_benq_mixers[] = {
822         HDA_CODEC_VOLUME("CD Capture Volume", 0x1a, 0x04, HDA_INPUT),
823         HDA_CODEC_MUTE("CD Capture Switch", 0x1a, 0x04, HDA_INPUT),
824         HDA_CODEC_VOLUME("CD Playback Volume", 0x17, 0x4, HDA_INPUT),
825         HDA_CODEC_MUTE("CD Playback Switch", 0x17, 0x4, HDA_INPUT),
826
827         HDA_CODEC_VOLUME("Line In Capture Volume", 0x1a, 0x03, HDA_INPUT),
828         HDA_CODEC_MUTE("Line In Capture Switch", 0x1a, 0x03, HDA_INPUT),
829         HDA_CODEC_VOLUME("Line In Playback Volume", 0x17, 0x3, HDA_INPUT),
830         HDA_CODEC_MUTE("Line In Playback Switch", 0x17, 0x3, HDA_INPUT),
831
832         HDA_CODEC_VOLUME("Mixer Capture Volume", 0x1a, 0x0, HDA_INPUT),
833         HDA_CODEC_MUTE("Mixer Capture Switch", 0x1a, 0x0, HDA_INPUT),
834
835         {}
836 };
837
838 static const struct snd_kcontrol_new cxt5045_mixers_hp530[] = {
839         HDA_CODEC_VOLUME("Internal Mic Capture Volume", 0x1a, 0x02, HDA_INPUT),
840         HDA_CODEC_MUTE("Internal Mic Capture Switch", 0x1a, 0x02, HDA_INPUT),
841         HDA_CODEC_VOLUME("Mic Capture Volume", 0x1a, 0x01, HDA_INPUT),
842         HDA_CODEC_MUTE("Mic Capture Switch", 0x1a, 0x01, HDA_INPUT),
843         HDA_CODEC_VOLUME("PCM Playback Volume", 0x17, 0x0, HDA_INPUT),
844         HDA_CODEC_MUTE("PCM Playback Switch", 0x17, 0x0, HDA_INPUT),
845         HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x17, 0x2, HDA_INPUT),
846         HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x17, 0x2, HDA_INPUT),
847         HDA_CODEC_VOLUME("Mic Playback Volume", 0x17, 0x1, HDA_INPUT),
848         HDA_CODEC_MUTE("Mic Playback Switch", 0x17, 0x1, HDA_INPUT),
849         HDA_BIND_VOL("Master Playback Volume", &cxt5045_hp_bind_master_vol),
850         {
851                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
852                 .name = "Master Playback Switch",
853                 .info = cxt_eapd_info,
854                 .get = cxt_eapd_get,
855                 .put = cxt5045_hp_master_sw_put,
856                 .private_value = 0x10,
857         },
858
859         {}
860 };
861
862 static const struct hda_verb cxt5045_init_verbs[] = {
863         /* Line in, Mic */
864         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_80 },
865         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_80 },
866         /* HP, Amp  */
867         {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
868         {0x10, AC_VERB_SET_CONNECT_SEL, 0x1},
869         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
870         {0x11, AC_VERB_SET_CONNECT_SEL, 0x1},
871         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
872         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
873         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
874         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
875         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
876         /* Record selector: Internal mic */
877         {0x1a, AC_VERB_SET_CONNECT_SEL,0x1},
878         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE,
879          AC_AMP_SET_INPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x17},
880         /* SPDIF route: PCM */
881         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
882         { 0x13, AC_VERB_SET_CONNECT_SEL, 0x0 },
883         /* EAPD */
884         {0x10, AC_VERB_SET_EAPD_BTLENABLE, 0x2 }, /* default on */ 
885         { } /* end */
886 };
887
888 static const struct hda_verb cxt5045_benq_init_verbs[] = {
889         /* Internal Mic, Mic */
890         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_80 },
891         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_80 },
892         /* Line In,HP, Amp  */
893         {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
894         {0x10, AC_VERB_SET_CONNECT_SEL, 0x1},
895         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
896         {0x11, AC_VERB_SET_CONNECT_SEL, 0x1},
897         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
898         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
899         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
900         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
901         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
902         /* Record selector: Internal mic */
903         {0x1a, AC_VERB_SET_CONNECT_SEL, 0x1},
904         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE,
905          AC_AMP_SET_INPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x17},
906         /* SPDIF route: PCM */
907         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
908         {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
909         /* EAPD */
910         {0x10, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
911         { } /* end */
912 };
913
914 static const struct hda_verb cxt5045_hp_sense_init_verbs[] = {
915         /* pin sensing on HP jack */
916         {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT},
917         { } /* end */
918 };
919
920 static const struct hda_verb cxt5045_mic_sense_init_verbs[] = {
921         /* pin sensing on HP jack */
922         {0x12, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT},
923         { } /* end */
924 };
925
926 #ifdef CONFIG_SND_DEBUG
927 /* Test configuration for debugging, modelled after the ALC260 test
928  * configuration.
929  */
930 static const struct hda_input_mux cxt5045_test_capture_source = {
931         .num_items = 5,
932         .items = {
933                 { "MIXER", 0x0 },
934                 { "MIC1 pin", 0x1 },
935                 { "LINE1 pin", 0x2 },
936                 { "HP-OUT pin", 0x3 },
937                 { "CD pin", 0x4 },
938         },
939 };
940
941 static const struct snd_kcontrol_new cxt5045_test_mixer[] = {
942
943         /* Output controls */
944         HDA_CODEC_VOLUME("Speaker Playback Volume", 0x10, 0x0, HDA_OUTPUT),
945         HDA_CODEC_MUTE("Speaker Playback Switch", 0x10, 0x0, HDA_OUTPUT),
946         HDA_CODEC_VOLUME("Node 11 Playback Volume", 0x11, 0x0, HDA_OUTPUT),
947         HDA_CODEC_MUTE("Node 11 Playback Switch", 0x11, 0x0, HDA_OUTPUT),
948         HDA_CODEC_VOLUME("Node 12 Playback Volume", 0x12, 0x0, HDA_OUTPUT),
949         HDA_CODEC_MUTE("Node 12 Playback Switch", 0x12, 0x0, HDA_OUTPUT),
950         
951         /* Modes for retasking pin widgets */
952         CXT_PIN_MODE("HP-OUT pin mode", 0x11, CXT_PIN_DIR_INOUT),
953         CXT_PIN_MODE("LINE1 pin mode", 0x12, CXT_PIN_DIR_INOUT),
954
955         /* EAPD Switch Control */
956         CXT_EAPD_SWITCH("External Amplifier", 0x10, 0x0),
957
958         /* Loopback mixer controls */
959
960         HDA_CODEC_VOLUME("Mixer-1 Volume", 0x17, 0x0, HDA_INPUT),
961         HDA_CODEC_MUTE("Mixer-1 Switch", 0x17, 0x0, HDA_INPUT),
962         HDA_CODEC_VOLUME("Mixer-2 Volume", 0x17, 0x1, HDA_INPUT),
963         HDA_CODEC_MUTE("Mixer-2 Switch", 0x17, 0x1, HDA_INPUT),
964         HDA_CODEC_VOLUME("Mixer-3 Volume", 0x17, 0x2, HDA_INPUT),
965         HDA_CODEC_MUTE("Mixer-3 Switch", 0x17, 0x2, HDA_INPUT),
966         HDA_CODEC_VOLUME("Mixer-4 Volume", 0x17, 0x3, HDA_INPUT),
967         HDA_CODEC_MUTE("Mixer-4 Switch", 0x17, 0x3, HDA_INPUT),
968         HDA_CODEC_VOLUME("Mixer-5 Volume", 0x17, 0x4, HDA_INPUT),
969         HDA_CODEC_MUTE("Mixer-5 Switch", 0x17, 0x4, HDA_INPUT),
970         {
971                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
972                 .name = "Input Source",
973                 .info = conexant_mux_enum_info,
974                 .get = conexant_mux_enum_get,
975                 .put = conexant_mux_enum_put,
976         },
977         /* Audio input controls */
978         HDA_CODEC_VOLUME("Input-1 Volume", 0x1a, 0x0, HDA_INPUT),
979         HDA_CODEC_MUTE("Input-1 Switch", 0x1a, 0x0, HDA_INPUT),
980         HDA_CODEC_VOLUME("Input-2 Volume", 0x1a, 0x1, HDA_INPUT),
981         HDA_CODEC_MUTE("Input-2 Switch", 0x1a, 0x1, HDA_INPUT),
982         HDA_CODEC_VOLUME("Input-3 Volume", 0x1a, 0x2, HDA_INPUT),
983         HDA_CODEC_MUTE("Input-3 Switch", 0x1a, 0x2, HDA_INPUT),
984         HDA_CODEC_VOLUME("Input-4 Volume", 0x1a, 0x3, HDA_INPUT),
985         HDA_CODEC_MUTE("Input-4 Switch", 0x1a, 0x3, HDA_INPUT),
986         HDA_CODEC_VOLUME("Input-5 Volume", 0x1a, 0x4, HDA_INPUT),
987         HDA_CODEC_MUTE("Input-5 Switch", 0x1a, 0x4, HDA_INPUT),
988         { } /* end */
989 };
990
991 static const struct hda_verb cxt5045_test_init_verbs[] = {
992         /* Set connections */
993         { 0x10, AC_VERB_SET_CONNECT_SEL, 0x0 },
994         { 0x11, AC_VERB_SET_CONNECT_SEL, 0x0 },
995         { 0x12, AC_VERB_SET_CONNECT_SEL, 0x0 },
996         /* Enable retasking pins as output, initially without power amp */
997         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
998         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
999
1000         /* Disable digital (SPDIF) pins initially, but users can enable
1001          * them via a mixer switch.  In the case of SPDIF-out, this initverb
1002          * payload also sets the generation to 0, output to be in "consumer"
1003          * PCM format, copyright asserted, no pre-emphasis and no validity
1004          * control.
1005          */
1006         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1007         {0x18, AC_VERB_SET_DIGI_CONVERT_1, 0},
1008
1009         /* Start with output sum widgets muted and their output gains at min */
1010         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1011         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1012
1013         /* Unmute retasking pin widget output buffers since the default
1014          * state appears to be output.  As the pin mode is changed by the
1015          * user the pin mode control will take care of enabling the pin's
1016          * input/output buffers as needed.
1017          */
1018         {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1019         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1020
1021         /* Mute capture amp left and right */
1022         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1023
1024         /* Set ADC connection select to match default mixer setting (mic1
1025          * pin)
1026          */
1027         {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
1028         {0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
1029
1030         /* Mute all inputs to mixer widget (even unconnected ones) */
1031         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* Mixer pin */
1032         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* Mic1 pin */
1033         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* Line pin */
1034         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* HP pin */
1035         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
1036
1037         { }
1038 };
1039 #endif
1040
1041
1042 /* initialize jack-sensing, too */
1043 static int cxt5045_init(struct hda_codec *codec)
1044 {
1045         conexant_init(codec);
1046         cxt5045_hp_automute(codec);
1047         return 0;
1048 }
1049
1050
1051 enum {
1052         CXT5045_LAPTOP_HPSENSE,
1053         CXT5045_LAPTOP_MICSENSE,
1054         CXT5045_LAPTOP_HPMICSENSE,
1055         CXT5045_BENQ,
1056         CXT5045_LAPTOP_HP530,
1057 #ifdef CONFIG_SND_DEBUG
1058         CXT5045_TEST,
1059 #endif
1060         CXT5045_AUTO,
1061         CXT5045_MODELS
1062 };
1063
1064 static const char * const cxt5045_models[CXT5045_MODELS] = {
1065         [CXT5045_LAPTOP_HPSENSE]        = "laptop-hpsense",
1066         [CXT5045_LAPTOP_MICSENSE]       = "laptop-micsense",
1067         [CXT5045_LAPTOP_HPMICSENSE]     = "laptop-hpmicsense",
1068         [CXT5045_BENQ]                  = "benq",
1069         [CXT5045_LAPTOP_HP530]          = "laptop-hp530",
1070 #ifdef CONFIG_SND_DEBUG
1071         [CXT5045_TEST]          = "test",
1072 #endif
1073         [CXT5045_AUTO]                  = "auto",
1074 };
1075
1076 static const struct snd_pci_quirk cxt5045_cfg_tbl[] = {
1077         SND_PCI_QUIRK(0x103c, 0x30d5, "HP 530", CXT5045_LAPTOP_HP530),
1078         SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba P105", CXT5045_LAPTOP_MICSENSE),
1079         SND_PCI_QUIRK(0x152d, 0x0753, "Benq R55E", CXT5045_BENQ),
1080         SND_PCI_QUIRK(0x1734, 0x10ad, "Fujitsu Si1520", CXT5045_LAPTOP_MICSENSE),
1081         SND_PCI_QUIRK(0x1734, 0x10cb, "Fujitsu Si3515", CXT5045_LAPTOP_HPMICSENSE),
1082         SND_PCI_QUIRK(0x1734, 0x110e, "Fujitsu V5505",
1083                       CXT5045_LAPTOP_HPMICSENSE),
1084         SND_PCI_QUIRK(0x1509, 0x1e40, "FIC", CXT5045_LAPTOP_HPMICSENSE),
1085         SND_PCI_QUIRK(0x1509, 0x2f05, "FIC", CXT5045_LAPTOP_HPMICSENSE),
1086         SND_PCI_QUIRK(0x1509, 0x2f06, "FIC", CXT5045_LAPTOP_HPMICSENSE),
1087         SND_PCI_QUIRK_MASK(0x1631, 0xff00, 0xc100, "Packard Bell",
1088                            CXT5045_LAPTOP_HPMICSENSE),
1089         SND_PCI_QUIRK(0x8086, 0x2111, "Conexant Reference board", CXT5045_LAPTOP_HPSENSE),
1090         {}
1091 };
1092
1093 static int patch_cxt5045(struct hda_codec *codec)
1094 {
1095         struct conexant_spec *spec;
1096         int board_config;
1097
1098         board_config = snd_hda_check_board_config(codec, CXT5045_MODELS,
1099                                                   cxt5045_models,
1100                                                   cxt5045_cfg_tbl);
1101         if (board_config < 0)
1102                 board_config = CXT5045_AUTO; /* model=auto as default */
1103         if (board_config == CXT5045_AUTO)
1104                 return patch_conexant_auto(codec);
1105
1106         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1107         if (!spec)
1108                 return -ENOMEM;
1109         codec->spec = spec;
1110         codec->pin_amp_workaround = 1;
1111
1112         spec->multiout.max_channels = 2;
1113         spec->multiout.num_dacs = ARRAY_SIZE(cxt5045_dac_nids);
1114         spec->multiout.dac_nids = cxt5045_dac_nids;
1115         spec->multiout.dig_out_nid = CXT5045_SPDIF_OUT;
1116         spec->num_adc_nids = 1;
1117         spec->adc_nids = cxt5045_adc_nids;
1118         spec->capsrc_nids = cxt5045_capsrc_nids;
1119         spec->input_mux = &cxt5045_capture_source;
1120         spec->num_mixers = 1;
1121         spec->mixers[0] = cxt5045_mixers;
1122         spec->num_init_verbs = 1;
1123         spec->init_verbs[0] = cxt5045_init_verbs;
1124         spec->spdif_route = 0;
1125         spec->num_channel_mode = ARRAY_SIZE(cxt5045_modes);
1126         spec->channel_mode = cxt5045_modes;
1127
1128         set_beep_amp(spec, 0x16, 0, 1);
1129
1130         codec->patch_ops = conexant_patch_ops;
1131
1132         switch (board_config) {
1133         case CXT5045_LAPTOP_HPSENSE:
1134                 codec->patch_ops.unsol_event = cxt5045_hp_unsol_event;
1135                 spec->input_mux = &cxt5045_capture_source;
1136                 spec->num_init_verbs = 2;
1137                 spec->init_verbs[1] = cxt5045_hp_sense_init_verbs;
1138                 spec->mixers[0] = cxt5045_mixers;
1139                 codec->patch_ops.init = cxt5045_init;
1140                 break;
1141         case CXT5045_LAPTOP_MICSENSE:
1142                 codec->patch_ops.unsol_event = cxt5045_hp_unsol_event;
1143                 spec->input_mux = &cxt5045_capture_source;
1144                 spec->num_init_verbs = 2;
1145                 spec->init_verbs[1] = cxt5045_mic_sense_init_verbs;
1146                 spec->mixers[0] = cxt5045_mixers;
1147                 codec->patch_ops.init = cxt5045_init;
1148                 break;
1149         default:
1150         case CXT5045_LAPTOP_HPMICSENSE:
1151                 codec->patch_ops.unsol_event = cxt5045_hp_unsol_event;
1152                 spec->input_mux = &cxt5045_capture_source;
1153                 spec->num_init_verbs = 3;
1154                 spec->init_verbs[1] = cxt5045_hp_sense_init_verbs;
1155                 spec->init_verbs[2] = cxt5045_mic_sense_init_verbs;
1156                 spec->mixers[0] = cxt5045_mixers;
1157                 codec->patch_ops.init = cxt5045_init;
1158                 break;
1159         case CXT5045_BENQ:
1160                 codec->patch_ops.unsol_event = cxt5045_hp_unsol_event;
1161                 spec->input_mux = &cxt5045_capture_source_benq;
1162                 spec->num_init_verbs = 1;
1163                 spec->init_verbs[0] = cxt5045_benq_init_verbs;
1164                 spec->mixers[0] = cxt5045_mixers;
1165                 spec->mixers[1] = cxt5045_benq_mixers;
1166                 spec->num_mixers = 2;
1167                 codec->patch_ops.init = cxt5045_init;
1168                 break;
1169         case CXT5045_LAPTOP_HP530:
1170                 codec->patch_ops.unsol_event = cxt5045_hp_unsol_event;
1171                 spec->input_mux = &cxt5045_capture_source_hp530;
1172                 spec->num_init_verbs = 2;
1173                 spec->init_verbs[1] = cxt5045_hp_sense_init_verbs;
1174                 spec->mixers[0] = cxt5045_mixers_hp530;
1175                 codec->patch_ops.init = cxt5045_init;
1176                 break;
1177 #ifdef CONFIG_SND_DEBUG
1178         case CXT5045_TEST:
1179                 spec->input_mux = &cxt5045_test_capture_source;
1180                 spec->mixers[0] = cxt5045_test_mixer;
1181                 spec->init_verbs[0] = cxt5045_test_init_verbs;
1182                 break;
1183                 
1184 #endif  
1185         }
1186
1187         switch (codec->subsystem_id >> 16) {
1188         case 0x103c:
1189         case 0x1631:
1190         case 0x1734:
1191         case 0x17aa:
1192                 /* HP, Packard Bell, Fujitsu-Siemens & Lenovo laptops have
1193                  * really bad sound over 0dB on NID 0x17. Fix max PCM level to
1194                  * 0 dB (originally it has 0x2b steps with 0dB offset 0x14)
1195                  */
1196                 snd_hda_override_amp_caps(codec, 0x17, HDA_INPUT,
1197                                           (0x14 << AC_AMPCAP_OFFSET_SHIFT) |
1198                                           (0x14 << AC_AMPCAP_NUM_STEPS_SHIFT) |
1199                                           (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) |
1200                                           (1 << AC_AMPCAP_MUTE_SHIFT));
1201                 break;
1202         }
1203
1204         if (spec->beep_amp)
1205                 snd_hda_attach_beep_device(codec, spec->beep_amp);
1206
1207         return 0;
1208 }
1209
1210
1211 /* Conexant 5047 specific */
1212 #define CXT5047_SPDIF_OUT       0x11
1213
1214 static const hda_nid_t cxt5047_dac_nids[1] = { 0x10 }; /* 0x1c */
1215 static const hda_nid_t cxt5047_adc_nids[1] = { 0x12 };
1216 static const hda_nid_t cxt5047_capsrc_nids[1] = { 0x1a };
1217
1218 static const struct hda_channel_mode cxt5047_modes[1] = {
1219         { 2, NULL },
1220 };
1221
1222 static const struct hda_input_mux cxt5047_toshiba_capture_source = {
1223         .num_items = 2,
1224         .items = {
1225                 { "ExtMic", 0x2 },
1226                 { "Line-In", 0x1 },
1227         }
1228 };
1229
1230 /* turn on/off EAPD (+ mute HP) as a master switch */
1231 static int cxt5047_hp_master_sw_put(struct snd_kcontrol *kcontrol,
1232                                     struct snd_ctl_elem_value *ucontrol)
1233 {
1234         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1235         struct conexant_spec *spec = codec->spec;
1236         unsigned int bits;
1237
1238         if (!cxt_eapd_put(kcontrol, ucontrol))
1239                 return 0;
1240
1241         /* toggle internal speakers mute depending of presence of
1242          * the headphone jack
1243          */
1244         bits = (!spec->hp_present && spec->cur_eapd) ? 0 : HDA_AMP_MUTE;
1245         /* NOTE: Conexat codec needs the index for *OUTPUT* amp of
1246          * pin widgets unlike other codecs.  In this case, we need to
1247          * set index 0x01 for the volume from the mixer amp 0x19.
1248          */
1249         snd_hda_codec_amp_stereo(codec, 0x1d, HDA_OUTPUT, 0x01,
1250                                  HDA_AMP_MUTE, bits);
1251         bits = spec->cur_eapd ? 0 : HDA_AMP_MUTE;
1252         snd_hda_codec_amp_stereo(codec, 0x13, HDA_OUTPUT, 0,
1253                                  HDA_AMP_MUTE, bits);
1254         return 1;
1255 }
1256
1257 /* mute internal speaker if HP is plugged */
1258 static void cxt5047_hp_automute(struct hda_codec *codec)
1259 {
1260         struct conexant_spec *spec = codec->spec;
1261         unsigned int bits;
1262
1263         spec->hp_present = snd_hda_jack_detect(codec, 0x13);
1264
1265         bits = (spec->hp_present || !spec->cur_eapd) ? HDA_AMP_MUTE : 0;
1266         /* See the note in cxt5047_hp_master_sw_put */
1267         snd_hda_codec_amp_stereo(codec, 0x1d, HDA_OUTPUT, 0x01,
1268                                  HDA_AMP_MUTE, bits);
1269 }
1270
1271 /* toggle input of built-in and mic jack appropriately */
1272 static void cxt5047_hp_automic(struct hda_codec *codec)
1273 {
1274         static const struct hda_verb mic_jack_on[] = {
1275                 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1276                 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1277                 {}
1278         };
1279         static const struct hda_verb mic_jack_off[] = {
1280                 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1281                 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1282                 {}
1283         };
1284         unsigned int present;
1285
1286         present = snd_hda_jack_detect(codec, 0x15);
1287         if (present)
1288                 snd_hda_sequence_write(codec, mic_jack_on);
1289         else
1290                 snd_hda_sequence_write(codec, mic_jack_off);
1291 }
1292
1293 /* unsolicited event for HP jack sensing */
1294 static void cxt5047_hp_unsol_event(struct hda_codec *codec,
1295                                   unsigned int res)
1296 {
1297         switch (res >> 26) {
1298         case CONEXANT_HP_EVENT:
1299                 cxt5047_hp_automute(codec);
1300                 break;
1301         case CONEXANT_MIC_EVENT:
1302                 cxt5047_hp_automic(codec);
1303                 break;
1304         }
1305 }
1306
1307 static const struct snd_kcontrol_new cxt5047_base_mixers[] = {
1308         HDA_CODEC_VOLUME("Mic Playback Volume", 0x19, 0x02, HDA_INPUT),
1309         HDA_CODEC_MUTE("Mic Playback Switch", 0x19, 0x02, HDA_INPUT),
1310         HDA_CODEC_VOLUME("Mic Boost Volume", 0x1a, 0x0, HDA_OUTPUT),
1311         HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x03, HDA_INPUT),
1312         HDA_CODEC_MUTE("Capture Switch", 0x12, 0x03, HDA_INPUT),
1313         HDA_CODEC_VOLUME("PCM Volume", 0x10, 0x00, HDA_OUTPUT),
1314         HDA_CODEC_MUTE("PCM Switch", 0x10, 0x00, HDA_OUTPUT),
1315         {
1316                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1317                 .name = "Master Playback Switch",
1318                 .info = cxt_eapd_info,
1319                 .get = cxt_eapd_get,
1320                 .put = cxt5047_hp_master_sw_put,
1321                 .private_value = 0x13,
1322         },
1323
1324         {}
1325 };
1326
1327 static const struct snd_kcontrol_new cxt5047_hp_spk_mixers[] = {
1328         /* See the note in cxt5047_hp_master_sw_put */
1329         HDA_CODEC_VOLUME("Speaker Playback Volume", 0x1d, 0x01, HDA_OUTPUT),
1330         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x13, 0x00, HDA_OUTPUT),
1331         {}
1332 };
1333
1334 static const struct snd_kcontrol_new cxt5047_hp_only_mixers[] = {
1335         HDA_CODEC_VOLUME("Master Playback Volume", 0x13, 0x00, HDA_OUTPUT),
1336         { } /* end */
1337 };
1338
1339 static const struct hda_verb cxt5047_init_verbs[] = {
1340         /* Line in, Mic, Built-in Mic */
1341         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1342         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_50 },
1343         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_50 },
1344         /* HP, Speaker  */
1345         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
1346         {0x13, AC_VERB_SET_CONNECT_SEL, 0x0}, /* mixer(0x19) */
1347         {0x1d, AC_VERB_SET_CONNECT_SEL, 0x1}, /* mixer(0x19) */
1348         /* Record selector: Mic */
1349         {0x12, AC_VERB_SET_CONNECT_SEL,0x03},
1350         {0x19, AC_VERB_SET_AMP_GAIN_MUTE,
1351          AC_AMP_SET_INPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x17},
1352         {0x1A, AC_VERB_SET_CONNECT_SEL,0x02},
1353         {0x1A, AC_VERB_SET_AMP_GAIN_MUTE,
1354          AC_AMP_SET_OUTPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x00},
1355         {0x1A, AC_VERB_SET_AMP_GAIN_MUTE,
1356          AC_AMP_SET_OUTPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x03},
1357         /* SPDIF route: PCM */
1358         { 0x18, AC_VERB_SET_CONNECT_SEL, 0x0 },
1359         /* Enable unsolicited events */
1360         {0x13, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT},
1361         {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT},
1362         { } /* end */
1363 };
1364
1365 /* configuration for Toshiba Laptops */
1366 static const struct hda_verb cxt5047_toshiba_init_verbs[] = {
1367         {0x13, AC_VERB_SET_EAPD_BTLENABLE, 0x0}, /* default off */
1368         {}
1369 };
1370
1371 /* Test configuration for debugging, modelled after the ALC260 test
1372  * configuration.
1373  */
1374 #ifdef CONFIG_SND_DEBUG
1375 static const struct hda_input_mux cxt5047_test_capture_source = {
1376         .num_items = 4,
1377         .items = {
1378                 { "LINE1 pin", 0x0 },
1379                 { "MIC1 pin", 0x1 },
1380                 { "MIC2 pin", 0x2 },
1381                 { "CD pin", 0x3 },
1382         },
1383 };
1384
1385 static const struct snd_kcontrol_new cxt5047_test_mixer[] = {
1386
1387         /* Output only controls */
1388         HDA_CODEC_VOLUME("OutAmp-1 Volume", 0x10, 0x0, HDA_OUTPUT),
1389         HDA_CODEC_MUTE("OutAmp-1 Switch", 0x10,0x0, HDA_OUTPUT),
1390         HDA_CODEC_VOLUME("OutAmp-2 Volume", 0x1c, 0x0, HDA_OUTPUT),
1391         HDA_CODEC_MUTE("OutAmp-2 Switch", 0x1c, 0x0, HDA_OUTPUT),
1392         HDA_CODEC_VOLUME("Speaker Playback Volume", 0x1d, 0x0, HDA_OUTPUT),
1393         HDA_CODEC_MUTE("Speaker Playback Switch", 0x1d, 0x0, HDA_OUTPUT),
1394         HDA_CODEC_VOLUME("HeadPhone Playback Volume", 0x13, 0x0, HDA_OUTPUT),
1395         HDA_CODEC_MUTE("HeadPhone Playback Switch", 0x13, 0x0, HDA_OUTPUT),
1396         HDA_CODEC_VOLUME("Line1-Out Playback Volume", 0x14, 0x0, HDA_OUTPUT),
1397         HDA_CODEC_MUTE("Line1-Out Playback Switch", 0x14, 0x0, HDA_OUTPUT),
1398         HDA_CODEC_VOLUME("Line2-Out Playback Volume", 0x15, 0x0, HDA_OUTPUT),
1399         HDA_CODEC_MUTE("Line2-Out Playback Switch", 0x15, 0x0, HDA_OUTPUT),
1400
1401         /* Modes for retasking pin widgets */
1402         CXT_PIN_MODE("LINE1 pin mode", 0x14, CXT_PIN_DIR_INOUT),
1403         CXT_PIN_MODE("MIC1 pin mode", 0x15, CXT_PIN_DIR_INOUT),
1404
1405         /* EAPD Switch Control */
1406         CXT_EAPD_SWITCH("External Amplifier", 0x13, 0x0),
1407
1408         /* Loopback mixer controls */
1409         HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x12, 0x01, HDA_INPUT),
1410         HDA_CODEC_MUTE("MIC1 Playback Switch", 0x12, 0x01, HDA_INPUT),
1411         HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x12, 0x02, HDA_INPUT),
1412         HDA_CODEC_MUTE("MIC2 Playback Switch", 0x12, 0x02, HDA_INPUT),
1413         HDA_CODEC_VOLUME("LINE Playback Volume", 0x12, 0x0, HDA_INPUT),
1414         HDA_CODEC_MUTE("LINE Playback Switch", 0x12, 0x0, HDA_INPUT),
1415         HDA_CODEC_VOLUME("CD Playback Volume", 0x12, 0x04, HDA_INPUT),
1416         HDA_CODEC_MUTE("CD Playback Switch", 0x12, 0x04, HDA_INPUT),
1417
1418         HDA_CODEC_VOLUME("Capture-1 Volume", 0x19, 0x0, HDA_INPUT),
1419         HDA_CODEC_MUTE("Capture-1 Switch", 0x19, 0x0, HDA_INPUT),
1420         HDA_CODEC_VOLUME("Capture-2 Volume", 0x19, 0x1, HDA_INPUT),
1421         HDA_CODEC_MUTE("Capture-2 Switch", 0x19, 0x1, HDA_INPUT),
1422         HDA_CODEC_VOLUME("Capture-3 Volume", 0x19, 0x2, HDA_INPUT),
1423         HDA_CODEC_MUTE("Capture-3 Switch", 0x19, 0x2, HDA_INPUT),
1424         HDA_CODEC_VOLUME("Capture-4 Volume", 0x19, 0x3, HDA_INPUT),
1425         HDA_CODEC_MUTE("Capture-4 Switch", 0x19, 0x3, HDA_INPUT),
1426         {
1427                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1428                 .name = "Input Source",
1429                 .info = conexant_mux_enum_info,
1430                 .get = conexant_mux_enum_get,
1431                 .put = conexant_mux_enum_put,
1432         },
1433         HDA_CODEC_VOLUME("Mic Boost Volume", 0x1a, 0x0, HDA_OUTPUT),
1434
1435         { } /* end */
1436 };
1437
1438 static const struct hda_verb cxt5047_test_init_verbs[] = {
1439         /* Enable retasking pins as output, initially without power amp */
1440         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1441         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1442         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1443
1444         /* Disable digital (SPDIF) pins initially, but users can enable
1445          * them via a mixer switch.  In the case of SPDIF-out, this initverb
1446          * payload also sets the generation to 0, output to be in "consumer"
1447          * PCM format, copyright asserted, no pre-emphasis and no validity
1448          * control.
1449          */
1450         {0x18, AC_VERB_SET_DIGI_CONVERT_1, 0},
1451
1452         /* Ensure mic1, mic2, line1 pin widgets take input from the 
1453          * OUT1 sum bus when acting as an output.
1454          */
1455         {0x1a, AC_VERB_SET_CONNECT_SEL, 0},
1456         {0x1b, AC_VERB_SET_CONNECT_SEL, 0},
1457
1458         /* Start with output sum widgets muted and their output gains at min */
1459         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1460         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1461
1462         /* Unmute retasking pin widget output buffers since the default
1463          * state appears to be output.  As the pin mode is changed by the
1464          * user the pin mode control will take care of enabling the pin's
1465          * input/output buffers as needed.
1466          */
1467         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1468         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1469         {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1470
1471         /* Mute capture amp left and right */
1472         {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1473
1474         /* Set ADC connection select to match default mixer setting (mic1
1475          * pin)
1476          */
1477         {0x12, AC_VERB_SET_CONNECT_SEL, 0x00},
1478
1479         /* Mute all inputs to mixer widget (even unconnected ones) */
1480         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
1481         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
1482         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
1483         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
1484         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
1485         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
1486         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
1487         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
1488
1489         { }
1490 };
1491 #endif
1492
1493
1494 /* initialize jack-sensing, too */
1495 static int cxt5047_hp_init(struct hda_codec *codec)
1496 {
1497         conexant_init(codec);
1498         cxt5047_hp_automute(codec);
1499         return 0;
1500 }
1501
1502
1503 enum {
1504         CXT5047_LAPTOP,         /* Laptops w/o EAPD support */
1505         CXT5047_LAPTOP_HP,      /* Some HP laptops */
1506         CXT5047_LAPTOP_EAPD,    /* Laptops with EAPD support */
1507 #ifdef CONFIG_SND_DEBUG
1508         CXT5047_TEST,
1509 #endif
1510         CXT5047_AUTO,
1511         CXT5047_MODELS
1512 };
1513
1514 static const char * const cxt5047_models[CXT5047_MODELS] = {
1515         [CXT5047_LAPTOP]        = "laptop",
1516         [CXT5047_LAPTOP_HP]     = "laptop-hp",
1517         [CXT5047_LAPTOP_EAPD]   = "laptop-eapd",
1518 #ifdef CONFIG_SND_DEBUG
1519         [CXT5047_TEST]          = "test",
1520 #endif
1521         [CXT5047_AUTO]          = "auto",
1522 };
1523
1524 static const struct snd_pci_quirk cxt5047_cfg_tbl[] = {
1525         SND_PCI_QUIRK(0x103c, 0x30a5, "HP DV5200T/DV8000T", CXT5047_LAPTOP_HP),
1526         SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3000, "HP DV Series",
1527                            CXT5047_LAPTOP),
1528         SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba P100", CXT5047_LAPTOP_EAPD),
1529         {}
1530 };
1531
1532 static int patch_cxt5047(struct hda_codec *codec)
1533 {
1534         struct conexant_spec *spec;
1535         int board_config;
1536
1537         board_config = snd_hda_check_board_config(codec, CXT5047_MODELS,
1538                                                   cxt5047_models,
1539                                                   cxt5047_cfg_tbl);
1540         if (board_config < 0)
1541                 board_config = CXT5047_AUTO; /* model=auto as default */
1542         if (board_config == CXT5047_AUTO)
1543                 return patch_conexant_auto(codec);
1544
1545         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1546         if (!spec)
1547                 return -ENOMEM;
1548         codec->spec = spec;
1549         codec->pin_amp_workaround = 1;
1550
1551         spec->multiout.max_channels = 2;
1552         spec->multiout.num_dacs = ARRAY_SIZE(cxt5047_dac_nids);
1553         spec->multiout.dac_nids = cxt5047_dac_nids;
1554         spec->multiout.dig_out_nid = CXT5047_SPDIF_OUT;
1555         spec->num_adc_nids = 1;
1556         spec->adc_nids = cxt5047_adc_nids;
1557         spec->capsrc_nids = cxt5047_capsrc_nids;
1558         spec->num_mixers = 1;
1559         spec->mixers[0] = cxt5047_base_mixers;
1560         spec->num_init_verbs = 1;
1561         spec->init_verbs[0] = cxt5047_init_verbs;
1562         spec->spdif_route = 0;
1563         spec->num_channel_mode = ARRAY_SIZE(cxt5047_modes),
1564         spec->channel_mode = cxt5047_modes,
1565
1566         codec->patch_ops = conexant_patch_ops;
1567
1568         switch (board_config) {
1569         case CXT5047_LAPTOP:
1570                 spec->num_mixers = 2;
1571                 spec->mixers[1] = cxt5047_hp_spk_mixers;
1572                 codec->patch_ops.unsol_event = cxt5047_hp_unsol_event;
1573                 break;
1574         case CXT5047_LAPTOP_HP:
1575                 spec->num_mixers = 2;
1576                 spec->mixers[1] = cxt5047_hp_only_mixers;
1577                 codec->patch_ops.unsol_event = cxt5047_hp_unsol_event;
1578                 codec->patch_ops.init = cxt5047_hp_init;
1579                 break;
1580         case CXT5047_LAPTOP_EAPD:
1581                 spec->input_mux = &cxt5047_toshiba_capture_source;
1582                 spec->num_mixers = 2;
1583                 spec->mixers[1] = cxt5047_hp_spk_mixers;
1584                 spec->num_init_verbs = 2;
1585                 spec->init_verbs[1] = cxt5047_toshiba_init_verbs;
1586                 codec->patch_ops.unsol_event = cxt5047_hp_unsol_event;
1587                 break;
1588 #ifdef CONFIG_SND_DEBUG
1589         case CXT5047_TEST:
1590                 spec->input_mux = &cxt5047_test_capture_source;
1591                 spec->mixers[0] = cxt5047_test_mixer;
1592                 spec->init_verbs[0] = cxt5047_test_init_verbs;
1593                 codec->patch_ops.unsol_event = cxt5047_hp_unsol_event;
1594 #endif  
1595         }
1596         spec->vmaster_nid = 0x13;
1597
1598         switch (codec->subsystem_id >> 16) {
1599         case 0x103c:
1600                 /* HP laptops have really bad sound over 0 dB on NID 0x10.
1601                  * Fix max PCM level to 0 dB (originally it has 0x1e steps
1602                  * with 0 dB offset 0x17)
1603                  */
1604                 snd_hda_override_amp_caps(codec, 0x10, HDA_INPUT,
1605                                           (0x17 << AC_AMPCAP_OFFSET_SHIFT) |
1606                                           (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) |
1607                                           (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) |
1608                                           (1 << AC_AMPCAP_MUTE_SHIFT));
1609                 break;
1610         }
1611
1612         return 0;
1613 }
1614
1615 /* Conexant 5051 specific */
1616 static const hda_nid_t cxt5051_dac_nids[1] = { 0x10 };
1617 static const hda_nid_t cxt5051_adc_nids[2] = { 0x14, 0x15 };
1618
1619 static const struct hda_channel_mode cxt5051_modes[1] = {
1620         { 2, NULL },
1621 };
1622
1623 static void cxt5051_update_speaker(struct hda_codec *codec)
1624 {
1625         struct conexant_spec *spec = codec->spec;
1626         unsigned int pinctl;
1627         /* headphone pin */
1628         pinctl = (spec->hp_present && spec->cur_eapd) ? PIN_HP : 0;
1629         snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
1630                             pinctl);
1631         /* speaker pin */
1632         pinctl = (!spec->hp_present && spec->cur_eapd) ? PIN_OUT : 0;
1633         snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
1634                             pinctl);
1635         /* on ideapad there is an aditional speaker (subwoofer) to mute */
1636         if (spec->ideapad)
1637                 snd_hda_codec_write(codec, 0x1b, 0,
1638                                     AC_VERB_SET_PIN_WIDGET_CONTROL,
1639                                     pinctl);
1640 }
1641
1642 /* turn on/off EAPD (+ mute HP) as a master switch */
1643 static int cxt5051_hp_master_sw_put(struct snd_kcontrol *kcontrol,
1644                                     struct snd_ctl_elem_value *ucontrol)
1645 {
1646         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1647
1648         if (!cxt_eapd_put(kcontrol, ucontrol))
1649                 return 0;
1650         cxt5051_update_speaker(codec);
1651         return 1;
1652 }
1653
1654 /* toggle input of built-in and mic jack appropriately */
1655 static void cxt5051_portb_automic(struct hda_codec *codec)
1656 {
1657         struct conexant_spec *spec = codec->spec;
1658         unsigned int present;
1659
1660         if (!(spec->auto_mic & AUTO_MIC_PORTB))
1661                 return;
1662         present = snd_hda_jack_detect(codec, 0x17);
1663         snd_hda_codec_write(codec, 0x14, 0,
1664                             AC_VERB_SET_CONNECT_SEL,
1665                             present ? 0x01 : 0x00);
1666 }
1667
1668 /* switch the current ADC according to the jack state */
1669 static void cxt5051_portc_automic(struct hda_codec *codec)
1670 {
1671         struct conexant_spec *spec = codec->spec;
1672         unsigned int present;
1673         hda_nid_t new_adc;
1674
1675         if (!(spec->auto_mic & AUTO_MIC_PORTC))
1676                 return;
1677         present = snd_hda_jack_detect(codec, 0x18);
1678         if (present)
1679                 spec->cur_adc_idx = 1;
1680         else
1681                 spec->cur_adc_idx = 0;
1682         new_adc = spec->adc_nids[spec->cur_adc_idx];
1683         if (spec->cur_adc && spec->cur_adc != new_adc) {
1684                 /* stream is running, let's swap the current ADC */
1685                 __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1);
1686                 spec->cur_adc = new_adc;
1687                 snd_hda_codec_setup_stream(codec, new_adc,
1688                                            spec->cur_adc_stream_tag, 0,
1689                                            spec->cur_adc_format);
1690         }
1691 }
1692
1693 /* mute internal speaker if HP is plugged */
1694 static void cxt5051_hp_automute(struct hda_codec *codec)
1695 {
1696         struct conexant_spec *spec = codec->spec;
1697
1698         spec->hp_present = snd_hda_jack_detect(codec, 0x16);
1699         cxt5051_update_speaker(codec);
1700 }
1701
1702 /* unsolicited event for HP jack sensing */
1703 static void cxt5051_hp_unsol_event(struct hda_codec *codec,
1704                                    unsigned int res)
1705 {
1706         switch (res >> 26) {
1707         case CONEXANT_HP_EVENT:
1708                 cxt5051_hp_automute(codec);
1709                 break;
1710         case CXT5051_PORTB_EVENT:
1711                 cxt5051_portb_automic(codec);
1712                 break;
1713         case CXT5051_PORTC_EVENT:
1714                 cxt5051_portc_automic(codec);
1715                 break;
1716         }
1717 }
1718
1719 static const struct snd_kcontrol_new cxt5051_playback_mixers[] = {
1720         HDA_CODEC_VOLUME("Master Playback Volume", 0x10, 0x00, HDA_OUTPUT),
1721         {
1722                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1723                 .name = "Master Playback Switch",
1724                 .info = cxt_eapd_info,
1725                 .get = cxt_eapd_get,
1726                 .put = cxt5051_hp_master_sw_put,
1727                 .private_value = 0x1a,
1728         },
1729         {}
1730 };
1731
1732 static const struct snd_kcontrol_new cxt5051_capture_mixers[] = {
1733         HDA_CODEC_VOLUME("Internal Mic Volume", 0x14, 0x00, HDA_INPUT),
1734         HDA_CODEC_MUTE("Internal Mic Switch", 0x14, 0x00, HDA_INPUT),
1735         HDA_CODEC_VOLUME("Mic Volume", 0x14, 0x01, HDA_INPUT),
1736         HDA_CODEC_MUTE("Mic Switch", 0x14, 0x01, HDA_INPUT),
1737         HDA_CODEC_VOLUME("Docking Mic Volume", 0x15, 0x00, HDA_INPUT),
1738         HDA_CODEC_MUTE("Docking Mic Switch", 0x15, 0x00, HDA_INPUT),
1739         {}
1740 };
1741
1742 static const struct snd_kcontrol_new cxt5051_hp_mixers[] = {
1743         HDA_CODEC_VOLUME("Internal Mic Volume", 0x14, 0x00, HDA_INPUT),
1744         HDA_CODEC_MUTE("Internal Mic Switch", 0x14, 0x00, HDA_INPUT),
1745         HDA_CODEC_VOLUME("Mic Volume", 0x15, 0x00, HDA_INPUT),
1746         HDA_CODEC_MUTE("Mic Switch", 0x15, 0x00, HDA_INPUT),
1747         {}
1748 };
1749
1750 static const struct snd_kcontrol_new cxt5051_hp_dv6736_mixers[] = {
1751         HDA_CODEC_VOLUME("Capture Volume", 0x14, 0x00, HDA_INPUT),
1752         HDA_CODEC_MUTE("Capture Switch", 0x14, 0x00, HDA_INPUT),
1753         {}
1754 };
1755
1756 static const struct snd_kcontrol_new cxt5051_f700_mixers[] = {
1757         HDA_CODEC_VOLUME("Capture Volume", 0x14, 0x01, HDA_INPUT),
1758         HDA_CODEC_MUTE("Capture Switch", 0x14, 0x01, HDA_INPUT),
1759         {}
1760 };
1761
1762 static const struct snd_kcontrol_new cxt5051_toshiba_mixers[] = {
1763         HDA_CODEC_VOLUME("Internal Mic Volume", 0x14, 0x00, HDA_INPUT),
1764         HDA_CODEC_MUTE("Internal Mic Switch", 0x14, 0x00, HDA_INPUT),
1765         HDA_CODEC_VOLUME("Mic Volume", 0x14, 0x01, HDA_INPUT),
1766         HDA_CODEC_MUTE("Mic Switch", 0x14, 0x01, HDA_INPUT),
1767         {}
1768 };
1769
1770 static const struct hda_verb cxt5051_init_verbs[] = {
1771         /* Line in, Mic */
1772         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03},
1773         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1774         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03},
1775         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1776         {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1777         {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03},
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: Internal mic */
1787         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x44},
1788         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1) | 0x44},
1789         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x44},
1790         /* SPDIF route: PCM */
1791         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1792         {0x1c, AC_VERB_SET_CONNECT_SEL, 0x0},
1793         /* EAPD */
1794         {0x1a, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */ 
1795         {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CONEXANT_HP_EVENT},
1796         { } /* end */
1797 };
1798
1799 static const struct hda_verb cxt5051_hp_dv6736_init_verbs[] = {
1800         /* Line in, Mic */
1801         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03},
1802         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1803         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0},
1804         {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0},
1805         /* SPK  */
1806         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1807         {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
1808         /* HP, Amp  */
1809         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1810         {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
1811         /* DAC1 */
1812         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1813         /* Record selector: Internal mic */
1814         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1) | 0x44},
1815         {0x14, AC_VERB_SET_CONNECT_SEL, 0x1},
1816         /* SPDIF route: PCM */
1817         {0x1c, AC_VERB_SET_CONNECT_SEL, 0x0},
1818         /* EAPD */
1819         {0x1a, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
1820         {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CONEXANT_HP_EVENT},
1821         { } /* end */
1822 };
1823
1824 static const struct hda_verb cxt5051_f700_init_verbs[] = {
1825         /* Line in, Mic */
1826         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03},
1827         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1828         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0},
1829         {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0},
1830         /* SPK  */
1831         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1832         {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
1833         /* HP, Amp  */
1834         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1835         {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
1836         /* DAC1 */
1837         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1838         /* Record selector: Internal mic */
1839         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1) | 0x44},
1840         {0x14, AC_VERB_SET_CONNECT_SEL, 0x1},
1841         /* SPDIF route: PCM */
1842         {0x1c, AC_VERB_SET_CONNECT_SEL, 0x0},
1843         /* EAPD */
1844         {0x1a, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
1845         {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CONEXANT_HP_EVENT},
1846         { } /* end */
1847 };
1848
1849 static void cxt5051_init_mic_port(struct hda_codec *codec, hda_nid_t nid,
1850                                  unsigned int event)
1851 {
1852         snd_hda_codec_write(codec, nid, 0,
1853                             AC_VERB_SET_UNSOLICITED_ENABLE,
1854                             AC_USRSP_EN | event);
1855 }
1856
1857 static const struct hda_verb cxt5051_ideapad_init_verbs[] = {
1858         /* Subwoofer */
1859         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1860         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1861         { } /* end */
1862 };
1863
1864 /* initialize jack-sensing, too */
1865 static int cxt5051_init(struct hda_codec *codec)
1866 {
1867         struct conexant_spec *spec = codec->spec;
1868
1869         conexant_init(codec);
1870
1871         if (spec->auto_mic & AUTO_MIC_PORTB)
1872                 cxt5051_init_mic_port(codec, 0x17, CXT5051_PORTB_EVENT);
1873         if (spec->auto_mic & AUTO_MIC_PORTC)
1874                 cxt5051_init_mic_port(codec, 0x18, CXT5051_PORTC_EVENT);
1875
1876         if (codec->patch_ops.unsol_event) {
1877                 cxt5051_hp_automute(codec);
1878                 cxt5051_portb_automic(codec);
1879                 cxt5051_portc_automic(codec);
1880         }
1881         return 0;
1882 }
1883
1884
1885 enum {
1886         CXT5051_LAPTOP,  /* Laptops w/ EAPD support */
1887         CXT5051_HP,     /* no docking */
1888         CXT5051_HP_DV6736,      /* HP without mic switch */
1889         CXT5051_F700,       /* HP Compaq Presario F700 */
1890         CXT5051_TOSHIBA,        /* Toshiba M300 & co */
1891         CXT5051_IDEAPAD,        /* Lenovo IdeaPad Y430 */
1892         CXT5051_AUTO,           /* auto-parser */
1893         CXT5051_MODELS
1894 };
1895
1896 static const char *const cxt5051_models[CXT5051_MODELS] = {
1897         [CXT5051_LAPTOP]        = "laptop",
1898         [CXT5051_HP]            = "hp",
1899         [CXT5051_HP_DV6736]     = "hp-dv6736",
1900         [CXT5051_F700]          = "hp-700",
1901         [CXT5051_TOSHIBA]       = "toshiba",
1902         [CXT5051_IDEAPAD]       = "ideapad",
1903         [CXT5051_AUTO]          = "auto",
1904 };
1905
1906 static const struct snd_pci_quirk cxt5051_cfg_tbl[] = {
1907         SND_PCI_QUIRK(0x103c, 0x30cf, "HP DV6736", CXT5051_HP_DV6736),
1908         SND_PCI_QUIRK(0x103c, 0x360b, "Compaq Presario CQ60", CXT5051_HP),
1909         SND_PCI_QUIRK(0x103c, 0x30ea, "Compaq Presario F700", CXT5051_F700),
1910         SND_PCI_QUIRK(0x1179, 0xff50, "Toshiba M30x", CXT5051_TOSHIBA),
1911         SND_PCI_QUIRK(0x14f1, 0x0101, "Conexant Reference board",
1912                       CXT5051_LAPTOP),
1913         SND_PCI_QUIRK(0x14f1, 0x5051, "HP Spartan 1.1", CXT5051_HP),
1914         SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo IdeaPad", CXT5051_IDEAPAD),
1915         {}
1916 };
1917
1918 static int patch_cxt5051(struct hda_codec *codec)
1919 {
1920         struct conexant_spec *spec;
1921         int board_config;
1922
1923         board_config = snd_hda_check_board_config(codec, CXT5051_MODELS,
1924                                                   cxt5051_models,
1925                                                   cxt5051_cfg_tbl);
1926         if (board_config < 0)
1927                 board_config = CXT5051_AUTO; /* model=auto as default */
1928         if (board_config == CXT5051_AUTO)
1929                 return patch_conexant_auto(codec);
1930
1931         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1932         if (!spec)
1933                 return -ENOMEM;
1934         codec->spec = spec;
1935         codec->pin_amp_workaround = 1;
1936
1937         codec->patch_ops = conexant_patch_ops;
1938         codec->patch_ops.init = cxt5051_init;
1939
1940         spec->multiout.max_channels = 2;
1941         spec->multiout.num_dacs = ARRAY_SIZE(cxt5051_dac_nids);
1942         spec->multiout.dac_nids = cxt5051_dac_nids;
1943         spec->multiout.dig_out_nid = CXT5051_SPDIF_OUT;
1944         spec->num_adc_nids = 1; /* not 2; via auto-mic switch */
1945         spec->adc_nids = cxt5051_adc_nids;
1946         spec->num_mixers = 2;
1947         spec->mixers[0] = cxt5051_capture_mixers;
1948         spec->mixers[1] = cxt5051_playback_mixers;
1949         spec->num_init_verbs = 1;
1950         spec->init_verbs[0] = cxt5051_init_verbs;
1951         spec->spdif_route = 0;
1952         spec->num_channel_mode = ARRAY_SIZE(cxt5051_modes);
1953         spec->channel_mode = cxt5051_modes;
1954         spec->cur_adc = 0;
1955         spec->cur_adc_idx = 0;
1956
1957         set_beep_amp(spec, 0x13, 0, HDA_OUTPUT);
1958
1959         codec->patch_ops.unsol_event = cxt5051_hp_unsol_event;
1960
1961         spec->auto_mic = AUTO_MIC_PORTB | AUTO_MIC_PORTC;
1962         switch (board_config) {
1963         case CXT5051_HP:
1964                 spec->mixers[0] = cxt5051_hp_mixers;
1965                 break;
1966         case CXT5051_HP_DV6736:
1967                 spec->init_verbs[0] = cxt5051_hp_dv6736_init_verbs;
1968                 spec->mixers[0] = cxt5051_hp_dv6736_mixers;
1969                 spec->auto_mic = 0;
1970                 break;
1971         case CXT5051_F700:
1972                 spec->init_verbs[0] = cxt5051_f700_init_verbs;
1973                 spec->mixers[0] = cxt5051_f700_mixers;
1974                 spec->auto_mic = 0;
1975                 break;
1976         case CXT5051_TOSHIBA:
1977                 spec->mixers[0] = cxt5051_toshiba_mixers;
1978                 spec->auto_mic = AUTO_MIC_PORTB;
1979                 break;
1980         case CXT5051_IDEAPAD:
1981                 spec->init_verbs[spec->num_init_verbs++] =
1982                         cxt5051_ideapad_init_verbs;
1983                 spec->ideapad = 1;
1984                 break;
1985         }
1986
1987         if (spec->beep_amp)
1988                 snd_hda_attach_beep_device(codec, spec->beep_amp);
1989
1990         return 0;
1991 }
1992
1993 /* Conexant 5066 specific */
1994
1995 static const hda_nid_t cxt5066_dac_nids[1] = { 0x10 };
1996 static const hda_nid_t cxt5066_adc_nids[3] = { 0x14, 0x15, 0x16 };
1997 static const hda_nid_t cxt5066_capsrc_nids[1] = { 0x17 };
1998 static const hda_nid_t cxt5066_digout_pin_nids[2] = { 0x20, 0x22 };
1999
2000 /* OLPC's microphone port is DC coupled for use with external sensors,
2001  * therefore we use a 50% mic bias in order to center the input signal with
2002  * the DC input range of the codec. */
2003 #define CXT5066_OLPC_EXT_MIC_BIAS PIN_VREF50
2004
2005 static const struct hda_channel_mode cxt5066_modes[1] = {
2006         { 2, NULL },
2007 };
2008
2009 #define HP_PRESENT_PORT_A       (1 << 0)
2010 #define HP_PRESENT_PORT_D       (1 << 1)
2011 #define hp_port_a_present(spec) ((spec)->hp_present & HP_PRESENT_PORT_A)
2012 #define hp_port_d_present(spec) ((spec)->hp_present & HP_PRESENT_PORT_D)
2013
2014 static void cxt5066_update_speaker(struct hda_codec *codec)
2015 {
2016         struct conexant_spec *spec = codec->spec;
2017         unsigned int pinctl;
2018
2019         snd_printdd("CXT5066: update speaker, hp_present=%d, cur_eapd=%d\n",
2020                     spec->hp_present, spec->cur_eapd);
2021
2022         /* Port A (HP) */
2023         pinctl = (hp_port_a_present(spec) && spec->cur_eapd) ? PIN_HP : 0;
2024         snd_hda_codec_write(codec, 0x19, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
2025                         pinctl);
2026
2027         /* Port D (HP/LO) */
2028         pinctl = spec->cur_eapd ? spec->port_d_mode : 0;
2029         if (spec->dell_automute || spec->thinkpad) {
2030                 /* Mute if Port A is connected */
2031                 if (hp_port_a_present(spec))
2032                         pinctl = 0;
2033         } else {
2034                 /* Thinkpad/Dell doesn't give pin-D status */
2035                 if (!hp_port_d_present(spec))
2036                         pinctl = 0;
2037         }
2038         snd_hda_codec_write(codec, 0x1c, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
2039                         pinctl);
2040
2041         /* CLASS_D AMP */
2042         pinctl = (!spec->hp_present && spec->cur_eapd) ? PIN_OUT : 0;
2043         snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
2044                         pinctl);
2045 }
2046
2047 /* turn on/off EAPD (+ mute HP) as a master switch */
2048 static int cxt5066_hp_master_sw_put(struct snd_kcontrol *kcontrol,
2049                                     struct snd_ctl_elem_value *ucontrol)
2050 {
2051         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2052
2053         if (!cxt_eapd_put(kcontrol, ucontrol))
2054                 return 0;
2055
2056         cxt5066_update_speaker(codec);
2057         return 1;
2058 }
2059
2060 static const struct hda_input_mux cxt5066_olpc_dc_bias = {
2061         .num_items = 3,
2062         .items = {
2063                 { "Off", PIN_IN },
2064                 { "50%", PIN_VREF50 },
2065                 { "80%", PIN_VREF80 },
2066         },
2067 };
2068
2069 static int cxt5066_set_olpc_dc_bias(struct hda_codec *codec)
2070 {
2071         struct conexant_spec *spec = codec->spec;
2072         /* Even though port F is the DC input, the bias is controlled on port B.
2073          * we also leave that port as an active input (but unselected) in DC mode
2074          * just in case that is necessary to make the bias setting take effect. */
2075         return snd_hda_codec_write_cache(codec, 0x1a, 0,
2076                 AC_VERB_SET_PIN_WIDGET_CONTROL,
2077                 cxt5066_olpc_dc_bias.items[spec->dc_input_bias].index);
2078 }
2079
2080 /* OLPC defers mic widget control until when capture is started because the
2081  * microphone LED comes on as soon as these settings are put in place. if we
2082  * did this before recording, it would give the false indication that recording
2083  * is happening when it is not. */
2084 static void cxt5066_olpc_select_mic(struct hda_codec *codec)
2085 {
2086         struct conexant_spec *spec = codec->spec;
2087         if (!spec->recording)
2088                 return;
2089
2090         if (spec->dc_enable) {
2091                 /* in DC mode we ignore presence detection and just use the jack
2092                  * through our special DC port */
2093                 const struct hda_verb enable_dc_mode[] = {
2094                         /* disble internal mic, port C */
2095                         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2096
2097                         /* enable DC capture, port F */
2098                         {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2099                         {},
2100                 };
2101
2102                 snd_hda_sequence_write(codec, enable_dc_mode);
2103                 /* port B input disabled (and bias set) through the following call */
2104                 cxt5066_set_olpc_dc_bias(codec);
2105                 return;
2106         }
2107
2108         /* disable DC (port F) */
2109         snd_hda_codec_write(codec, 0x1e, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
2110
2111         /* external mic, port B */
2112         snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
2113                 spec->ext_mic_present ? CXT5066_OLPC_EXT_MIC_BIAS : 0);
2114
2115         /* internal mic, port C */
2116         snd_hda_codec_write(codec, 0x1b, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
2117                 spec->ext_mic_present ? 0 : PIN_VREF80);
2118 }
2119
2120 /* toggle input of built-in and mic jack appropriately */
2121 static void cxt5066_olpc_automic(struct hda_codec *codec)
2122 {
2123         struct conexant_spec *spec = codec->spec;
2124         unsigned int present;
2125
2126         if (spec->dc_enable) /* don't do presence detection in DC mode */
2127                 return;
2128
2129         present = snd_hda_codec_read(codec, 0x1a, 0,
2130                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2131         if (present)
2132                 snd_printdd("CXT5066: external microphone detected\n");
2133         else
2134                 snd_printdd("CXT5066: external microphone absent\n");
2135
2136         snd_hda_codec_write(codec, 0x17, 0, AC_VERB_SET_CONNECT_SEL,
2137                 present ? 0 : 1);
2138         spec->ext_mic_present = !!present;
2139
2140         cxt5066_olpc_select_mic(codec);
2141 }
2142
2143 /* toggle input of built-in digital mic and mic jack appropriately */
2144 static void cxt5066_vostro_automic(struct hda_codec *codec)
2145 {
2146         unsigned int present;
2147
2148         struct hda_verb ext_mic_present[] = {
2149                 /* enable external mic, port B */
2150                 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2151
2152                 /* switch to external mic input */
2153                 {0x17, AC_VERB_SET_CONNECT_SEL, 0},
2154                 {0x14, AC_VERB_SET_CONNECT_SEL, 0},
2155
2156                 /* disable internal digital mic */
2157                 {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2158                 {}
2159         };
2160         static const struct hda_verb ext_mic_absent[] = {
2161                 /* enable internal mic, port C */
2162                 {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2163
2164                 /* switch to internal mic input */
2165                 {0x14, AC_VERB_SET_CONNECT_SEL, 2},
2166
2167                 /* disable external mic, port B */
2168                 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2169                 {}
2170         };
2171
2172         present = snd_hda_jack_detect(codec, 0x1a);
2173         if (present) {
2174                 snd_printdd("CXT5066: external microphone detected\n");
2175                 snd_hda_sequence_write(codec, ext_mic_present);
2176         } else {
2177                 snd_printdd("CXT5066: external microphone absent\n");
2178                 snd_hda_sequence_write(codec, ext_mic_absent);
2179         }
2180 }
2181
2182 /* toggle input of built-in digital mic and mic jack appropriately */
2183 static void cxt5066_ideapad_automic(struct hda_codec *codec)
2184 {
2185         unsigned int present;
2186
2187         struct hda_verb ext_mic_present[] = {
2188                 {0x14, AC_VERB_SET_CONNECT_SEL, 0},
2189                 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2190                 {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2191                 {}
2192         };
2193         static const struct hda_verb ext_mic_absent[] = {
2194                 {0x14, AC_VERB_SET_CONNECT_SEL, 2},
2195                 {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2196                 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2197                 {}
2198         };
2199
2200         present = snd_hda_jack_detect(codec, 0x1b);
2201         if (present) {
2202                 snd_printdd("CXT5066: external microphone detected\n");
2203                 snd_hda_sequence_write(codec, ext_mic_present);
2204         } else {
2205                 snd_printdd("CXT5066: external microphone absent\n");
2206                 snd_hda_sequence_write(codec, ext_mic_absent);
2207         }
2208 }
2209
2210
2211 /* toggle input of built-in digital mic and mic jack appropriately */
2212 static void cxt5066_asus_automic(struct hda_codec *codec)
2213 {
2214         unsigned int present;
2215
2216         present = snd_hda_jack_detect(codec, 0x1b);
2217         snd_printdd("CXT5066: external microphone present=%d\n", present);
2218         snd_hda_codec_write(codec, 0x17, 0, AC_VERB_SET_CONNECT_SEL,
2219                             present ? 1 : 0);
2220 }
2221
2222
2223 /* toggle input of built-in digital mic and mic jack appropriately */
2224 static void cxt5066_hp_laptop_automic(struct hda_codec *codec)
2225 {
2226         unsigned int present;
2227
2228         present = snd_hda_jack_detect(codec, 0x1b);
2229         snd_printdd("CXT5066: external microphone present=%d\n", present);
2230         snd_hda_codec_write(codec, 0x17, 0, AC_VERB_SET_CONNECT_SEL,
2231                             present ? 1 : 3);
2232 }
2233
2234
2235 /* toggle input of built-in digital mic and mic jack appropriately
2236    order is: external mic -> dock mic -> interal mic */
2237 static void cxt5066_thinkpad_automic(struct hda_codec *codec)
2238 {
2239         unsigned int ext_present, dock_present;
2240
2241         static const struct hda_verb ext_mic_present[] = {
2242                 {0x14, AC_VERB_SET_CONNECT_SEL, 0},
2243                 {0x17, AC_VERB_SET_CONNECT_SEL, 1},
2244                 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2245                 {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2246                 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2247                 {}
2248         };
2249         static const struct hda_verb dock_mic_present[] = {
2250                 {0x14, AC_VERB_SET_CONNECT_SEL, 0},
2251                 {0x17, AC_VERB_SET_CONNECT_SEL, 0},
2252                 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2253                 {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2254                 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2255                 {}
2256         };
2257         static const struct hda_verb ext_mic_absent[] = {
2258                 {0x14, AC_VERB_SET_CONNECT_SEL, 2},
2259                 {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2260                 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2261                 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2262                 {}
2263         };
2264
2265         ext_present = snd_hda_jack_detect(codec, 0x1b);
2266         dock_present = snd_hda_jack_detect(codec, 0x1a);
2267         if (ext_present) {
2268                 snd_printdd("CXT5066: external microphone detected\n");
2269                 snd_hda_sequence_write(codec, ext_mic_present);
2270         } else if (dock_present) {
2271                 snd_printdd("CXT5066: dock microphone detected\n");
2272                 snd_hda_sequence_write(codec, dock_mic_present);
2273         } else {
2274                 snd_printdd("CXT5066: external microphone absent\n");
2275                 snd_hda_sequence_write(codec, ext_mic_absent);
2276         }
2277 }
2278
2279 /* mute internal speaker if HP is plugged */
2280 static void cxt5066_hp_automute(struct hda_codec *codec)
2281 {
2282         struct conexant_spec *spec = codec->spec;
2283         unsigned int portA, portD;
2284
2285         /* Port A */
2286         portA = snd_hda_jack_detect(codec, 0x19);
2287
2288         /* Port D */
2289         portD = snd_hda_jack_detect(codec, 0x1c);
2290
2291         spec->hp_present = portA ? HP_PRESENT_PORT_A : 0;
2292         spec->hp_present |= portD ? HP_PRESENT_PORT_D : 0;
2293         snd_printdd("CXT5066: hp automute portA=%x portD=%x present=%d\n",
2294                 portA, portD, spec->hp_present);
2295         cxt5066_update_speaker(codec);
2296 }
2297
2298 /* Dispatch the right mic autoswitch function */
2299 static void cxt5066_automic(struct hda_codec *codec)
2300 {
2301         struct conexant_spec *spec = codec->spec;
2302
2303         if (spec->dell_vostro)
2304                 cxt5066_vostro_automic(codec);
2305         else if (spec->ideapad)
2306                 cxt5066_ideapad_automic(codec);
2307         else if (spec->thinkpad)
2308                 cxt5066_thinkpad_automic(codec);
2309         else if (spec->hp_laptop)
2310                 cxt5066_hp_laptop_automic(codec);
2311         else if (spec->asus)
2312                 cxt5066_asus_automic(codec);
2313 }
2314
2315 /* unsolicited event for jack sensing */
2316 static void cxt5066_olpc_unsol_event(struct hda_codec *codec, unsigned int res)
2317 {
2318         struct conexant_spec *spec = codec->spec;
2319         snd_printdd("CXT5066: unsol event %x (%x)\n", res, res >> 26);
2320         switch (res >> 26) {
2321         case CONEXANT_HP_EVENT:
2322                 cxt5066_hp_automute(codec);
2323                 break;
2324         case CONEXANT_MIC_EVENT:
2325                 /* ignore mic events in DC mode; we're always using the jack */
2326                 if (!spec->dc_enable)
2327                         cxt5066_olpc_automic(codec);
2328                 break;
2329         }
2330 }
2331
2332 /* unsolicited event for jack sensing */
2333 static void cxt5066_unsol_event(struct hda_codec *codec, unsigned int res)
2334 {
2335         snd_printdd("CXT5066: unsol event %x (%x)\n", res, res >> 26);
2336         switch (res >> 26) {
2337         case CONEXANT_HP_EVENT:
2338                 cxt5066_hp_automute(codec);
2339                 break;
2340         case CONEXANT_MIC_EVENT:
2341                 cxt5066_automic(codec);
2342                 break;
2343         }
2344 }
2345
2346
2347 static const struct hda_input_mux cxt5066_analog_mic_boost = {
2348         .num_items = 5,
2349         .items = {
2350                 { "0dB",  0 },
2351                 { "10dB", 1 },
2352                 { "20dB", 2 },
2353                 { "30dB", 3 },
2354                 { "40dB", 4 },
2355         },
2356 };
2357
2358 static void cxt5066_set_mic_boost(struct hda_codec *codec)
2359 {
2360         struct conexant_spec *spec = codec->spec;
2361         snd_hda_codec_write_cache(codec, 0x17, 0,
2362                 AC_VERB_SET_AMP_GAIN_MUTE,
2363                 AC_AMP_SET_RIGHT | AC_AMP_SET_LEFT | AC_AMP_SET_OUTPUT |
2364                         cxt5066_analog_mic_boost.items[spec->mic_boost].index);
2365         if (spec->ideapad || spec->thinkpad) {
2366                 /* adjust the internal mic as well...it is not through 0x17 */
2367                 snd_hda_codec_write_cache(codec, 0x23, 0,
2368                         AC_VERB_SET_AMP_GAIN_MUTE,
2369                         AC_AMP_SET_RIGHT | AC_AMP_SET_LEFT | AC_AMP_SET_INPUT |
2370                                 cxt5066_analog_mic_boost.
2371                                         items[spec->mic_boost].index);
2372         }
2373 }
2374
2375 static int cxt5066_mic_boost_mux_enum_info(struct snd_kcontrol *kcontrol,
2376                                            struct snd_ctl_elem_info *uinfo)
2377 {
2378         return snd_hda_input_mux_info(&cxt5066_analog_mic_boost, uinfo);
2379 }
2380
2381 static int cxt5066_mic_boost_mux_enum_get(struct snd_kcontrol *kcontrol,
2382                                           struct snd_ctl_elem_value *ucontrol)
2383 {
2384         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2385         struct conexant_spec *spec = codec->spec;
2386         ucontrol->value.enumerated.item[0] = spec->mic_boost;
2387         return 0;
2388 }
2389
2390 static int cxt5066_mic_boost_mux_enum_put(struct snd_kcontrol *kcontrol,
2391                                           struct snd_ctl_elem_value *ucontrol)
2392 {
2393         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2394         struct conexant_spec *spec = codec->spec;
2395         const struct hda_input_mux *imux = &cxt5066_analog_mic_boost;
2396         unsigned int idx;
2397         idx = ucontrol->value.enumerated.item[0];
2398         if (idx >= imux->num_items)
2399                 idx = imux->num_items - 1;
2400
2401         spec->mic_boost = idx;
2402         if (!spec->dc_enable)
2403                 cxt5066_set_mic_boost(codec);
2404         return 1;
2405 }
2406
2407 static void cxt5066_enable_dc(struct hda_codec *codec)
2408 {
2409         const struct hda_verb enable_dc_mode[] = {
2410                 /* disable gain */
2411                 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2412
2413                 /* switch to DC input */
2414                 {0x17, AC_VERB_SET_CONNECT_SEL, 3},
2415                 {}
2416         };
2417
2418         /* configure as input source */
2419         snd_hda_sequence_write(codec, enable_dc_mode);
2420         cxt5066_olpc_select_mic(codec); /* also sets configured bias */
2421 }
2422
2423 static void cxt5066_disable_dc(struct hda_codec *codec)
2424 {
2425         /* reconfigure input source */
2426         cxt5066_set_mic_boost(codec);
2427         /* automic also selects the right mic if we're recording */
2428         cxt5066_olpc_automic(codec);
2429 }
2430
2431 static int cxt5066_olpc_dc_get(struct snd_kcontrol *kcontrol,
2432                              struct snd_ctl_elem_value *ucontrol)
2433 {
2434         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2435         struct conexant_spec *spec = codec->spec;
2436         ucontrol->value.integer.value[0] = spec->dc_enable;
2437         return 0;
2438 }
2439
2440 static int cxt5066_olpc_dc_put(struct snd_kcontrol *kcontrol,
2441                              struct snd_ctl_elem_value *ucontrol)
2442 {
2443         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2444         struct conexant_spec *spec = codec->spec;
2445         int dc_enable = !!ucontrol->value.integer.value[0];
2446
2447         if (dc_enable == spec->dc_enable)
2448                 return 0;
2449
2450         spec->dc_enable = dc_enable;
2451         if (dc_enable)
2452                 cxt5066_enable_dc(codec);
2453         else
2454                 cxt5066_disable_dc(codec);
2455
2456         return 1;
2457 }
2458
2459 static int cxt5066_olpc_dc_bias_enum_info(struct snd_kcontrol *kcontrol,
2460                                            struct snd_ctl_elem_info *uinfo)
2461 {
2462         return snd_hda_input_mux_info(&cxt5066_olpc_dc_bias, uinfo);
2463 }
2464
2465 static int cxt5066_olpc_dc_bias_enum_get(struct snd_kcontrol *kcontrol,
2466                                           struct snd_ctl_elem_value *ucontrol)
2467 {
2468         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2469         struct conexant_spec *spec = codec->spec;
2470         ucontrol->value.enumerated.item[0] = spec->dc_input_bias;
2471         return 0;
2472 }
2473
2474 static int cxt5066_olpc_dc_bias_enum_put(struct snd_kcontrol *kcontrol,
2475                                           struct snd_ctl_elem_value *ucontrol)
2476 {
2477         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2478         struct conexant_spec *spec = codec->spec;
2479         const struct hda_input_mux *imux = &cxt5066_analog_mic_boost;
2480         unsigned int idx;
2481
2482         idx = ucontrol->value.enumerated.item[0];
2483         if (idx >= imux->num_items)
2484                 idx = imux->num_items - 1;
2485
2486         spec->dc_input_bias = idx;
2487         if (spec->dc_enable)
2488                 cxt5066_set_olpc_dc_bias(codec);
2489         return 1;
2490 }
2491
2492 static void cxt5066_olpc_capture_prepare(struct hda_codec *codec)
2493 {
2494         struct conexant_spec *spec = codec->spec;
2495         /* mark as recording and configure the microphone widget so that the
2496          * recording LED comes on. */
2497         spec->recording = 1;
2498         cxt5066_olpc_select_mic(codec);
2499 }
2500
2501 static void cxt5066_olpc_capture_cleanup(struct hda_codec *codec)
2502 {
2503         struct conexant_spec *spec = codec->spec;
2504         const struct hda_verb disable_mics[] = {
2505                 /* disable external mic, port B */
2506                 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2507
2508                 /* disble internal mic, port C */
2509                 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2510
2511                 /* disable DC capture, port F */
2512                 {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2513                 {},
2514         };
2515
2516         snd_hda_sequence_write(codec, disable_mics);
2517         spec->recording = 0;
2518 }
2519
2520 static void conexant_check_dig_outs(struct hda_codec *codec,
2521                                     const hda_nid_t *dig_pins,
2522                                     int num_pins)
2523 {
2524         struct conexant_spec *spec = codec->spec;
2525         hda_nid_t *nid_loc = &spec->multiout.dig_out_nid;
2526         int i;
2527
2528         for (i = 0; i < num_pins; i++, dig_pins++) {
2529                 unsigned int cfg = snd_hda_codec_get_pincfg(codec, *dig_pins);
2530                 if (get_defcfg_connect(cfg) == AC_JACK_PORT_NONE)
2531                         continue;
2532                 if (snd_hda_get_connections(codec, *dig_pins, nid_loc, 1) != 1)
2533                         continue;
2534                 if (spec->slave_dig_outs[0])
2535                         nid_loc++;
2536                 else
2537                         nid_loc = spec->slave_dig_outs;
2538         }
2539 }
2540
2541 static const struct hda_input_mux cxt5066_capture_source = {
2542         .num_items = 4,
2543         .items = {
2544                 { "Mic B", 0 },
2545                 { "Mic C", 1 },
2546                 { "Mic E", 2 },
2547                 { "Mic F", 3 },
2548         },
2549 };
2550
2551 static const struct hda_bind_ctls cxt5066_bind_capture_vol_others = {
2552         .ops = &snd_hda_bind_vol,
2553         .values = {
2554                 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_INPUT),
2555                 HDA_COMPOSE_AMP_VAL(0x14, 3, 2, HDA_INPUT),
2556                 0
2557         },
2558 };
2559
2560 static const struct hda_bind_ctls cxt5066_bind_capture_sw_others = {
2561         .ops = &snd_hda_bind_sw,
2562         .values = {
2563                 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_INPUT),
2564                 HDA_COMPOSE_AMP_VAL(0x14, 3, 2, HDA_INPUT),
2565                 0
2566         },
2567 };
2568
2569 static const struct snd_kcontrol_new cxt5066_mixer_master[] = {
2570         HDA_CODEC_VOLUME("Master Playback Volume", 0x10, 0x00, HDA_OUTPUT),
2571         {}
2572 };
2573
2574 static const struct snd_kcontrol_new cxt5066_mixer_master_olpc[] = {
2575         {
2576                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2577                 .name = "Master Playback Volume",
2578                 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
2579                                   SNDRV_CTL_ELEM_ACCESS_TLV_READ |
2580                                   SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK,
2581                 .subdevice = HDA_SUBDEV_AMP_FLAG,
2582                 .info = snd_hda_mixer_amp_volume_info,
2583                 .get = snd_hda_mixer_amp_volume_get,
2584                 .put = snd_hda_mixer_amp_volume_put,
2585                 .tlv = { .c = snd_hda_mixer_amp_tlv },
2586                 /* offset by 28 volume steps to limit minimum gain to -46dB */
2587                 .private_value =
2588                         HDA_COMPOSE_AMP_VAL_OFS(0x10, 3, 0, HDA_OUTPUT, 28),
2589         },
2590         {}
2591 };
2592
2593 static const struct snd_kcontrol_new cxt5066_mixer_olpc_dc[] = {
2594         {
2595                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2596                 .name = "DC Mode Enable Switch",
2597                 .info = snd_ctl_boolean_mono_info,
2598                 .get = cxt5066_olpc_dc_get,
2599                 .put = cxt5066_olpc_dc_put,
2600         },
2601         {
2602                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2603                 .name = "DC Input Bias Enum",
2604                 .info = cxt5066_olpc_dc_bias_enum_info,
2605                 .get = cxt5066_olpc_dc_bias_enum_get,
2606                 .put = cxt5066_olpc_dc_bias_enum_put,
2607         },
2608         {}
2609 };
2610
2611 static const struct snd_kcontrol_new cxt5066_mixers[] = {
2612         {
2613                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2614                 .name = "Master Playback Switch",
2615                 .info = cxt_eapd_info,
2616                 .get = cxt_eapd_get,
2617                 .put = cxt5066_hp_master_sw_put,
2618                 .private_value = 0x1d,
2619         },
2620
2621         {
2622                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2623                 .name = "Analog Mic Boost Capture Enum",
2624                 .info = cxt5066_mic_boost_mux_enum_info,
2625                 .get = cxt5066_mic_boost_mux_enum_get,
2626                 .put = cxt5066_mic_boost_mux_enum_put,
2627         },
2628
2629         HDA_BIND_VOL("Capture Volume", &cxt5066_bind_capture_vol_others),
2630         HDA_BIND_SW("Capture Switch", &cxt5066_bind_capture_sw_others),
2631         {}
2632 };
2633
2634 static const struct snd_kcontrol_new cxt5066_vostro_mixers[] = {
2635         {
2636                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2637                 .name = "Internal Mic Boost Capture Enum",
2638                 .info = cxt5066_mic_boost_mux_enum_info,
2639                 .get = cxt5066_mic_boost_mux_enum_get,
2640                 .put = cxt5066_mic_boost_mux_enum_put,
2641                 .private_value = 0x23 | 0x100,
2642         },
2643         {}
2644 };
2645
2646 static const struct hda_verb cxt5066_init_verbs[] = {
2647         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, /* Port B */
2648         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, /* Port C */
2649         {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Port F */
2650         {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Port E */
2651
2652         /* Speakers  */
2653         {0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2654         {0x1f, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
2655
2656         /* HP, Amp  */
2657         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2658         {0x19, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
2659
2660         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2661         {0x1c, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
2662
2663         /* DAC1 */
2664         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2665
2666         /* Node 14 connections: 0x17 0x18 0x23 0x24 0x27 */
2667         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x50},
2668         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2669         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2) | 0x50},
2670         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2671         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2672
2673         /* no digital microphone support yet */
2674         {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2675
2676         /* Audio input selector */
2677         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x3},
2678
2679         /* SPDIF route: PCM */
2680         {0x20, AC_VERB_SET_CONNECT_SEL, 0x0},
2681         {0x22, AC_VERB_SET_CONNECT_SEL, 0x0},
2682
2683         {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2684         {0x22, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2685
2686         /* EAPD */
2687         {0x1d, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
2688
2689         /* not handling these yet */
2690         {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, 0},
2691         {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, 0},
2692         {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, 0},
2693         {0x1c, AC_VERB_SET_UNSOLICITED_ENABLE, 0},
2694         {0x1d, AC_VERB_SET_UNSOLICITED_ENABLE, 0},
2695         {0x1e, AC_VERB_SET_UNSOLICITED_ENABLE, 0},
2696         {0x20, AC_VERB_SET_UNSOLICITED_ENABLE, 0},
2697         {0x22, AC_VERB_SET_UNSOLICITED_ENABLE, 0},
2698         { } /* end */
2699 };
2700
2701 static const struct hda_verb cxt5066_init_verbs_olpc[] = {
2702         /* Port A: headphones */
2703         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2704         {0x19, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
2705
2706         /* Port B: external microphone */
2707         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2708
2709         /* Port C: internal microphone */
2710         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2711
2712         /* Port D: unused */
2713         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2714
2715         /* Port E: unused, but has primary EAPD */
2716         {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2717         {0x1d, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
2718
2719         /* Port F: external DC input through microphone port */
2720         {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2721
2722         /* Port G: internal speakers */
2723         {0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2724         {0x1f, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
2725
2726         /* DAC1 */
2727         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2728
2729         /* DAC2: unused */
2730         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2731
2732         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x50},
2733         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2734         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2735         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2736         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2737         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2738         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2739         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2740         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2741         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2742         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2743         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2744
2745         /* Disable digital microphone port */
2746         {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2747
2748         /* Audio input selectors */
2749         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x3},
2750         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2751
2752         /* Disable SPDIF */
2753         {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2754         {0x22, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2755
2756         /* enable unsolicited events for Port A and B */
2757         {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT},
2758         {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT},
2759         { } /* end */
2760 };
2761
2762 static const struct hda_verb cxt5066_init_verbs_vostro[] = {
2763         /* Port A: headphones */
2764         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2765         {0x19, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
2766
2767         /* Port B: external microphone */
2768         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2769
2770         /* Port C: unused */
2771         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2772
2773         /* Port D: unused */
2774         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2775
2776         /* Port E: unused, but has primary EAPD */
2777         {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2778         {0x1d, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
2779
2780         /* Port F: unused */
2781         {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2782
2783         /* Port G: internal speakers */
2784         {0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2785         {0x1f, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
2786
2787         /* DAC1 */
2788         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2789
2790         /* DAC2: unused */
2791         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2792
2793         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2794         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2795         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2796         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2797         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2798         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2799         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2800         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2801         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2802         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2803         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2804         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2805
2806         /* Digital microphone port */
2807         {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2808
2809         /* Audio input selectors */
2810         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x3},
2811         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2812
2813         /* Disable SPDIF */
2814         {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2815         {0x22, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2816
2817         /* enable unsolicited events for Port A and B */
2818         {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT},
2819         {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT},
2820         { } /* end */
2821 };
2822
2823 static const struct hda_verb cxt5066_init_verbs_ideapad[] = {
2824         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, /* Port B */
2825         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, /* Port C */
2826         {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Port F */
2827         {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Port E */
2828
2829         /* Speakers  */
2830         {0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2831         {0x1f, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
2832
2833         /* HP, Amp  */
2834         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2835         {0x19, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
2836
2837         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2838         {0x1c, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
2839
2840         /* DAC1 */
2841         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2842
2843         /* Node 14 connections: 0x17 0x18 0x23 0x24 0x27 */
2844         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x50},
2845         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2846         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2) | 0x50},
2847         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2848         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2849         {0x14, AC_VERB_SET_CONNECT_SEL, 2},     /* default to internal mic */
2850
2851         /* Audio input selector */
2852         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x2},
2853         {0x17, AC_VERB_SET_CONNECT_SEL, 1},     /* route ext mic */
2854
2855         /* SPDIF route: PCM */
2856         {0x20, AC_VERB_SET_CONNECT_SEL, 0x0},
2857         {0x22, AC_VERB_SET_CONNECT_SEL, 0x0},
2858
2859         {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2860         {0x22, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2861
2862         /* internal microphone */
2863         {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* enable internal mic */
2864
2865         /* EAPD */
2866         {0x1d, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
2867
2868         {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT},
2869         {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT},
2870         { } /* end */
2871 };
2872
2873 static const struct hda_verb cxt5066_init_verbs_thinkpad[] = {
2874         {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Port F */
2875         {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Port E */
2876
2877         /* Port G: internal speakers  */
2878         {0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2879         {0x1f, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
2880
2881         /* Port A: HP, Amp  */
2882         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2883         {0x19, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
2884
2885         /* Port B: Mic Dock */
2886         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2887
2888         /* Port C: Mic */
2889         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2890
2891         /* Port D: HP Dock, Amp */
2892         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2893         {0x1c, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
2894
2895         /* DAC1 */
2896         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2897
2898         /* Node 14 connections: 0x17 0x18 0x23 0x24 0x27 */
2899         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x50},
2900         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2901         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2) | 0x50},
2902         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2903         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2904         {0x14, AC_VERB_SET_CONNECT_SEL, 2},     /* default to internal mic */
2905
2906         /* Audio input selector */
2907         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x2},
2908         {0x17, AC_VERB_SET_CONNECT_SEL, 1},     /* route ext mic */
2909
2910         /* SPDIF route: PCM */
2911         {0x20, AC_VERB_SET_CONNECT_SEL, 0x0},
2912         {0x22, AC_VERB_SET_CONNECT_SEL, 0x0},
2913
2914         {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2915         {0x22, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2916
2917         /* internal microphone */
2918         {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* enable internal mic */
2919
2920         /* EAPD */
2921         {0x1d, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
2922
2923         /* enable unsolicited events for Port A, B, C and D */
2924         {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT},
2925         {0x1c, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT},
2926         {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT},
2927         {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT},
2928         { } /* end */
2929 };
2930
2931 static const struct hda_verb cxt5066_init_verbs_portd_lo[] = {
2932         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2933         { } /* end */
2934 };
2935
2936
2937 static const struct hda_verb cxt5066_init_verbs_hp_laptop[] = {
2938         {0x14, AC_VERB_SET_CONNECT_SEL, 0x0},
2939         {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT},
2940         {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT},
2941         { } /* end */
2942 };
2943
2944 /* initialize jack-sensing, too */
2945 static int cxt5066_init(struct hda_codec *codec)
2946 {
2947         snd_printdd("CXT5066: init\n");
2948         conexant_init(codec);
2949         if (codec->patch_ops.unsol_event) {
2950                 cxt5066_hp_automute(codec);
2951                 cxt5066_automic(codec);
2952         }
2953         cxt5066_set_mic_boost(codec);
2954         return 0;
2955 }
2956
2957 static int cxt5066_olpc_init(struct hda_codec *codec)
2958 {
2959         struct conexant_spec *spec = codec->spec;
2960         snd_printdd("CXT5066: init\n");
2961         conexant_init(codec);
2962         cxt5066_hp_automute(codec);
2963         if (!spec->dc_enable) {
2964                 cxt5066_set_mic_boost(codec);
2965                 cxt5066_olpc_automic(codec);
2966         } else {
2967                 cxt5066_enable_dc(codec);
2968         }
2969         return 0;
2970 }
2971
2972 enum {
2973         CXT5066_LAPTOP,         /* Laptops w/ EAPD support */
2974         CXT5066_DELL_LAPTOP,    /* Dell Laptop */
2975         CXT5066_OLPC_XO_1_5,    /* OLPC XO 1.5 */
2976         CXT5066_DELL_VOSTRO,    /* Dell Vostro 1015i */
2977         CXT5066_IDEAPAD,        /* Lenovo IdeaPad U150 */
2978         CXT5066_THINKPAD,       /* Lenovo ThinkPad T410s, others? */
2979         CXT5066_ASUS,           /* Asus K52JU, Lenovo G560 - Int mic at 0x1a and Ext mic at 0x1b */
2980         CXT5066_HP_LAPTOP,      /* HP Laptop */
2981         CXT5066_AUTO,           /* BIOS auto-parser */
2982         CXT5066_MODELS
2983 };
2984
2985 static const char * const cxt5066_models[CXT5066_MODELS] = {
2986         [CXT5066_LAPTOP]        = "laptop",
2987         [CXT5066_DELL_LAPTOP]   = "dell-laptop",
2988         [CXT5066_OLPC_XO_1_5]   = "olpc-xo-1_5",
2989         [CXT5066_DELL_VOSTRO]   = "dell-vostro",
2990         [CXT5066_IDEAPAD]       = "ideapad",
2991         [CXT5066_THINKPAD]      = "thinkpad",
2992         [CXT5066_ASUS]          = "asus",
2993         [CXT5066_HP_LAPTOP]     = "hp-laptop",
2994         [CXT5066_AUTO]          = "auto",
2995 };
2996
2997 static const struct snd_pci_quirk cxt5066_cfg_tbl[] = {
2998         SND_PCI_QUIRK(0x1025, 0x054c, "Acer Aspire 3830TG", CXT5066_AUTO),
2999         SND_PCI_QUIRK_MASK(0x1025, 0xff00, 0x0400, "Acer", CXT5066_IDEAPAD),
3000         SND_PCI_QUIRK(0x1028, 0x02d8, "Dell Vostro", CXT5066_DELL_VOSTRO),
3001         SND_PCI_QUIRK(0x1028, 0x02f5, "Dell Vostro 320", CXT5066_IDEAPAD),
3002         SND_PCI_QUIRK(0x1028, 0x0401, "Dell Vostro 1014", CXT5066_DELL_VOSTRO),
3003         SND_PCI_QUIRK(0x1028, 0x0402, "Dell Vostro", CXT5066_DELL_VOSTRO),
3004         SND_PCI_QUIRK(0x1028, 0x0408, "Dell Inspiron One 19T", CXT5066_IDEAPAD),
3005         SND_PCI_QUIRK(0x1028, 0x050f, "Dell Inspiron", CXT5066_IDEAPAD),
3006         SND_PCI_QUIRK(0x1028, 0x0510, "Dell Vostro", CXT5066_IDEAPAD),
3007         SND_PCI_QUIRK(0x103c, 0x360b, "HP G60", CXT5066_HP_LAPTOP),
3008         SND_PCI_QUIRK(0x1043, 0x13f3, "Asus A52J", CXT5066_ASUS),
3009         SND_PCI_QUIRK(0x1043, 0x1643, "Asus K52JU", CXT5066_ASUS),
3010         SND_PCI_QUIRK(0x1043, 0x1993, "Asus U50F", CXT5066_ASUS),
3011         SND_PCI_QUIRK(0x1179, 0xff1e, "Toshiba Satellite C650D", CXT5066_IDEAPAD),
3012         SND_PCI_QUIRK(0x1179, 0xff50, "Toshiba Satellite P500-PSPGSC-01800T", CXT5066_OLPC_XO_1_5),
3013         SND_PCI_QUIRK(0x14f1, 0x0101, "Conexant Reference board",
3014                       CXT5066_LAPTOP),
3015         SND_PCI_QUIRK(0x152d, 0x0833, "OLPC XO-1.5", CXT5066_OLPC_XO_1_5),
3016         SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo T400s", CXT5066_THINKPAD),
3017         SND_PCI_QUIRK(0x17aa, 0x21c5, "Thinkpad Edge 13", CXT5066_THINKPAD),
3018         SND_PCI_QUIRK(0x17aa, 0x21c6, "Thinkpad Edge 13", CXT5066_ASUS),
3019         SND_PCI_QUIRK(0x17aa, 0x215e, "Lenovo T510", CXT5066_AUTO),
3020         SND_PCI_QUIRK(0x17aa, 0x21cf, "Lenovo T520 & W520", CXT5066_AUTO),
3021         SND_PCI_QUIRK(0x17aa, 0x21da, "Lenovo X220", CXT5066_THINKPAD),
3022         SND_PCI_QUIRK(0x17aa, 0x21db, "Lenovo X220-tablet", CXT5066_THINKPAD),
3023         SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo U350", CXT5066_ASUS),
3024         SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo G560", CXT5066_ASUS),
3025         SND_PCI_QUIRK(0x17aa, 0x3938, "Lenovo G565", CXT5066_AUTO),
3026         SND_PCI_QUIRK(0x1b0a, 0x2092, "CyberpowerPC Gamer Xplorer N57001", CXT5066_AUTO),
3027         {}
3028 };
3029
3030 static int patch_cxt5066(struct hda_codec *codec)
3031 {
3032         struct conexant_spec *spec;
3033         int board_config;
3034
3035         board_config = snd_hda_check_board_config(codec, CXT5066_MODELS,
3036                                                   cxt5066_models, cxt5066_cfg_tbl);
3037         if (board_config < 0)
3038                 board_config = CXT5066_AUTO; /* model=auto as default */
3039         if (board_config == CXT5066_AUTO)
3040                 return patch_conexant_auto(codec);
3041
3042         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
3043         if (!spec)
3044                 return -ENOMEM;
3045         codec->spec = spec;
3046
3047         codec->patch_ops = conexant_patch_ops;
3048         codec->patch_ops.init = conexant_init;
3049
3050         spec->dell_automute = 0;
3051         spec->multiout.max_channels = 2;
3052         spec->multiout.num_dacs = ARRAY_SIZE(cxt5066_dac_nids);
3053         spec->multiout.dac_nids = cxt5066_dac_nids;
3054         conexant_check_dig_outs(codec, cxt5066_digout_pin_nids,
3055             ARRAY_SIZE(cxt5066_digout_pin_nids));
3056         spec->num_adc_nids = 1;
3057         spec->adc_nids = cxt5066_adc_nids;
3058         spec->capsrc_nids = cxt5066_capsrc_nids;
3059         spec->input_mux = &cxt5066_capture_source;
3060
3061         spec->port_d_mode = PIN_HP;
3062
3063         spec->num_init_verbs = 1;
3064         spec->init_verbs[0] = cxt5066_init_verbs;
3065         spec->num_channel_mode = ARRAY_SIZE(cxt5066_modes);
3066         spec->channel_mode = cxt5066_modes;
3067         spec->cur_adc = 0;
3068         spec->cur_adc_idx = 0;
3069
3070         set_beep_amp(spec, 0x13, 0, HDA_OUTPUT);
3071
3072         switch (board_config) {
3073         default:
3074         case CXT5066_LAPTOP:
3075                 spec->mixers[spec->num_mixers++] = cxt5066_mixer_master;
3076                 spec->mixers[spec->num_mixers++] = cxt5066_mixers;
3077                 break;
3078         case CXT5066_DELL_LAPTOP:
3079                 spec->mixers[spec->num_mixers++] = cxt5066_mixer_master;
3080                 spec->mixers[spec->num_mixers++] = cxt5066_mixers;
3081
3082                 spec->port_d_mode = PIN_OUT;
3083                 spec->init_verbs[spec->num_init_verbs] = cxt5066_init_verbs_portd_lo;
3084                 spec->num_init_verbs++;
3085                 spec->dell_automute = 1;
3086                 break;
3087         case CXT5066_ASUS:
3088         case CXT5066_HP_LAPTOP:
3089                 codec->patch_ops.init = cxt5066_init;
3090                 codec->patch_ops.unsol_event = cxt5066_unsol_event;
3091                 spec->init_verbs[spec->num_init_verbs] =
3092                         cxt5066_init_verbs_hp_laptop;
3093                 spec->num_init_verbs++;
3094                 spec->hp_laptop = board_config == CXT5066_HP_LAPTOP;
3095                 spec->asus = board_config == CXT5066_ASUS;
3096                 spec->mixers[spec->num_mixers++] = cxt5066_mixer_master;
3097                 spec->mixers[spec->num_mixers++] = cxt5066_mixers;
3098                 /* no S/PDIF out */
3099                 if (board_config == CXT5066_HP_LAPTOP)
3100                         spec->multiout.dig_out_nid = 0;
3101                 /* input source automatically selected */
3102                 spec->input_mux = NULL;
3103                 spec->port_d_mode = 0;
3104                 spec->mic_boost = 3; /* default 30dB gain */
3105                 break;
3106
3107         case CXT5066_OLPC_XO_1_5:
3108                 codec->patch_ops.init = cxt5066_olpc_init;
3109                 codec->patch_ops.unsol_event = cxt5066_olpc_unsol_event;
3110                 spec->init_verbs[0] = cxt5066_init_verbs_olpc;
3111                 spec->mixers[spec->num_mixers++] = cxt5066_mixer_master_olpc;
3112                 spec->mixers[spec->num_mixers++] = cxt5066_mixer_olpc_dc;
3113                 spec->mixers[spec->num_mixers++] = cxt5066_mixers;
3114                 spec->port_d_mode = 0;
3115                 spec->mic_boost = 3; /* default 30dB gain */
3116
3117                 /* no S/PDIF out */
3118                 spec->multiout.dig_out_nid = 0;
3119
3120                 /* input source automatically selected */
3121                 spec->input_mux = NULL;
3122
3123                 /* our capture hooks which allow us to turn on the microphone LED
3124                  * at the right time */
3125                 spec->capture_prepare = cxt5066_olpc_capture_prepare;
3126                 spec->capture_cleanup = cxt5066_olpc_capture_cleanup;
3127                 break;
3128         case CXT5066_DELL_VOSTRO:
3129                 codec->patch_ops.init = cxt5066_init;
3130                 codec->patch_ops.unsol_event = cxt5066_unsol_event;
3131                 spec->init_verbs[0] = cxt5066_init_verbs_vostro;
3132                 spec->mixers[spec->num_mixers++] = cxt5066_mixer_master_olpc;
3133                 spec->mixers[spec->num_mixers++] = cxt5066_mixers;
3134                 spec->mixers[spec->num_mixers++] = cxt5066_vostro_mixers;
3135                 spec->port_d_mode = 0;
3136                 spec->dell_vostro = 1;
3137                 spec->mic_boost = 3; /* default 30dB gain */
3138
3139                 /* no S/PDIF out */
3140                 spec->multiout.dig_out_nid = 0;
3141
3142                 /* input source automatically selected */
3143                 spec->input_mux = NULL;
3144                 break;
3145         case CXT5066_IDEAPAD:
3146                 codec->patch_ops.init = cxt5066_init;
3147                 codec->patch_ops.unsol_event = cxt5066_unsol_event;
3148                 spec->mixers[spec->num_mixers++] = cxt5066_mixer_master;
3149                 spec->mixers[spec->num_mixers++] = cxt5066_mixers;
3150                 spec->init_verbs[0] = cxt5066_init_verbs_ideapad;
3151                 spec->port_d_mode = 0;
3152                 spec->ideapad = 1;
3153                 spec->mic_boost = 2;    /* default 20dB gain */
3154
3155                 /* no S/PDIF out */
3156                 spec->multiout.dig_out_nid = 0;
3157
3158                 /* input source automatically selected */
3159                 spec->input_mux = NULL;
3160                 break;
3161         case CXT5066_THINKPAD:
3162                 codec->patch_ops.init = cxt5066_init;
3163                 codec->patch_ops.unsol_event = cxt5066_unsol_event;
3164                 spec->mixers[spec->num_mixers++] = cxt5066_mixer_master;
3165                 spec->mixers[spec->num_mixers++] = cxt5066_mixers;
3166                 spec->init_verbs[0] = cxt5066_init_verbs_thinkpad;
3167                 spec->thinkpad = 1;
3168                 spec->port_d_mode = PIN_OUT;
3169                 spec->mic_boost = 2;    /* default 20dB gain */
3170
3171                 /* no S/PDIF out */
3172                 spec->multiout.dig_out_nid = 0;
3173
3174                 /* input source automatically selected */
3175                 spec->input_mux = NULL;
3176                 break;
3177         }
3178
3179         if (spec->beep_amp)
3180                 snd_hda_attach_beep_device(codec, spec->beep_amp);
3181
3182         return 0;
3183 }
3184
3185 /*
3186  * Automatic parser for CX20641 & co
3187  */
3188
3189 static int cx_auto_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
3190                                        struct hda_codec *codec,
3191                                        unsigned int stream_tag,
3192                                        unsigned int format,
3193                                        struct snd_pcm_substream *substream)
3194 {
3195         struct conexant_spec *spec = codec->spec;
3196         hda_nid_t adc = spec->imux_info[spec->cur_mux[0]].adc;
3197         if (spec->adc_switching) {
3198                 spec->cur_adc = adc;
3199                 spec->cur_adc_stream_tag = stream_tag;
3200                 spec->cur_adc_format = format;
3201         }
3202         snd_hda_codec_setup_stream(codec, adc, stream_tag, 0, format);
3203         return 0;
3204 }
3205
3206 static int cx_auto_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
3207                                        struct hda_codec *codec,
3208                                        struct snd_pcm_substream *substream)
3209 {
3210         struct conexant_spec *spec = codec->spec;
3211         snd_hda_codec_cleanup_stream(codec, spec->cur_adc);
3212         spec->cur_adc = 0;
3213         return 0;
3214 }
3215
3216 static const struct hda_pcm_stream cx_auto_pcm_analog_capture = {
3217         .substreams = 1,
3218         .channels_min = 2,
3219         .channels_max = 2,
3220         .nid = 0, /* fill later */
3221         .ops = {
3222                 .prepare = cx_auto_capture_pcm_prepare,
3223                 .cleanup = cx_auto_capture_pcm_cleanup
3224         },
3225 };
3226
3227 static const hda_nid_t cx_auto_adc_nids[] = { 0x14 };
3228
3229 #define get_connection_index(codec, mux, nid)\
3230         snd_hda_get_conn_index(codec, mux, nid, 0)
3231
3232 /* get an unassigned DAC from the given list.
3233  * Return the nid if found and reduce the DAC list, or return zero if
3234  * not found
3235  */
3236 static hda_nid_t get_unassigned_dac(struct hda_codec *codec, hda_nid_t pin,
3237                                     hda_nid_t *dacs, int *num_dacs)
3238 {
3239         int i, nums = *num_dacs;
3240         hda_nid_t ret = 0;
3241
3242         for (i = 0; i < nums; i++) {
3243                 if (get_connection_index(codec, pin, dacs[i]) >= 0) {
3244                         ret = dacs[i];
3245                         break;
3246                 }
3247         }
3248         if (!ret)
3249                 return 0;
3250         if (--nums > 0)
3251                 memmove(dacs, dacs + 1, nums * sizeof(hda_nid_t));
3252         *num_dacs = nums;
3253         return ret;
3254 }
3255
3256 #define MAX_AUTO_DACS   5
3257
3258 #define DAC_SLAVE_FLAG  0x8000  /* filled dac is a slave */
3259
3260 /* fill analog DAC list from the widget tree */
3261 static int fill_cx_auto_dacs(struct hda_codec *codec, hda_nid_t *dacs)
3262 {
3263         hda_nid_t nid, end_nid;
3264         int nums = 0;
3265
3266         end_nid = codec->start_nid + codec->num_nodes;
3267         for (nid = codec->start_nid; nid < end_nid; nid++) {
3268                 unsigned int wcaps = get_wcaps(codec, nid);
3269                 unsigned int type = get_wcaps_type(wcaps);
3270                 if (type == AC_WID_AUD_OUT && !(wcaps & AC_WCAP_DIGITAL)) {
3271                         dacs[nums++] = nid;
3272                         if (nums >= MAX_AUTO_DACS)
3273                                 break;
3274                 }
3275         }
3276         return nums;
3277 }
3278
3279 /* fill pin_dac_pair list from the pin and dac list */
3280 static int fill_dacs_for_pins(struct hda_codec *codec, hda_nid_t *pins,
3281                               int num_pins, hda_nid_t *dacs, int *rest,
3282                               struct pin_dac_pair *filled, int nums, 
3283                               int type)
3284 {
3285         int i, start = nums;
3286
3287         for (i = 0; i < num_pins; i++, nums++) {
3288                 filled[nums].pin = pins[i];
3289                 filled[nums].type = type;
3290                 filled[nums].dac = get_unassigned_dac(codec, pins[i], dacs, rest);
3291                 if (filled[nums].dac) 
3292                         continue;
3293                 if (filled[start].dac && get_connection_index(codec, pins[i], filled[start].dac) >= 0) {
3294                         filled[nums].dac = filled[start].dac | DAC_SLAVE_FLAG;
3295                         continue;
3296                 }
3297                 if (filled[0].dac && get_connection_index(codec, pins[i], filled[0].dac) >= 0) {
3298                         filled[nums].dac = filled[0].dac | DAC_SLAVE_FLAG;
3299                         continue;
3300                 }
3301                 snd_printdd("Failed to find a DAC for pin 0x%x", pins[i]);
3302         }
3303         return nums;
3304 }
3305
3306 /* parse analog output paths */
3307 static void cx_auto_parse_output(struct hda_codec *codec)
3308 {
3309         struct conexant_spec *spec = codec->spec;
3310         struct auto_pin_cfg *cfg = &spec->autocfg;
3311         hda_nid_t dacs[MAX_AUTO_DACS];
3312         int i, j, nums, rest;
3313
3314         rest = fill_cx_auto_dacs(codec, dacs);
3315         /* parse all analog output pins */
3316         nums = fill_dacs_for_pins(codec, cfg->line_out_pins, cfg->line_outs,
3317                           dacs, &rest, spec->dac_info, 0,
3318                           AUTO_PIN_LINE_OUT);
3319         nums = fill_dacs_for_pins(codec, cfg->hp_pins, cfg->hp_outs,
3320                           dacs, &rest, spec->dac_info, nums,
3321                           AUTO_PIN_HP_OUT);
3322         nums = fill_dacs_for_pins(codec, cfg->speaker_pins, cfg->speaker_outs,
3323                           dacs, &rest, spec->dac_info, nums,
3324                           AUTO_PIN_SPEAKER_OUT);
3325         spec->dac_info_filled = nums;
3326         /* fill multiout struct */
3327         for (i = 0; i < nums; i++) {
3328                 hda_nid_t dac = spec->dac_info[i].dac;
3329                 if (!dac || (dac & DAC_SLAVE_FLAG))
3330                         continue;
3331                 switch (spec->dac_info[i].type) {
3332                 case AUTO_PIN_LINE_OUT:
3333                         spec->private_dac_nids[spec->multiout.num_dacs] = dac;
3334                         spec->multiout.num_dacs++;
3335                         break;
3336                 case AUTO_PIN_HP_OUT:
3337                 case AUTO_PIN_SPEAKER_OUT:
3338                         if (!spec->multiout.hp_nid) {
3339                                 spec->multiout.hp_nid = dac;
3340                                 break;
3341                         }
3342                         for (j = 0; j < ARRAY_SIZE(spec->multiout.extra_out_nid); j++)
3343                                 if (!spec->multiout.extra_out_nid[j]) {
3344                                         spec->multiout.extra_out_nid[j] = dac;
3345                                         break;
3346                                 }
3347                         break;
3348                 }
3349         }
3350         spec->multiout.dac_nids = spec->private_dac_nids;
3351         spec->multiout.max_channels = spec->multiout.num_dacs * 2;
3352
3353         for (i = 0; i < cfg->hp_outs; i++) {
3354                 if (is_jack_detectable(codec, cfg->hp_pins[i])) {
3355                         spec->auto_mute = 1;
3356                         break;
3357                 }
3358         }
3359         if (spec->auto_mute &&
3360             cfg->line_out_pins[0] &&
3361             cfg->line_out_type != AUTO_PIN_SPEAKER_OUT &&
3362             cfg->line_out_pins[0] != cfg->hp_pins[0] &&
3363             cfg->line_out_pins[0] != cfg->speaker_pins[0]) {
3364                 for (i = 0; i < cfg->line_outs; i++) {
3365                         if (is_jack_detectable(codec, cfg->line_out_pins[i])) {
3366                                 spec->detect_line = 1;
3367                                 break;
3368                         }
3369                 }
3370                 spec->automute_lines = spec->detect_line;
3371         }
3372
3373         spec->vmaster_nid = spec->private_dac_nids[0];
3374 }
3375
3376 static void cx_auto_turn_eapd(struct hda_codec *codec, int num_pins,
3377                               hda_nid_t *pins, bool on);
3378
3379 static void do_automute(struct hda_codec *codec, int num_pins,
3380                         hda_nid_t *pins, bool on)
3381 {
3382         struct conexant_spec *spec = codec->spec;
3383         int i;
3384         for (i = 0; i < num_pins; i++)
3385                 snd_hda_codec_write(codec, pins[i], 0,
3386                                     AC_VERB_SET_PIN_WIDGET_CONTROL,
3387                                     on ? PIN_OUT : 0);
3388         if (spec->pin_eapd_ctrls)
3389                 cx_auto_turn_eapd(codec, num_pins, pins, on);
3390 }
3391
3392 static int detect_jacks(struct hda_codec *codec, int num_pins, hda_nid_t *pins)
3393 {
3394         int i, present = 0;
3395
3396         for (i = 0; i < num_pins; i++) {
3397                 hda_nid_t nid = pins[i];
3398                 if (!nid || !is_jack_detectable(codec, nid))
3399                         break;
3400                 present |= snd_hda_jack_detect(codec, nid);
3401         }
3402         return present;
3403 }
3404
3405 /* auto-mute/unmute speaker and line outs according to headphone jack */
3406 static void cx_auto_update_speakers(struct hda_codec *codec)
3407 {
3408         struct conexant_spec *spec = codec->spec;
3409         struct auto_pin_cfg *cfg = &spec->autocfg;
3410         int on = 1;
3411
3412         /* turn on HP EAPD when HP jacks are present */
3413         if (spec->pin_eapd_ctrls) {
3414                 if (spec->auto_mute)
3415                         on = spec->hp_present;
3416                 cx_auto_turn_eapd(codec, cfg->hp_outs, cfg->hp_pins, on);
3417         }
3418
3419         /* mute speakers in auto-mode if HP or LO jacks are plugged */
3420         if (spec->auto_mute)
3421                 on = !(spec->hp_present ||
3422                        (spec->detect_line && spec->line_present));
3423         do_automute(codec, cfg->speaker_outs, cfg->speaker_pins, on);
3424
3425         /* toggle line-out mutes if needed, too */
3426         /* if LO is a copy of either HP or Speaker, don't need to handle it */
3427         if (cfg->line_out_pins[0] == cfg->hp_pins[0] ||
3428             cfg->line_out_pins[0] == cfg->speaker_pins[0])
3429                 return;
3430         if (spec->auto_mute) {
3431                 /* mute LO in auto-mode when HP jack is present */
3432                 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT ||
3433                     spec->automute_lines)
3434                         on = !spec->hp_present;
3435                 else
3436                         on = 1;
3437         }
3438         do_automute(codec, cfg->line_outs, cfg->line_out_pins, on);
3439 }
3440
3441 static void cx_auto_hp_automute(struct hda_codec *codec)
3442 {
3443         struct conexant_spec *spec = codec->spec;
3444         struct auto_pin_cfg *cfg = &spec->autocfg;
3445
3446         if (!spec->auto_mute)
3447                 return;
3448         spec->hp_present = detect_jacks(codec, cfg->hp_outs, cfg->hp_pins);
3449         cx_auto_update_speakers(codec);
3450 }
3451
3452 static void cx_auto_line_automute(struct hda_codec *codec)
3453 {
3454         struct conexant_spec *spec = codec->spec;
3455         struct auto_pin_cfg *cfg = &spec->autocfg;
3456
3457         if (!spec->auto_mute || !spec->detect_line)
3458                 return;
3459         spec->line_present = detect_jacks(codec, cfg->line_outs,
3460                                           cfg->line_out_pins);
3461         cx_auto_update_speakers(codec);
3462 }
3463
3464 static int cx_automute_mode_info(struct snd_kcontrol *kcontrol,
3465                                  struct snd_ctl_elem_info *uinfo)
3466 {
3467         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3468         struct conexant_spec *spec = codec->spec;
3469         static const char * const texts2[] = {
3470                 "Disabled", "Enabled"
3471         };
3472         static const char * const texts3[] = {
3473                 "Disabled", "Speaker Only", "Line-Out+Speaker"
3474         };
3475         const char * const *texts;
3476
3477         uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
3478         uinfo->count = 1;
3479         if (spec->automute_hp_lo) {
3480                 uinfo->value.enumerated.items = 3;
3481                 texts = texts3;
3482         } else {
3483                 uinfo->value.enumerated.items = 2;
3484                 texts = texts2;
3485         }
3486         if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
3487                 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
3488         strcpy(uinfo->value.enumerated.name,
3489                texts[uinfo->value.enumerated.item]);
3490         return 0;
3491 }
3492
3493 static int cx_automute_mode_get(struct snd_kcontrol *kcontrol,
3494                                 struct snd_ctl_elem_value *ucontrol)
3495 {
3496         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3497         struct conexant_spec *spec = codec->spec;
3498         unsigned int val;
3499         if (!spec->auto_mute)
3500                 val = 0;
3501         else if (!spec->automute_lines)
3502                 val = 1;
3503         else
3504                 val = 2;
3505         ucontrol->value.enumerated.item[0] = val;
3506         return 0;
3507 }
3508
3509 static int cx_automute_mode_put(struct snd_kcontrol *kcontrol,
3510                                 struct snd_ctl_elem_value *ucontrol)
3511 {
3512         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3513         struct conexant_spec *spec = codec->spec;
3514
3515         switch (ucontrol->value.enumerated.item[0]) {
3516         case 0:
3517                 if (!spec->auto_mute)
3518                         return 0;
3519                 spec->auto_mute = 0;
3520                 break;
3521         case 1:
3522                 if (spec->auto_mute && !spec->automute_lines)
3523                         return 0;
3524                 spec->auto_mute = 1;
3525                 spec->automute_lines = 0;
3526                 break;
3527         case 2:
3528                 if (!spec->automute_hp_lo)
3529                         return -EINVAL;
3530                 if (spec->auto_mute && spec->automute_lines)
3531                         return 0;
3532                 spec->auto_mute = 1;
3533                 spec->automute_lines = 1;
3534                 break;
3535         default:
3536                 return -EINVAL;
3537         }
3538         cx_auto_update_speakers(codec);
3539         return 1;
3540 }
3541
3542 static const struct snd_kcontrol_new cx_automute_mode_enum[] = {
3543         {
3544                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3545                 .name = "Auto-Mute Mode",
3546                 .info = cx_automute_mode_info,
3547                 .get = cx_automute_mode_get,
3548                 .put = cx_automute_mode_put,
3549         },
3550         { }
3551 };
3552
3553 static int cx_auto_mux_enum_info(struct snd_kcontrol *kcontrol,
3554                                  struct snd_ctl_elem_info *uinfo)
3555 {
3556         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3557         struct conexant_spec *spec = codec->spec;
3558
3559         return snd_hda_input_mux_info(&spec->private_imux, uinfo);
3560 }
3561
3562 static int cx_auto_mux_enum_get(struct snd_kcontrol *kcontrol,
3563                                 struct snd_ctl_elem_value *ucontrol)
3564 {
3565         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3566         struct conexant_spec *spec = codec->spec;
3567
3568         ucontrol->value.enumerated.item[0] = spec->cur_mux[0];
3569         return 0;
3570 }
3571
3572 /* look for the route the given pin from mux and return the index;
3573  * if do_select is set, actually select the route.
3574  */
3575 static int __select_input_connection(struct hda_codec *codec, hda_nid_t mux,
3576                                      hda_nid_t pin, hda_nid_t *srcp,
3577                                      bool do_select, int depth)
3578 {
3579         hda_nid_t conn[HDA_MAX_NUM_INPUTS];
3580         int i, nums;
3581
3582         switch (get_wcaps_type(get_wcaps(codec, mux))) {
3583         case AC_WID_AUD_IN:
3584         case AC_WID_AUD_SEL:
3585         case AC_WID_AUD_MIX:
3586                 break;
3587         default:
3588                 return -1;
3589         }
3590
3591         nums = snd_hda_get_connections(codec, mux, conn, ARRAY_SIZE(conn));
3592         for (i = 0; i < nums; i++)
3593                 if (conn[i] == pin) {
3594                         if (do_select)
3595                                 snd_hda_codec_write(codec, mux, 0,
3596                                                     AC_VERB_SET_CONNECT_SEL, i);
3597                         if (srcp)
3598                                 *srcp = mux;
3599                         return i;
3600                 }
3601         depth++;
3602         if (depth == 2)
3603                 return -1;
3604         for (i = 0; i < nums; i++) {
3605                 int ret  = __select_input_connection(codec, conn[i], pin, srcp,
3606                                                      do_select, depth);
3607                 if (ret >= 0) {
3608                         if (do_select)
3609                                 snd_hda_codec_write(codec, mux, 0,
3610                                                     AC_VERB_SET_CONNECT_SEL, i);
3611                         return i;
3612                 }
3613         }
3614         return -1;
3615 }
3616
3617 static void select_input_connection(struct hda_codec *codec, hda_nid_t mux,
3618                                    hda_nid_t pin)
3619 {
3620         __select_input_connection(codec, mux, pin, NULL, true, 0);
3621 }
3622
3623 static int get_input_connection(struct hda_codec *codec, hda_nid_t mux,
3624                                 hda_nid_t pin)
3625 {
3626         return __select_input_connection(codec, mux, pin, NULL, false, 0);
3627 }
3628
3629 static int cx_auto_mux_enum_update(struct hda_codec *codec,
3630                                    const struct hda_input_mux *imux,
3631                                    unsigned int idx)
3632 {
3633         struct conexant_spec *spec = codec->spec;
3634         hda_nid_t adc;
3635         int changed = 1;
3636
3637         if (!imux->num_items)
3638                 return 0;
3639         if (idx >= imux->num_items)
3640                 idx = imux->num_items - 1;
3641         if (spec->cur_mux[0] == idx)
3642                 changed = 0;
3643         adc = spec->imux_info[idx].adc;
3644         select_input_connection(codec, spec->imux_info[idx].adc,
3645                                 spec->imux_info[idx].pin);
3646         if (spec->cur_adc && spec->cur_adc != adc) {
3647                 /* stream is running, let's swap the current ADC */
3648                 __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1);
3649                 spec->cur_adc = adc;
3650                 snd_hda_codec_setup_stream(codec, adc,
3651                                            spec->cur_adc_stream_tag, 0,
3652                                            spec->cur_adc_format);
3653         }
3654         spec->cur_mux[0] = idx;
3655         return changed;
3656 }
3657
3658 static int cx_auto_mux_enum_put(struct snd_kcontrol *kcontrol,
3659                                 struct snd_ctl_elem_value *ucontrol)
3660 {
3661         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3662         struct conexant_spec *spec = codec->spec;
3663
3664         return cx_auto_mux_enum_update(codec, &spec->private_imux,
3665                                        ucontrol->value.enumerated.item[0]);
3666 }
3667
3668 static const struct snd_kcontrol_new cx_auto_capture_mixers[] = {
3669         {
3670                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3671                 .name = "Capture Source",
3672                 .info = cx_auto_mux_enum_info,
3673                 .get = cx_auto_mux_enum_get,
3674                 .put = cx_auto_mux_enum_put
3675         },
3676         {}
3677 };
3678
3679 static bool select_automic(struct hda_codec *codec, int idx, bool detect)
3680 {
3681         struct conexant_spec *spec = codec->spec;
3682         if (idx < 0)
3683                 return false;
3684         if (detect && !snd_hda_jack_detect(codec, spec->imux_info[idx].pin))
3685                 return false;
3686         cx_auto_mux_enum_update(codec, &spec->private_imux, idx);
3687         return true;
3688 }
3689
3690 /* automatic switch internal and external mic */
3691 static void cx_auto_automic(struct hda_codec *codec)
3692 {
3693         struct conexant_spec *spec = codec->spec;
3694
3695         if (!spec->auto_mic)
3696                 return;
3697         if (!select_automic(codec, spec->auto_mic_ext, true))
3698                 if (!select_automic(codec, spec->auto_mic_dock, true))
3699                         select_automic(codec, spec->auto_mic_int, false);
3700 }
3701
3702 static void cx_auto_unsol_event(struct hda_codec *codec, unsigned int res)
3703 {
3704         switch (snd_hda_jack_get_action(codec, res >> 26)) {
3705         case CONEXANT_HP_EVENT:
3706                 cx_auto_hp_automute(codec);
3707                 break;
3708         case CONEXANT_LINE_EVENT:
3709                 cx_auto_line_automute(codec);
3710                 break;
3711         case CONEXANT_MIC_EVENT:
3712                 cx_auto_automic(codec);
3713                 break;
3714         }
3715         snd_hda_jack_report_sync(codec);
3716 }
3717
3718 /* check whether the pin config is suitable for auto-mic switching;
3719  * auto-mic is enabled only when one int-mic and one ext- and/or
3720  * one dock-mic exist
3721  */
3722 static void cx_auto_check_auto_mic(struct hda_codec *codec)
3723 {
3724         struct conexant_spec *spec = codec->spec;
3725         int pset[INPUT_PIN_ATTR_NORMAL + 1];
3726         int i;
3727
3728         for (i = 0; i < ARRAY_SIZE(pset); i++)
3729                 pset[i] = -1;
3730         for (i = 0; i < spec->private_imux.num_items; i++) {
3731                 hda_nid_t pin = spec->imux_info[i].pin;
3732                 unsigned int def_conf = snd_hda_codec_get_pincfg(codec, pin);
3733                 int type, attr;
3734                 attr = snd_hda_get_input_pin_attr(def_conf);
3735                 if (attr == INPUT_PIN_ATTR_UNUSED)
3736                         return; /* invalid entry */
3737                 if (attr > INPUT_PIN_ATTR_NORMAL)
3738                         attr = INPUT_PIN_ATTR_NORMAL;
3739                 if (attr != INPUT_PIN_ATTR_INT &&
3740                     !is_jack_detectable(codec, pin))
3741                         return; /* non-detectable pin */
3742                 type = get_defcfg_device(def_conf);
3743                 if (type != AC_JACK_MIC_IN &&
3744                     (attr != INPUT_PIN_ATTR_DOCK || type != AC_JACK_LINE_IN))
3745                         return; /* no valid input type */
3746                 if (pset[attr] >= 0)
3747                         return; /* already occupied */
3748                 pset[attr] = i;
3749         }
3750         if (pset[INPUT_PIN_ATTR_INT] < 0 ||
3751             (pset[INPUT_PIN_ATTR_NORMAL] < 0 && pset[INPUT_PIN_ATTR_DOCK]))
3752                 return; /* no input to switch*/
3753         spec->auto_mic = 1;
3754         spec->auto_mic_ext = pset[INPUT_PIN_ATTR_NORMAL];
3755         spec->auto_mic_dock = pset[INPUT_PIN_ATTR_DOCK];
3756         spec->auto_mic_int = pset[INPUT_PIN_ATTR_INT];
3757 }
3758
3759 static void cx_auto_parse_input(struct hda_codec *codec)
3760 {
3761         struct conexant_spec *spec = codec->spec;
3762         struct auto_pin_cfg *cfg = &spec->autocfg;
3763         struct hda_input_mux *imux;
3764         int i, j;
3765
3766         imux = &spec->private_imux;
3767         for (i = 0; i < cfg->num_inputs; i++) {
3768                 for (j = 0; j < spec->num_adc_nids; j++) {
3769                         hda_nid_t adc = spec->adc_nids[j];
3770                         int idx = get_input_connection(codec, adc,
3771                                                        cfg->inputs[i].pin);
3772                         if (idx >= 0) {
3773                                 const char *label;
3774                                 label = hda_get_autocfg_input_label(codec, cfg, i);
3775                                 spec->imux_info[imux->num_items].index = i;
3776                                 spec->imux_info[imux->num_items].boost = 0;
3777                                 spec->imux_info[imux->num_items].adc = adc;
3778                                 spec->imux_info[imux->num_items].pin =
3779                                         cfg->inputs[i].pin;
3780                                 snd_hda_add_imux_item(imux, label, idx, NULL);
3781                                 break;
3782                         }
3783                 }
3784         }
3785         if (imux->num_items >= 2 && cfg->num_inputs == imux->num_items)
3786                 cx_auto_check_auto_mic(codec);
3787         if (imux->num_items > 1) {
3788                 for (i = 1; i < imux->num_items; i++) {
3789                         if (spec->imux_info[i].adc != spec->imux_info[0].adc) {
3790                                 spec->adc_switching = 1;
3791                                 break;
3792                         }
3793                 }
3794         }
3795 }
3796
3797 /* get digital-input audio widget corresponding to the given pin */
3798 static hda_nid_t cx_auto_get_dig_in(struct hda_codec *codec, hda_nid_t pin)
3799 {
3800         hda_nid_t nid, end_nid;
3801
3802         end_nid = codec->start_nid + codec->num_nodes;
3803         for (nid = codec->start_nid; nid < end_nid; nid++) {
3804                 unsigned int wcaps = get_wcaps(codec, nid);
3805                 unsigned int type = get_wcaps_type(wcaps);
3806                 if (type == AC_WID_AUD_IN && (wcaps & AC_WCAP_DIGITAL)) {
3807                         if (get_connection_index(codec, nid, pin) >= 0)
3808                                 return nid;
3809                 }
3810         }
3811         return 0;
3812 }
3813
3814 static void cx_auto_parse_digital(struct hda_codec *codec)
3815 {
3816         struct conexant_spec *spec = codec->spec;
3817         struct auto_pin_cfg *cfg = &spec->autocfg;
3818         hda_nid_t nid;
3819
3820         if (cfg->dig_outs &&
3821             snd_hda_get_connections(codec, cfg->dig_out_pins[0], &nid, 1) == 1)
3822                 spec->multiout.dig_out_nid = nid;
3823         if (cfg->dig_in_pin)
3824                 spec->dig_in_nid = cx_auto_get_dig_in(codec, cfg->dig_in_pin);
3825 }
3826
3827 #ifdef CONFIG_SND_HDA_INPUT_BEEP
3828 static void cx_auto_parse_beep(struct hda_codec *codec)
3829 {
3830         struct conexant_spec *spec = codec->spec;
3831         hda_nid_t nid, end_nid;
3832
3833         end_nid = codec->start_nid + codec->num_nodes;
3834         for (nid = codec->start_nid; nid < end_nid; nid++)
3835                 if (get_wcaps_type(get_wcaps(codec, nid)) == AC_WID_BEEP) {
3836                         set_beep_amp(spec, nid, 0, HDA_OUTPUT);
3837                         break;
3838                 }
3839 }
3840 #else
3841 #define cx_auto_parse_beep(codec)
3842 #endif
3843
3844 /* parse EAPDs */
3845 static void cx_auto_parse_eapd(struct hda_codec *codec)
3846 {
3847         struct conexant_spec *spec = codec->spec;
3848         hda_nid_t nid, end_nid;
3849
3850         end_nid = codec->start_nid + codec->num_nodes;
3851         for (nid = codec->start_nid; nid < end_nid; nid++) {
3852                 if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN)
3853                         continue;
3854                 if (!(snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD))
3855                         continue;
3856                 spec->eapds[spec->num_eapds++] = nid;
3857                 if (spec->num_eapds >= ARRAY_SIZE(spec->eapds))
3858                         break;
3859         }
3860
3861         /* NOTE: below is a wild guess; if we have more than two EAPDs,
3862          * it's a new chip, where EAPDs are supposed to be associated to
3863          * pins, and we can control EAPD per pin.
3864          * OTOH, if only one or two EAPDs are found, it's an old chip,
3865          * thus it might control over all pins.
3866          */
3867         spec->pin_eapd_ctrls = spec->num_eapds > 2;
3868 }
3869
3870 static int cx_auto_parse_auto_config(struct hda_codec *codec)
3871 {
3872         struct conexant_spec *spec = codec->spec;
3873         int err;
3874
3875         err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
3876         if (err < 0)
3877                 return err;
3878
3879         cx_auto_parse_output(codec);
3880         cx_auto_parse_input(codec);
3881         cx_auto_parse_digital(codec);
3882         cx_auto_parse_beep(codec);
3883         cx_auto_parse_eapd(codec);
3884         return 0;
3885 }
3886
3887 static void cx_auto_turn_eapd(struct hda_codec *codec, int num_pins,
3888                               hda_nid_t *pins, bool on)
3889 {
3890         int i;
3891         for (i = 0; i < num_pins; i++) {
3892                 if (snd_hda_query_pin_caps(codec, pins[i]) & AC_PINCAP_EAPD)
3893                         snd_hda_codec_write(codec, pins[i], 0,
3894                                             AC_VERB_SET_EAPD_BTLENABLE,
3895                                             on ? 0x02 : 0);
3896         }
3897 }
3898
3899 static void select_connection(struct hda_codec *codec, hda_nid_t pin,
3900                               hda_nid_t src)
3901 {
3902         int idx = get_connection_index(codec, pin, src);
3903         if (idx >= 0)
3904                 snd_hda_codec_write(codec, pin, 0,
3905                                     AC_VERB_SET_CONNECT_SEL, idx);
3906 }
3907
3908 static void mute_outputs(struct hda_codec *codec, int num_nids,
3909                          const hda_nid_t *nids)
3910 {
3911         int i, val;
3912
3913         for (i = 0; i < num_nids; i++) {
3914                 hda_nid_t nid = nids[i];
3915                 if (!(get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
3916                         continue;
3917                 if (query_amp_caps(codec, nid, HDA_OUTPUT) & AC_AMPCAP_MUTE)
3918                         val = AMP_OUT_MUTE;
3919                 else
3920                         val = AMP_OUT_ZERO;
3921                 snd_hda_codec_write(codec, nid, 0,
3922                                     AC_VERB_SET_AMP_GAIN_MUTE, val);
3923         }
3924 }
3925
3926 static void enable_unsol_pins(struct hda_codec *codec, int num_pins,
3927                               hda_nid_t *pins, unsigned int action)
3928 {
3929         int i;
3930         for (i = 0; i < num_pins; i++)
3931                 snd_hda_jack_detect_enable(codec, pins[i], action);
3932 }
3933
3934 static void cx_auto_init_output(struct hda_codec *codec)
3935 {
3936         struct conexant_spec *spec = codec->spec;
3937         struct auto_pin_cfg *cfg = &spec->autocfg;
3938         hda_nid_t nid;
3939         int i;
3940
3941         mute_outputs(codec, spec->multiout.num_dacs, spec->multiout.dac_nids);
3942         for (i = 0; i < cfg->hp_outs; i++)
3943                 snd_hda_codec_write(codec, cfg->hp_pins[i], 0,
3944                                     AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP);
3945         mute_outputs(codec, cfg->hp_outs, cfg->hp_pins);
3946         mute_outputs(codec, cfg->line_outs, cfg->line_out_pins);
3947         mute_outputs(codec, cfg->speaker_outs, cfg->speaker_pins);
3948         for (i = 0; i < spec->dac_info_filled; i++) {
3949                 nid = spec->dac_info[i].dac;
3950                 if (!nid)
3951                         nid = spec->multiout.dac_nids[0];
3952                 else if (nid & DAC_SLAVE_FLAG)
3953                         nid &= ~DAC_SLAVE_FLAG;
3954                 select_connection(codec, spec->dac_info[i].pin, nid);
3955         }
3956         if (spec->auto_mute) {
3957                 enable_unsol_pins(codec, cfg->hp_outs, cfg->hp_pins,
3958                                   CONEXANT_HP_EVENT);
3959                 spec->hp_present = detect_jacks(codec, cfg->hp_outs,
3960                                                 cfg->hp_pins);
3961                 if (spec->detect_line) {
3962                         enable_unsol_pins(codec, cfg->line_outs,
3963                                           cfg->line_out_pins,
3964                                           CONEXANT_LINE_EVENT);
3965                         spec->line_present =
3966                                 detect_jacks(codec, cfg->line_outs,
3967                                              cfg->line_out_pins);
3968                 }
3969         }
3970         cx_auto_update_speakers(codec);
3971         /* turn on all EAPDs if no individual EAPD control is available */
3972         if (!spec->pin_eapd_ctrls)
3973                 cx_auto_turn_eapd(codec, spec->num_eapds, spec->eapds, true);
3974 }
3975
3976 static void cx_auto_init_input(struct hda_codec *codec)
3977 {
3978         struct conexant_spec *spec = codec->spec;
3979         struct auto_pin_cfg *cfg = &spec->autocfg;
3980         int i, val;
3981
3982         for (i = 0; i < spec->num_adc_nids; i++) {
3983                 hda_nid_t nid = spec->adc_nids[i];
3984                 if (!(get_wcaps(codec, nid) & AC_WCAP_IN_AMP))
3985                         continue;
3986                 if (query_amp_caps(codec, nid, HDA_INPUT) & AC_AMPCAP_MUTE)
3987                         val = AMP_IN_MUTE(0);
3988                 else
3989                         val = AMP_IN_UNMUTE(0);
3990                 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
3991                                     val);
3992         }
3993
3994         for (i = 0; i < cfg->num_inputs; i++) {
3995                 unsigned int type;
3996                 if (cfg->inputs[i].type == AUTO_PIN_MIC)
3997                         type = PIN_VREF80;
3998                 else
3999                         type = PIN_IN;
4000                 snd_hda_codec_write(codec, cfg->inputs[i].pin, 0,
4001                                     AC_VERB_SET_PIN_WIDGET_CONTROL, type);
4002         }
4003
4004         if (spec->auto_mic) {
4005                 if (spec->auto_mic_ext >= 0) {
4006                         snd_hda_jack_detect_enable(codec,
4007                                 cfg->inputs[spec->auto_mic_ext].pin,
4008                                 CONEXANT_MIC_EVENT);
4009                 }
4010                 if (spec->auto_mic_dock >= 0) {
4011                         snd_hda_jack_detect_enable(codec,
4012                                 cfg->inputs[spec->auto_mic_dock].pin,
4013                                 CONEXANT_MIC_EVENT);
4014                 }
4015                 cx_auto_automic(codec);
4016         } else {
4017                 select_input_connection(codec, spec->imux_info[0].adc,
4018                                         spec->imux_info[0].pin);
4019         }
4020 }
4021
4022 static void cx_auto_init_digital(struct hda_codec *codec)
4023 {
4024         struct conexant_spec *spec = codec->spec;
4025         struct auto_pin_cfg *cfg = &spec->autocfg;
4026
4027         if (spec->multiout.dig_out_nid)
4028                 snd_hda_codec_write(codec, cfg->dig_out_pins[0], 0,
4029                                     AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
4030         if (spec->dig_in_nid)
4031                 snd_hda_codec_write(codec, cfg->dig_in_pin, 0,
4032                                     AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN);
4033 }
4034
4035 static int cx_auto_init(struct hda_codec *codec)
4036 {
4037         /*snd_hda_sequence_write(codec, cx_auto_init_verbs);*/
4038         cx_auto_init_output(codec);
4039         cx_auto_init_input(codec);
4040         cx_auto_init_digital(codec);
4041         snd_hda_jack_report_sync(codec);
4042         return 0;
4043 }
4044
4045 static int cx_auto_add_volume_idx(struct hda_codec *codec, const char *basename,
4046                               const char *dir, int cidx,
4047                               hda_nid_t nid, int hda_dir, int amp_idx)
4048 {
4049         static char name[32];
4050         static struct snd_kcontrol_new knew[] = {
4051                 HDA_CODEC_VOLUME(name, 0, 0, 0),
4052                 HDA_CODEC_MUTE(name, 0, 0, 0),
4053         };
4054         static const char * const sfx[2] = { "Volume", "Switch" };
4055         int i, err;
4056
4057         for (i = 0; i < 2; i++) {
4058                 struct snd_kcontrol *kctl;
4059                 knew[i].private_value = HDA_COMPOSE_AMP_VAL(nid, 3, amp_idx,
4060                                                             hda_dir);
4061                 knew[i].subdevice = HDA_SUBDEV_AMP_FLAG;
4062                 knew[i].index = cidx;
4063                 snprintf(name, sizeof(name), "%s%s %s", basename, dir, sfx[i]);
4064                 kctl = snd_ctl_new1(&knew[i], codec);
4065                 if (!kctl)
4066                         return -ENOMEM;
4067                 err = snd_hda_ctl_add(codec, nid, kctl);
4068                 if (err < 0)
4069                         return err;
4070                 if (!(query_amp_caps(codec, nid, hda_dir) & AC_AMPCAP_MUTE))
4071                         break;
4072         }
4073         return 0;
4074 }
4075
4076 #define cx_auto_add_volume(codec, str, dir, cidx, nid, hda_dir)         \
4077         cx_auto_add_volume_idx(codec, str, dir, cidx, nid, hda_dir, 0)
4078
4079 #define cx_auto_add_pb_volume(codec, nid, str, idx)                     \
4080         cx_auto_add_volume(codec, str, " Playback", idx, nid, HDA_OUTPUT)
4081
4082 static int try_add_pb_volume(struct hda_codec *codec, hda_nid_t dac,
4083                              hda_nid_t pin, const char *name, int idx)
4084 {
4085         unsigned int caps;
4086         if (dac && !(dac & DAC_SLAVE_FLAG)) {
4087                 caps = query_amp_caps(codec, dac, HDA_OUTPUT);
4088                 if (caps & AC_AMPCAP_NUM_STEPS)
4089                         return cx_auto_add_pb_volume(codec, dac, name, idx);
4090         }
4091         caps = query_amp_caps(codec, pin, HDA_OUTPUT);
4092         if (caps & AC_AMPCAP_NUM_STEPS)
4093                 return cx_auto_add_pb_volume(codec, pin, name, idx);
4094         return 0;
4095 }
4096
4097 static int cx_auto_build_output_controls(struct hda_codec *codec)
4098 {
4099         struct conexant_spec *spec = codec->spec;
4100         int i, err;
4101         int num_line = 0, num_hp = 0, num_spk = 0;
4102         static const char * const texts[3] = { "Front", "Surround", "CLFE" };
4103
4104         if (spec->dac_info_filled == 1)
4105                 return try_add_pb_volume(codec, spec->dac_info[0].dac,
4106                                          spec->dac_info[0].pin,
4107                                          "Master", 0);
4108
4109         for (i = 0; i < spec->dac_info_filled; i++) {
4110                 const char *label;
4111                 int idx, type;
4112                 hda_nid_t dac = spec->dac_info[i].dac;
4113                 type = spec->dac_info[i].type;
4114                 if (type == AUTO_PIN_LINE_OUT)
4115                         type = spec->autocfg.line_out_type;
4116                 switch (type) {
4117                 case AUTO_PIN_LINE_OUT:
4118                 default:
4119                         label = texts[num_line++];
4120                         idx = 0;
4121                         break;
4122                 case AUTO_PIN_HP_OUT:
4123                         label = "Headphone";
4124                         idx = num_hp++;
4125                         break;
4126                 case AUTO_PIN_SPEAKER_OUT:
4127                         label = "Speaker";
4128                         idx = num_spk++;
4129                         break;
4130                 }
4131                 err = try_add_pb_volume(codec, dac,
4132                                         spec->dac_info[i].pin,
4133                                         label, idx);
4134                 if (err < 0)
4135                         return err;
4136         }
4137
4138         if (spec->auto_mute) {
4139                 err = snd_hda_add_new_ctls(codec, cx_automute_mode_enum);
4140                 if (err < 0)
4141                         return err;
4142         }
4143         
4144         return 0;
4145 }
4146
4147 static int cx_auto_add_capture_volume(struct hda_codec *codec, hda_nid_t nid,
4148                                       const char *label, const char *pfx,
4149                                       int cidx)
4150 {
4151         struct conexant_spec *spec = codec->spec;
4152         int i;
4153
4154         for (i = 0; i < spec->num_adc_nids; i++) {
4155                 hda_nid_t adc_nid = spec->adc_nids[i];
4156                 int idx = get_input_connection(codec, adc_nid, nid);
4157                 if (idx < 0)
4158                         continue;
4159                 if (spec->single_adc_amp)
4160                         idx = 0;
4161                 return cx_auto_add_volume_idx(codec, label, pfx,
4162                                               cidx, adc_nid, HDA_INPUT, idx);
4163         }
4164         return 0;
4165 }
4166
4167 static int cx_auto_add_boost_volume(struct hda_codec *codec, int idx,
4168                                     const char *label, int cidx)
4169 {
4170         struct conexant_spec *spec = codec->spec;
4171         hda_nid_t mux, nid;
4172         int i, con;
4173
4174         nid = spec->imux_info[idx].pin;
4175         if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)
4176                 return cx_auto_add_volume(codec, label, " Boost", cidx,
4177                                           nid, HDA_INPUT);
4178         con = __select_input_connection(codec, spec->imux_info[idx].adc, nid,
4179                                         &mux, false, 0);
4180         if (con < 0)
4181                 return 0;
4182         for (i = 0; i < idx; i++) {
4183                 if (spec->imux_info[i].boost == mux)
4184                         return 0; /* already present */
4185         }
4186
4187         if (get_wcaps(codec, mux) & AC_WCAP_OUT_AMP) {
4188                 spec->imux_info[idx].boost = mux;
4189                 return cx_auto_add_volume(codec, label, " Boost", 0,
4190                                           mux, HDA_OUTPUT);
4191         }
4192         return 0;
4193 }
4194
4195 static int cx_auto_build_input_controls(struct hda_codec *codec)
4196 {
4197         struct conexant_spec *spec = codec->spec;
4198         struct hda_input_mux *imux = &spec->private_imux;
4199         const char *prev_label;
4200         int input_conn[HDA_MAX_NUM_INPUTS];
4201         int i, j, err, cidx;
4202         int multi_connection;
4203
4204         if (!imux->num_items)
4205                 return 0;
4206
4207         multi_connection = 0;
4208         for (i = 0; i < imux->num_items; i++) {
4209                 cidx = get_input_connection(codec, spec->imux_info[i].adc,
4210                                             spec->imux_info[i].pin);
4211                 if (cidx < 0)
4212                         continue;
4213                 input_conn[i] = spec->imux_info[i].adc;
4214                 if (!spec->single_adc_amp)
4215                         input_conn[i] |= cidx << 8;
4216                 if (i > 0 && input_conn[i] != input_conn[0])
4217                         multi_connection = 1;
4218         }
4219
4220         prev_label = NULL;
4221         cidx = 0;
4222         for (i = 0; i < imux->num_items; i++) {
4223                 hda_nid_t nid = spec->imux_info[i].pin;
4224                 const char *label;
4225
4226                 label = hda_get_autocfg_input_label(codec, &spec->autocfg,
4227                                                     spec->imux_info[i].index);
4228                 if (label == prev_label)
4229                         cidx++;
4230                 else
4231                         cidx = 0;
4232                 prev_label = label;
4233
4234                 err = cx_auto_add_boost_volume(codec, i, label, cidx);
4235                 if (err < 0)
4236                         return err;
4237
4238                 if (!multi_connection) {
4239                         if (i > 0)
4240                                 continue;
4241                         err = cx_auto_add_capture_volume(codec, nid,
4242                                                          "Capture", "", cidx);
4243                 } else {
4244                         bool dup_found = false;
4245                         for (j = 0; j < i; j++) {
4246                                 if (input_conn[j] == input_conn[i]) {
4247                                         dup_found = true;
4248                                         break;
4249                                 }
4250                         }
4251                         if (dup_found)
4252                                 continue;
4253                         err = cx_auto_add_capture_volume(codec, nid,
4254                                                          label, " Capture", cidx);
4255                 }
4256                 if (err < 0)
4257                         return err;
4258         }
4259
4260         if (spec->private_imux.num_items > 1 && !spec->auto_mic) {
4261                 err = snd_hda_add_new_ctls(codec, cx_auto_capture_mixers);
4262                 if (err < 0)
4263                         return err;
4264         }
4265
4266         return 0;
4267 }
4268
4269 static int cx_auto_build_controls(struct hda_codec *codec)
4270 {
4271         struct conexant_spec *spec = codec->spec;
4272         int err;
4273
4274         err = cx_auto_build_output_controls(codec);
4275         if (err < 0)
4276                 return err;
4277         err = cx_auto_build_input_controls(codec);
4278         if (err < 0)
4279                 return err;
4280         err = conexant_build_controls(codec);
4281         if (err < 0)
4282                 return err;
4283         err = snd_hda_jack_add_kctls(codec, &spec->autocfg);
4284         if (err < 0)
4285                 return err;
4286         return 0;
4287 }
4288
4289 static int cx_auto_search_adcs(struct hda_codec *codec)
4290 {
4291         struct conexant_spec *spec = codec->spec;
4292         hda_nid_t nid, end_nid;
4293
4294         end_nid = codec->start_nid + codec->num_nodes;
4295         for (nid = codec->start_nid; nid < end_nid; nid++) {
4296                 unsigned int caps = get_wcaps(codec, nid);
4297                 if (get_wcaps_type(caps) != AC_WID_AUD_IN)
4298                         continue;
4299                 if (caps & AC_WCAP_DIGITAL)
4300                         continue;
4301                 if (snd_BUG_ON(spec->num_adc_nids >=
4302                                ARRAY_SIZE(spec->private_adc_nids)))
4303                         break;
4304                 spec->private_adc_nids[spec->num_adc_nids++] = nid;
4305         }
4306         spec->adc_nids = spec->private_adc_nids;
4307         return 0;
4308 }
4309
4310
4311 static const struct hda_codec_ops cx_auto_patch_ops = {
4312         .build_controls = cx_auto_build_controls,
4313         .build_pcms = conexant_build_pcms,
4314         .init = cx_auto_init,
4315         .free = conexant_free,
4316         .unsol_event = cx_auto_unsol_event,
4317 #ifdef CONFIG_SND_HDA_POWER_SAVE
4318         .suspend = conexant_suspend,
4319 #endif
4320         .reboot_notify = snd_hda_shutup_pins,
4321 };
4322
4323 /*
4324  * pin fix-up
4325  */
4326 struct cxt_pincfg {
4327         hda_nid_t nid;
4328         u32 val;
4329 };
4330
4331 static void apply_pincfg(struct hda_codec *codec, const struct cxt_pincfg *cfg)
4332 {
4333         for (; cfg->nid; cfg++)
4334                 snd_hda_codec_set_pincfg(codec, cfg->nid, cfg->val);
4335
4336 }
4337
4338 static void apply_pin_fixup(struct hda_codec *codec,
4339                             const struct snd_pci_quirk *quirk,
4340                             const struct cxt_pincfg **table)
4341 {
4342         quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
4343         if (quirk) {
4344                 snd_printdd(KERN_INFO "hda_codec: applying pincfg for %s\n",
4345                             quirk->name);
4346                 apply_pincfg(codec, table[quirk->value]);
4347         }
4348 }
4349
4350 enum {
4351         CXT_PINCFG_LENOVO_X200,
4352 };
4353
4354 static const struct cxt_pincfg cxt_pincfg_lenovo_x200[] = {
4355         { 0x16, 0x042140ff }, /* HP (seq# overridden) */
4356         { 0x17, 0x21a11000 }, /* dock-mic */
4357         { 0x19, 0x2121103f }, /* dock-HP */
4358         {}
4359 };
4360
4361 static const struct cxt_pincfg *cxt_pincfg_tbl[] = {
4362         [CXT_PINCFG_LENOVO_X200] = cxt_pincfg_lenovo_x200,
4363 };
4364
4365 static const struct snd_pci_quirk cxt_fixups[] = {
4366         SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo X200", CXT_PINCFG_LENOVO_X200),
4367         {}
4368 };
4369
4370 static int patch_conexant_auto(struct hda_codec *codec)
4371 {
4372         struct conexant_spec *spec;
4373         int err;
4374
4375         printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
4376                codec->chip_name);
4377
4378         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
4379         if (!spec)
4380                 return -ENOMEM;
4381         codec->spec = spec;
4382         codec->pin_amp_workaround = 1;
4383
4384         switch (codec->vendor_id) {
4385         case 0x14f15045:
4386                 spec->single_adc_amp = 1;
4387                 break;
4388         }
4389
4390         apply_pin_fixup(codec, cxt_fixups, cxt_pincfg_tbl);
4391
4392         err = cx_auto_search_adcs(codec);
4393         if (err < 0)
4394                 return err;
4395         err = cx_auto_parse_auto_config(codec);
4396         if (err < 0) {
4397                 kfree(codec->spec);
4398                 codec->spec = NULL;
4399                 return err;
4400         }
4401         spec->capture_stream = &cx_auto_pcm_analog_capture;
4402         codec->patch_ops = cx_auto_patch_ops;
4403         if (spec->beep_amp)
4404                 snd_hda_attach_beep_device(codec, spec->beep_amp);
4405
4406         /* Some laptops with Conexant chips show stalls in S3 resume,
4407          * which falls into the single-cmd mode.
4408          * Better to make reset, then.
4409          */
4410         if (!codec->bus->sync_write) {
4411                 snd_printd("hda_codec: "
4412                            "Enable sync_write for stable communication\n");
4413                 codec->bus->sync_write = 1;
4414                 codec->bus->allow_bus_reset = 1;
4415         }
4416
4417         return 0;
4418 }
4419
4420 /*
4421  */
4422
4423 static const struct hda_codec_preset snd_hda_preset_conexant[] = {
4424         { .id = 0x14f15045, .name = "CX20549 (Venice)",
4425           .patch = patch_cxt5045 },
4426         { .id = 0x14f15047, .name = "CX20551 (Waikiki)",
4427           .patch = patch_cxt5047 },
4428         { .id = 0x14f15051, .name = "CX20561 (Hermosa)",
4429           .patch = patch_cxt5051 },
4430         { .id = 0x14f15066, .name = "CX20582 (Pebble)",
4431           .patch = patch_cxt5066 },
4432         { .id = 0x14f15067, .name = "CX20583 (Pebble HSF)",
4433           .patch = patch_cxt5066 },
4434         { .id = 0x14f15068, .name = "CX20584",
4435           .patch = patch_cxt5066 },
4436         { .id = 0x14f15069, .name = "CX20585",
4437           .patch = patch_cxt5066 },
4438         { .id = 0x14f1506c, .name = "CX20588",
4439           .patch = patch_cxt5066 },
4440         { .id = 0x14f1506e, .name = "CX20590",
4441           .patch = patch_cxt5066 },
4442         { .id = 0x14f15097, .name = "CX20631",
4443           .patch = patch_conexant_auto },
4444         { .id = 0x14f15098, .name = "CX20632",
4445           .patch = patch_conexant_auto },
4446         { .id = 0x14f150a1, .name = "CX20641",
4447           .patch = patch_conexant_auto },
4448         { .id = 0x14f150a2, .name = "CX20642",
4449           .patch = patch_conexant_auto },
4450         { .id = 0x14f150ab, .name = "CX20651",
4451           .patch = patch_conexant_auto },
4452         { .id = 0x14f150ac, .name = "CX20652",
4453           .patch = patch_conexant_auto },
4454         { .id = 0x14f150b8, .name = "CX20664",
4455           .patch = patch_conexant_auto },
4456         { .id = 0x14f150b9, .name = "CX20665",
4457           .patch = patch_conexant_auto },
4458         {} /* terminator */
4459 };
4460
4461 MODULE_ALIAS("snd-hda-codec-id:14f15045");
4462 MODULE_ALIAS("snd-hda-codec-id:14f15047");
4463 MODULE_ALIAS("snd-hda-codec-id:14f15051");
4464 MODULE_ALIAS("snd-hda-codec-id:14f15066");
4465 MODULE_ALIAS("snd-hda-codec-id:14f15067");
4466 MODULE_ALIAS("snd-hda-codec-id:14f15068");
4467 MODULE_ALIAS("snd-hda-codec-id:14f15069");
4468 MODULE_ALIAS("snd-hda-codec-id:14f1506c");
4469 MODULE_ALIAS("snd-hda-codec-id:14f1506e");
4470 MODULE_ALIAS("snd-hda-codec-id:14f15097");
4471 MODULE_ALIAS("snd-hda-codec-id:14f15098");
4472 MODULE_ALIAS("snd-hda-codec-id:14f150a1");
4473 MODULE_ALIAS("snd-hda-codec-id:14f150a2");
4474 MODULE_ALIAS("snd-hda-codec-id:14f150ab");
4475 MODULE_ALIAS("snd-hda-codec-id:14f150ac");
4476 MODULE_ALIAS("snd-hda-codec-id:14f150b8");
4477 MODULE_ALIAS("snd-hda-codec-id:14f150b9");
4478
4479 MODULE_LICENSE("GPL");
4480 MODULE_DESCRIPTION("Conexant HD-audio codec");
4481
4482 static struct hda_codec_preset_list conexant_list = {
4483         .preset = snd_hda_preset_conexant,
4484         .owner = THIS_MODULE,
4485 };
4486
4487 static int __init patch_conexant_init(void)
4488 {
4489         return snd_hda_add_codec_preset(&conexant_list);
4490 }
4491
4492 static void __exit patch_conexant_exit(void)
4493 {
4494         snd_hda_delete_codec_preset(&conexant_list);
4495 }
4496
4497 module_init(patch_conexant_init)
4498 module_exit(patch_conexant_exit)