ALSA: hda/conexant - Set up the missing docking-station pins
[~shefty/rdma-dev.git] / sound / pci / hda / patch_conexant.c
1 /*
2  * HD audio interface patch for Conexant HDA audio codec
3  *
4  * Copyright (c) 2006 Pototskiy Akex <alex.pototskiy@gmail.com>
5  *                    Takashi Iwai <tiwai@suse.de>
6  *                    Tobin Davis  <tdavis@dsl-only.net>
7  *
8  *  This driver is free software; you can redistribute it and/or modify
9  *  it under the terms of the GNU General Public License as published by
10  *  the Free Software Foundation; either version 2 of the License, or
11  *  (at your option) any later version.
12  *
13  *  This driver is distributed in the hope that it will be useful,
14  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  *  GNU General Public License for more details.
17  *
18  *  You should have received a copy of the GNU General Public License
19  *  along with this program; if not, write to the Free Software
20  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
21  */
22
23 #include <linux/init.h>
24 #include <linux/delay.h>
25 #include <linux/slab.h>
26 #include <linux/pci.h>
27 #include <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_vols[] = {
469         "Headphone Playback Volume",
470         "Speaker Playback Volume",
471         "Front Playback Volume",
472         "Surround Playback Volume",
473         "CLFE Playback Volume",
474         NULL
475 };
476
477 static const char * const slave_sws[] = {
478         "Headphone Playback Switch",
479         "Speaker Playback Switch",
480         "Front Playback Switch",
481         "Surround Playback Switch",
482         "CLFE Playback Switch",
483         NULL
484 };
485
486 static int conexant_build_controls(struct hda_codec *codec)
487 {
488         struct conexant_spec *spec = codec->spec;
489         unsigned int i;
490         int err;
491
492         for (i = 0; i < spec->num_mixers; i++) {
493                 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
494                 if (err < 0)
495                         return err;
496         }
497         if (spec->multiout.dig_out_nid) {
498                 err = snd_hda_create_spdif_out_ctls(codec,
499                                                     spec->multiout.dig_out_nid,
500                                                     spec->multiout.dig_out_nid);
501                 if (err < 0)
502                         return err;
503                 err = snd_hda_create_spdif_share_sw(codec,
504                                                     &spec->multiout);
505                 if (err < 0)
506                         return err;
507                 spec->multiout.share_spdif = 1;
508         } 
509         if (spec->dig_in_nid) {
510                 err = snd_hda_create_spdif_in_ctls(codec,spec->dig_in_nid);
511                 if (err < 0)
512                         return err;
513         }
514
515         /* if we have no master control, let's create it */
516         if (spec->vmaster_nid &&
517             !snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
518                 unsigned int vmaster_tlv[4];
519                 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
520                                         HDA_OUTPUT, vmaster_tlv);
521                 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
522                                           vmaster_tlv, slave_vols);
523                 if (err < 0)
524                         return err;
525         }
526         if (spec->vmaster_nid &&
527             !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
528                 err = snd_hda_add_vmaster(codec, "Master Playback Switch",
529                                           NULL, slave_sws);
530                 if (err < 0)
531                         return err;
532         }
533
534         if (spec->input_mux) {
535                 err = snd_hda_add_new_ctls(codec, cxt_capture_mixers);
536                 if (err < 0)
537                         return err;
538         }
539
540 #ifdef CONFIG_SND_HDA_INPUT_BEEP
541         /* create beep controls if needed */
542         if (spec->beep_amp) {
543                 const struct snd_kcontrol_new *knew;
544                 for (knew = cxt_beep_mixer; knew->name; knew++) {
545                         struct snd_kcontrol *kctl;
546                         kctl = snd_ctl_new1(knew, codec);
547                         if (!kctl)
548                                 return -ENOMEM;
549                         kctl->private_value = spec->beep_amp;
550                         err = snd_hda_ctl_add(codec, 0, kctl);
551                         if (err < 0)
552                                 return err;
553                 }
554         }
555 #endif
556
557         return 0;
558 }
559
560 #ifdef CONFIG_SND_HDA_POWER_SAVE
561 static int conexant_suspend(struct hda_codec *codec, pm_message_t state)
562 {
563         snd_hda_shutup_pins(codec);
564         return 0;
565 }
566 #endif
567
568 static const struct hda_codec_ops conexant_patch_ops = {
569         .build_controls = conexant_build_controls,
570         .build_pcms = conexant_build_pcms,
571         .init = conexant_init,
572         .free = conexant_free,
573         .set_power_state = conexant_set_power,
574 #ifdef CONFIG_SND_HDA_POWER_SAVE
575         .suspend = conexant_suspend,
576 #endif
577         .reboot_notify = snd_hda_shutup_pins,
578 };
579
580 #ifdef CONFIG_SND_HDA_INPUT_BEEP
581 #define set_beep_amp(spec, nid, idx, dir) \
582         ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 1, idx, dir))
583 #else
584 #define set_beep_amp(spec, nid, idx, dir) /* NOP */
585 #endif
586
587 static int patch_conexant_auto(struct hda_codec *codec);
588 /*
589  * EAPD control
590  * the private value = nid | (invert << 8)
591  */
592
593 #define cxt_eapd_info           snd_ctl_boolean_mono_info
594
595 static int cxt_eapd_get(struct snd_kcontrol *kcontrol,
596                              struct snd_ctl_elem_value *ucontrol)
597 {
598         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
599         struct conexant_spec *spec = codec->spec;
600         int invert = (kcontrol->private_value >> 8) & 1;
601         if (invert)
602                 ucontrol->value.integer.value[0] = !spec->cur_eapd;
603         else
604                 ucontrol->value.integer.value[0] = spec->cur_eapd;
605         return 0;
606
607 }
608
609 static int cxt_eapd_put(struct snd_kcontrol *kcontrol,
610                              struct snd_ctl_elem_value *ucontrol)
611 {
612         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
613         struct conexant_spec *spec = codec->spec;
614         int invert = (kcontrol->private_value >> 8) & 1;
615         hda_nid_t nid = kcontrol->private_value & 0xff;
616         unsigned int eapd;
617
618         eapd = !!ucontrol->value.integer.value[0];
619         if (invert)
620                 eapd = !eapd;
621         if (eapd == spec->cur_eapd)
622                 return 0;
623         
624         spec->cur_eapd = eapd;
625         snd_hda_codec_write_cache(codec, nid,
626                                   0, AC_VERB_SET_EAPD_BTLENABLE,
627                                   eapd ? 0x02 : 0x00);
628         return 1;
629 }
630
631 /* controls for test mode */
632 #ifdef CONFIG_SND_DEBUG
633
634 #define CXT_EAPD_SWITCH(xname, nid, mask) \
635         { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
636           .info = cxt_eapd_info, \
637           .get = cxt_eapd_get, \
638           .put = cxt_eapd_put, \
639           .private_value = nid | (mask<<16) }
640
641
642
643 static int conexant_ch_mode_info(struct snd_kcontrol *kcontrol,
644                                  struct snd_ctl_elem_info *uinfo)
645 {
646         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
647         struct conexant_spec *spec = codec->spec;
648         return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
649                                     spec->num_channel_mode);
650 }
651
652 static int conexant_ch_mode_get(struct snd_kcontrol *kcontrol,
653                                 struct snd_ctl_elem_value *ucontrol)
654 {
655         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
656         struct conexant_spec *spec = codec->spec;
657         return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
658                                    spec->num_channel_mode,
659                                    spec->multiout.max_channels);
660 }
661
662 static int conexant_ch_mode_put(struct snd_kcontrol *kcontrol,
663                                 struct snd_ctl_elem_value *ucontrol)
664 {
665         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
666         struct conexant_spec *spec = codec->spec;
667         int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
668                                       spec->num_channel_mode,
669                                       &spec->multiout.max_channels);
670         if (err >= 0 && spec->need_dac_fix)
671                 spec->multiout.num_dacs = spec->multiout.max_channels / 2;
672         return err;
673 }
674
675 #define CXT_PIN_MODE(xname, nid, dir) \
676         { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
677           .info = conexant_ch_mode_info, \
678           .get = conexant_ch_mode_get, \
679           .put = conexant_ch_mode_put, \
680           .private_value = nid | (dir<<16) }
681
682 #endif /* CONFIG_SND_DEBUG */
683
684 /* Conexant 5045 specific */
685
686 static const hda_nid_t cxt5045_dac_nids[1] = { 0x19 };
687 static const hda_nid_t cxt5045_adc_nids[1] = { 0x1a };
688 static const hda_nid_t cxt5045_capsrc_nids[1] = { 0x1a };
689 #define CXT5045_SPDIF_OUT       0x18
690
691 static const struct hda_channel_mode cxt5045_modes[1] = {
692         { 2, NULL },
693 };
694
695 static const struct hda_input_mux cxt5045_capture_source = {
696         .num_items = 2,
697         .items = {
698                 { "IntMic", 0x1 },
699                 { "ExtMic", 0x2 },
700         }
701 };
702
703 static const struct hda_input_mux cxt5045_capture_source_benq = {
704         .num_items = 5,
705         .items = {
706                 { "IntMic", 0x1 },
707                 { "ExtMic", 0x2 },
708                 { "LineIn", 0x3 },
709                 { "CD",     0x4 },
710                 { "Mixer",  0x0 },
711         }
712 };
713
714 static const struct hda_input_mux cxt5045_capture_source_hp530 = {
715         .num_items = 2,
716         .items = {
717                 { "ExtMic", 0x1 },
718                 { "IntMic", 0x2 },
719         }
720 };
721
722 /* turn on/off EAPD (+ mute HP) as a master switch */
723 static int cxt5045_hp_master_sw_put(struct snd_kcontrol *kcontrol,
724                                     struct snd_ctl_elem_value *ucontrol)
725 {
726         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
727         struct conexant_spec *spec = codec->spec;
728         unsigned int bits;
729
730         if (!cxt_eapd_put(kcontrol, ucontrol))
731                 return 0;
732
733         /* toggle internal speakers mute depending of presence of
734          * the headphone jack
735          */
736         bits = (!spec->hp_present && spec->cur_eapd) ? 0 : HDA_AMP_MUTE;
737         snd_hda_codec_amp_stereo(codec, 0x10, HDA_OUTPUT, 0,
738                                  HDA_AMP_MUTE, bits);
739
740         bits = spec->cur_eapd ? 0 : HDA_AMP_MUTE;
741         snd_hda_codec_amp_stereo(codec, 0x11, HDA_OUTPUT, 0,
742                                  HDA_AMP_MUTE, bits);
743         return 1;
744 }
745
746 /* bind volumes of both NID 0x10 and 0x11 */
747 static const struct hda_bind_ctls cxt5045_hp_bind_master_vol = {
748         .ops = &snd_hda_bind_vol,
749         .values = {
750                 HDA_COMPOSE_AMP_VAL(0x10, 3, 0, HDA_OUTPUT),
751                 HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT),
752                 0
753         },
754 };
755
756 /* toggle input of built-in and mic jack appropriately */
757 static void cxt5045_hp_automic(struct hda_codec *codec)
758 {
759         static const struct hda_verb mic_jack_on[] = {
760                 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
761                 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
762                 {}
763         };
764         static const struct hda_verb mic_jack_off[] = {
765                 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
766                 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
767                 {}
768         };
769         unsigned int present;
770
771         present = snd_hda_jack_detect(codec, 0x12);
772         if (present)
773                 snd_hda_sequence_write(codec, mic_jack_on);
774         else
775                 snd_hda_sequence_write(codec, mic_jack_off);
776 }
777
778
779 /* mute internal speaker if HP is plugged */
780 static void cxt5045_hp_automute(struct hda_codec *codec)
781 {
782         struct conexant_spec *spec = codec->spec;
783         unsigned int bits;
784
785         spec->hp_present = snd_hda_jack_detect(codec, 0x11);
786
787         bits = (spec->hp_present || !spec->cur_eapd) ? HDA_AMP_MUTE : 0; 
788         snd_hda_codec_amp_stereo(codec, 0x10, HDA_OUTPUT, 0,
789                                  HDA_AMP_MUTE, bits);
790 }
791
792 /* unsolicited event for HP jack sensing */
793 static void cxt5045_hp_unsol_event(struct hda_codec *codec,
794                                    unsigned int res)
795 {
796         res >>= 26;
797         switch (res) {
798         case CONEXANT_HP_EVENT:
799                 cxt5045_hp_automute(codec);
800                 break;
801         case CONEXANT_MIC_EVENT:
802                 cxt5045_hp_automic(codec);
803                 break;
804
805         }
806 }
807
808 static const struct snd_kcontrol_new cxt5045_mixers[] = {
809         HDA_CODEC_VOLUME("Internal Mic Capture Volume", 0x1a, 0x01, HDA_INPUT),
810         HDA_CODEC_MUTE("Internal Mic Capture Switch", 0x1a, 0x01, HDA_INPUT),
811         HDA_CODEC_VOLUME("Mic Capture Volume", 0x1a, 0x02, HDA_INPUT),
812         HDA_CODEC_MUTE("Mic Capture Switch", 0x1a, 0x02, HDA_INPUT),
813         HDA_CODEC_VOLUME("PCM Playback Volume", 0x17, 0x0, HDA_INPUT),
814         HDA_CODEC_MUTE("PCM Playback Switch", 0x17, 0x0, HDA_INPUT),
815         HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x17, 0x1, HDA_INPUT),
816         HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x17, 0x1, HDA_INPUT),
817         HDA_CODEC_VOLUME("Mic Playback Volume", 0x17, 0x2, HDA_INPUT),
818         HDA_CODEC_MUTE("Mic Playback Switch", 0x17, 0x2, HDA_INPUT),
819         HDA_BIND_VOL("Master Playback Volume", &cxt5045_hp_bind_master_vol),
820         {
821                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
822                 .name = "Master Playback Switch",
823                 .info = cxt_eapd_info,
824                 .get = cxt_eapd_get,
825                 .put = cxt5045_hp_master_sw_put,
826                 .private_value = 0x10,
827         },
828
829         {}
830 };
831
832 static const struct snd_kcontrol_new cxt5045_benq_mixers[] = {
833         HDA_CODEC_VOLUME("CD Capture Volume", 0x1a, 0x04, HDA_INPUT),
834         HDA_CODEC_MUTE("CD Capture Switch", 0x1a, 0x04, HDA_INPUT),
835         HDA_CODEC_VOLUME("CD Playback Volume", 0x17, 0x4, HDA_INPUT),
836         HDA_CODEC_MUTE("CD Playback Switch", 0x17, 0x4, HDA_INPUT),
837
838         HDA_CODEC_VOLUME("Line In Capture Volume", 0x1a, 0x03, HDA_INPUT),
839         HDA_CODEC_MUTE("Line In Capture Switch", 0x1a, 0x03, HDA_INPUT),
840         HDA_CODEC_VOLUME("Line In Playback Volume", 0x17, 0x3, HDA_INPUT),
841         HDA_CODEC_MUTE("Line In Playback Switch", 0x17, 0x3, HDA_INPUT),
842
843         HDA_CODEC_VOLUME("Mixer Capture Volume", 0x1a, 0x0, HDA_INPUT),
844         HDA_CODEC_MUTE("Mixer Capture Switch", 0x1a, 0x0, HDA_INPUT),
845
846         {}
847 };
848
849 static const struct snd_kcontrol_new cxt5045_mixers_hp530[] = {
850         HDA_CODEC_VOLUME("Internal Mic Capture Volume", 0x1a, 0x02, HDA_INPUT),
851         HDA_CODEC_MUTE("Internal Mic Capture Switch", 0x1a, 0x02, HDA_INPUT),
852         HDA_CODEC_VOLUME("Mic Capture Volume", 0x1a, 0x01, HDA_INPUT),
853         HDA_CODEC_MUTE("Mic Capture Switch", 0x1a, 0x01, HDA_INPUT),
854         HDA_CODEC_VOLUME("PCM Playback Volume", 0x17, 0x0, HDA_INPUT),
855         HDA_CODEC_MUTE("PCM Playback Switch", 0x17, 0x0, HDA_INPUT),
856         HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x17, 0x2, HDA_INPUT),
857         HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x17, 0x2, HDA_INPUT),
858         HDA_CODEC_VOLUME("Mic Playback Volume", 0x17, 0x1, HDA_INPUT),
859         HDA_CODEC_MUTE("Mic Playback Switch", 0x17, 0x1, HDA_INPUT),
860         HDA_BIND_VOL("Master Playback Volume", &cxt5045_hp_bind_master_vol),
861         {
862                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
863                 .name = "Master Playback Switch",
864                 .info = cxt_eapd_info,
865                 .get = cxt_eapd_get,
866                 .put = cxt5045_hp_master_sw_put,
867                 .private_value = 0x10,
868         },
869
870         {}
871 };
872
873 static const struct hda_verb cxt5045_init_verbs[] = {
874         /* Line in, Mic */
875         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_80 },
876         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_80 },
877         /* HP, Amp  */
878         {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
879         {0x10, AC_VERB_SET_CONNECT_SEL, 0x1},
880         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
881         {0x11, AC_VERB_SET_CONNECT_SEL, 0x1},
882         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
883         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
884         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
885         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
886         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
887         /* Record selector: Internal mic */
888         {0x1a, AC_VERB_SET_CONNECT_SEL,0x1},
889         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE,
890          AC_AMP_SET_INPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x17},
891         /* SPDIF route: PCM */
892         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
893         { 0x13, AC_VERB_SET_CONNECT_SEL, 0x0 },
894         /* EAPD */
895         {0x10, AC_VERB_SET_EAPD_BTLENABLE, 0x2 }, /* default on */ 
896         { } /* end */
897 };
898
899 static const struct hda_verb cxt5045_benq_init_verbs[] = {
900         /* Internal Mic, Mic */
901         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_80 },
902         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_80 },
903         /* Line In,HP, Amp  */
904         {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
905         {0x10, AC_VERB_SET_CONNECT_SEL, 0x1},
906         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
907         {0x11, AC_VERB_SET_CONNECT_SEL, 0x1},
908         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
909         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
910         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
911         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
912         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
913         /* Record selector: Internal mic */
914         {0x1a, AC_VERB_SET_CONNECT_SEL, 0x1},
915         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE,
916          AC_AMP_SET_INPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x17},
917         /* SPDIF route: PCM */
918         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
919         {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
920         /* EAPD */
921         {0x10, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
922         { } /* end */
923 };
924
925 static const struct hda_verb cxt5045_hp_sense_init_verbs[] = {
926         /* pin sensing on HP jack */
927         {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT},
928         { } /* end */
929 };
930
931 static const struct hda_verb cxt5045_mic_sense_init_verbs[] = {
932         /* pin sensing on HP jack */
933         {0x12, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT},
934         { } /* end */
935 };
936
937 #ifdef CONFIG_SND_DEBUG
938 /* Test configuration for debugging, modelled after the ALC260 test
939  * configuration.
940  */
941 static const struct hda_input_mux cxt5045_test_capture_source = {
942         .num_items = 5,
943         .items = {
944                 { "MIXER", 0x0 },
945                 { "MIC1 pin", 0x1 },
946                 { "LINE1 pin", 0x2 },
947                 { "HP-OUT pin", 0x3 },
948                 { "CD pin", 0x4 },
949         },
950 };
951
952 static const struct snd_kcontrol_new cxt5045_test_mixer[] = {
953
954         /* Output controls */
955         HDA_CODEC_VOLUME("Speaker Playback Volume", 0x10, 0x0, HDA_OUTPUT),
956         HDA_CODEC_MUTE("Speaker Playback Switch", 0x10, 0x0, HDA_OUTPUT),
957         HDA_CODEC_VOLUME("Node 11 Playback Volume", 0x11, 0x0, HDA_OUTPUT),
958         HDA_CODEC_MUTE("Node 11 Playback Switch", 0x11, 0x0, HDA_OUTPUT),
959         HDA_CODEC_VOLUME("Node 12 Playback Volume", 0x12, 0x0, HDA_OUTPUT),
960         HDA_CODEC_MUTE("Node 12 Playback Switch", 0x12, 0x0, HDA_OUTPUT),
961         
962         /* Modes for retasking pin widgets */
963         CXT_PIN_MODE("HP-OUT pin mode", 0x11, CXT_PIN_DIR_INOUT),
964         CXT_PIN_MODE("LINE1 pin mode", 0x12, CXT_PIN_DIR_INOUT),
965
966         /* EAPD Switch Control */
967         CXT_EAPD_SWITCH("External Amplifier", 0x10, 0x0),
968
969         /* Loopback mixer controls */
970
971         HDA_CODEC_VOLUME("Mixer-1 Volume", 0x17, 0x0, HDA_INPUT),
972         HDA_CODEC_MUTE("Mixer-1 Switch", 0x17, 0x0, HDA_INPUT),
973         HDA_CODEC_VOLUME("Mixer-2 Volume", 0x17, 0x1, HDA_INPUT),
974         HDA_CODEC_MUTE("Mixer-2 Switch", 0x17, 0x1, HDA_INPUT),
975         HDA_CODEC_VOLUME("Mixer-3 Volume", 0x17, 0x2, HDA_INPUT),
976         HDA_CODEC_MUTE("Mixer-3 Switch", 0x17, 0x2, HDA_INPUT),
977         HDA_CODEC_VOLUME("Mixer-4 Volume", 0x17, 0x3, HDA_INPUT),
978         HDA_CODEC_MUTE("Mixer-4 Switch", 0x17, 0x3, HDA_INPUT),
979         HDA_CODEC_VOLUME("Mixer-5 Volume", 0x17, 0x4, HDA_INPUT),
980         HDA_CODEC_MUTE("Mixer-5 Switch", 0x17, 0x4, HDA_INPUT),
981         {
982                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
983                 .name = "Input Source",
984                 .info = conexant_mux_enum_info,
985                 .get = conexant_mux_enum_get,
986                 .put = conexant_mux_enum_put,
987         },
988         /* Audio input controls */
989         HDA_CODEC_VOLUME("Input-1 Volume", 0x1a, 0x0, HDA_INPUT),
990         HDA_CODEC_MUTE("Input-1 Switch", 0x1a, 0x0, HDA_INPUT),
991         HDA_CODEC_VOLUME("Input-2 Volume", 0x1a, 0x1, HDA_INPUT),
992         HDA_CODEC_MUTE("Input-2 Switch", 0x1a, 0x1, HDA_INPUT),
993         HDA_CODEC_VOLUME("Input-3 Volume", 0x1a, 0x2, HDA_INPUT),
994         HDA_CODEC_MUTE("Input-3 Switch", 0x1a, 0x2, HDA_INPUT),
995         HDA_CODEC_VOLUME("Input-4 Volume", 0x1a, 0x3, HDA_INPUT),
996         HDA_CODEC_MUTE("Input-4 Switch", 0x1a, 0x3, HDA_INPUT),
997         HDA_CODEC_VOLUME("Input-5 Volume", 0x1a, 0x4, HDA_INPUT),
998         HDA_CODEC_MUTE("Input-5 Switch", 0x1a, 0x4, HDA_INPUT),
999         { } /* end */
1000 };
1001
1002 static const struct hda_verb cxt5045_test_init_verbs[] = {
1003         /* Set connections */
1004         { 0x10, AC_VERB_SET_CONNECT_SEL, 0x0 },
1005         { 0x11, AC_VERB_SET_CONNECT_SEL, 0x0 },
1006         { 0x12, AC_VERB_SET_CONNECT_SEL, 0x0 },
1007         /* Enable retasking pins as output, initially without power amp */
1008         {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1009         {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1010
1011         /* Disable digital (SPDIF) pins initially, but users can enable
1012          * them via a mixer switch.  In the case of SPDIF-out, this initverb
1013          * payload also sets the generation to 0, output to be in "consumer"
1014          * PCM format, copyright asserted, no pre-emphasis and no validity
1015          * control.
1016          */
1017         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1018         {0x18, AC_VERB_SET_DIGI_CONVERT_1, 0},
1019
1020         /* Start with output sum widgets muted and their output gains at min */
1021         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1022         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1023
1024         /* Unmute retasking pin widget output buffers since the default
1025          * state appears to be output.  As the pin mode is changed by the
1026          * user the pin mode control will take care of enabling the pin's
1027          * input/output buffers as needed.
1028          */
1029         {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1030         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1031
1032         /* Mute capture amp left and right */
1033         {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1034
1035         /* Set ADC connection select to match default mixer setting (mic1
1036          * pin)
1037          */
1038         {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
1039         {0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
1040
1041         /* Mute all inputs to mixer widget (even unconnected ones) */
1042         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* Mixer pin */
1043         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* Mic1 pin */
1044         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* Line pin */
1045         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* HP pin */
1046         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
1047
1048         { }
1049 };
1050 #endif
1051
1052
1053 /* initialize jack-sensing, too */
1054 static int cxt5045_init(struct hda_codec *codec)
1055 {
1056         conexant_init(codec);
1057         cxt5045_hp_automute(codec);
1058         return 0;
1059 }
1060
1061
1062 enum {
1063         CXT5045_LAPTOP_HPSENSE,
1064         CXT5045_LAPTOP_MICSENSE,
1065         CXT5045_LAPTOP_HPMICSENSE,
1066         CXT5045_BENQ,
1067         CXT5045_LAPTOP_HP530,
1068 #ifdef CONFIG_SND_DEBUG
1069         CXT5045_TEST,
1070 #endif
1071         CXT5045_AUTO,
1072         CXT5045_MODELS
1073 };
1074
1075 static const char * const cxt5045_models[CXT5045_MODELS] = {
1076         [CXT5045_LAPTOP_HPSENSE]        = "laptop-hpsense",
1077         [CXT5045_LAPTOP_MICSENSE]       = "laptop-micsense",
1078         [CXT5045_LAPTOP_HPMICSENSE]     = "laptop-hpmicsense",
1079         [CXT5045_BENQ]                  = "benq",
1080         [CXT5045_LAPTOP_HP530]          = "laptop-hp530",
1081 #ifdef CONFIG_SND_DEBUG
1082         [CXT5045_TEST]          = "test",
1083 #endif
1084         [CXT5045_AUTO]                  = "auto",
1085 };
1086
1087 static const struct snd_pci_quirk cxt5045_cfg_tbl[] = {
1088         SND_PCI_QUIRK(0x103c, 0x30d5, "HP 530", CXT5045_LAPTOP_HP530),
1089         SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba P105", CXT5045_LAPTOP_MICSENSE),
1090         SND_PCI_QUIRK(0x152d, 0x0753, "Benq R55E", CXT5045_BENQ),
1091         SND_PCI_QUIRK(0x1734, 0x10ad, "Fujitsu Si1520", CXT5045_LAPTOP_MICSENSE),
1092         SND_PCI_QUIRK(0x1734, 0x10cb, "Fujitsu Si3515", CXT5045_LAPTOP_HPMICSENSE),
1093         SND_PCI_QUIRK(0x1734, 0x110e, "Fujitsu V5505",
1094                       CXT5045_LAPTOP_HPMICSENSE),
1095         SND_PCI_QUIRK(0x1509, 0x1e40, "FIC", CXT5045_LAPTOP_HPMICSENSE),
1096         SND_PCI_QUIRK(0x1509, 0x2f05, "FIC", CXT5045_LAPTOP_HPMICSENSE),
1097         SND_PCI_QUIRK(0x1509, 0x2f06, "FIC", CXT5045_LAPTOP_HPMICSENSE),
1098         SND_PCI_QUIRK_MASK(0x1631, 0xff00, 0xc100, "Packard Bell",
1099                            CXT5045_LAPTOP_HPMICSENSE),
1100         SND_PCI_QUIRK(0x8086, 0x2111, "Conexant Reference board", CXT5045_LAPTOP_HPSENSE),
1101         {}
1102 };
1103
1104 static int patch_cxt5045(struct hda_codec *codec)
1105 {
1106         struct conexant_spec *spec;
1107         int board_config;
1108
1109         board_config = snd_hda_check_board_config(codec, CXT5045_MODELS,
1110                                                   cxt5045_models,
1111                                                   cxt5045_cfg_tbl);
1112         if (board_config < 0)
1113                 board_config = CXT5045_AUTO; /* model=auto as default */
1114         if (board_config == CXT5045_AUTO)
1115                 return patch_conexant_auto(codec);
1116
1117         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1118         if (!spec)
1119                 return -ENOMEM;
1120         codec->spec = spec;
1121         codec->pin_amp_workaround = 1;
1122
1123         spec->multiout.max_channels = 2;
1124         spec->multiout.num_dacs = ARRAY_SIZE(cxt5045_dac_nids);
1125         spec->multiout.dac_nids = cxt5045_dac_nids;
1126         spec->multiout.dig_out_nid = CXT5045_SPDIF_OUT;
1127         spec->num_adc_nids = 1;
1128         spec->adc_nids = cxt5045_adc_nids;
1129         spec->capsrc_nids = cxt5045_capsrc_nids;
1130         spec->input_mux = &cxt5045_capture_source;
1131         spec->num_mixers = 1;
1132         spec->mixers[0] = cxt5045_mixers;
1133         spec->num_init_verbs = 1;
1134         spec->init_verbs[0] = cxt5045_init_verbs;
1135         spec->spdif_route = 0;
1136         spec->num_channel_mode = ARRAY_SIZE(cxt5045_modes);
1137         spec->channel_mode = cxt5045_modes;
1138
1139         set_beep_amp(spec, 0x16, 0, 1);
1140
1141         codec->patch_ops = conexant_patch_ops;
1142
1143         switch (board_config) {
1144         case CXT5045_LAPTOP_HPSENSE:
1145                 codec->patch_ops.unsol_event = cxt5045_hp_unsol_event;
1146                 spec->input_mux = &cxt5045_capture_source;
1147                 spec->num_init_verbs = 2;
1148                 spec->init_verbs[1] = cxt5045_hp_sense_init_verbs;
1149                 spec->mixers[0] = cxt5045_mixers;
1150                 codec->patch_ops.init = cxt5045_init;
1151                 break;
1152         case CXT5045_LAPTOP_MICSENSE:
1153                 codec->patch_ops.unsol_event = cxt5045_hp_unsol_event;
1154                 spec->input_mux = &cxt5045_capture_source;
1155                 spec->num_init_verbs = 2;
1156                 spec->init_verbs[1] = cxt5045_mic_sense_init_verbs;
1157                 spec->mixers[0] = cxt5045_mixers;
1158                 codec->patch_ops.init = cxt5045_init;
1159                 break;
1160         default:
1161         case CXT5045_LAPTOP_HPMICSENSE:
1162                 codec->patch_ops.unsol_event = cxt5045_hp_unsol_event;
1163                 spec->input_mux = &cxt5045_capture_source;
1164                 spec->num_init_verbs = 3;
1165                 spec->init_verbs[1] = cxt5045_hp_sense_init_verbs;
1166                 spec->init_verbs[2] = cxt5045_mic_sense_init_verbs;
1167                 spec->mixers[0] = cxt5045_mixers;
1168                 codec->patch_ops.init = cxt5045_init;
1169                 break;
1170         case CXT5045_BENQ:
1171                 codec->patch_ops.unsol_event = cxt5045_hp_unsol_event;
1172                 spec->input_mux = &cxt5045_capture_source_benq;
1173                 spec->num_init_verbs = 1;
1174                 spec->init_verbs[0] = cxt5045_benq_init_verbs;
1175                 spec->mixers[0] = cxt5045_mixers;
1176                 spec->mixers[1] = cxt5045_benq_mixers;
1177                 spec->num_mixers = 2;
1178                 codec->patch_ops.init = cxt5045_init;
1179                 break;
1180         case CXT5045_LAPTOP_HP530:
1181                 codec->patch_ops.unsol_event = cxt5045_hp_unsol_event;
1182                 spec->input_mux = &cxt5045_capture_source_hp530;
1183                 spec->num_init_verbs = 2;
1184                 spec->init_verbs[1] = cxt5045_hp_sense_init_verbs;
1185                 spec->mixers[0] = cxt5045_mixers_hp530;
1186                 codec->patch_ops.init = cxt5045_init;
1187                 break;
1188 #ifdef CONFIG_SND_DEBUG
1189         case CXT5045_TEST:
1190                 spec->input_mux = &cxt5045_test_capture_source;
1191                 spec->mixers[0] = cxt5045_test_mixer;
1192                 spec->init_verbs[0] = cxt5045_test_init_verbs;
1193                 break;
1194                 
1195 #endif  
1196         }
1197
1198         switch (codec->subsystem_id >> 16) {
1199         case 0x103c:
1200         case 0x1631:
1201         case 0x1734:
1202         case 0x17aa:
1203                 /* HP, Packard Bell, Fujitsu-Siemens & Lenovo laptops have
1204                  * really bad sound over 0dB on NID 0x17. Fix max PCM level to
1205                  * 0 dB (originally it has 0x2b steps with 0dB offset 0x14)
1206                  */
1207                 snd_hda_override_amp_caps(codec, 0x17, HDA_INPUT,
1208                                           (0x14 << AC_AMPCAP_OFFSET_SHIFT) |
1209                                           (0x14 << AC_AMPCAP_NUM_STEPS_SHIFT) |
1210                                           (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) |
1211                                           (1 << AC_AMPCAP_MUTE_SHIFT));
1212                 break;
1213         }
1214
1215         if (spec->beep_amp)
1216                 snd_hda_attach_beep_device(codec, spec->beep_amp);
1217
1218         return 0;
1219 }
1220
1221
1222 /* Conexant 5047 specific */
1223 #define CXT5047_SPDIF_OUT       0x11
1224
1225 static const hda_nid_t cxt5047_dac_nids[1] = { 0x10 }; /* 0x1c */
1226 static const hda_nid_t cxt5047_adc_nids[1] = { 0x12 };
1227 static const hda_nid_t cxt5047_capsrc_nids[1] = { 0x1a };
1228
1229 static const struct hda_channel_mode cxt5047_modes[1] = {
1230         { 2, NULL },
1231 };
1232
1233 static const struct hda_input_mux cxt5047_toshiba_capture_source = {
1234         .num_items = 2,
1235         .items = {
1236                 { "ExtMic", 0x2 },
1237                 { "Line-In", 0x1 },
1238         }
1239 };
1240
1241 /* turn on/off EAPD (+ mute HP) as a master switch */
1242 static int cxt5047_hp_master_sw_put(struct snd_kcontrol *kcontrol,
1243                                     struct snd_ctl_elem_value *ucontrol)
1244 {
1245         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1246         struct conexant_spec *spec = codec->spec;
1247         unsigned int bits;
1248
1249         if (!cxt_eapd_put(kcontrol, ucontrol))
1250                 return 0;
1251
1252         /* toggle internal speakers mute depending of presence of
1253          * the headphone jack
1254          */
1255         bits = (!spec->hp_present && spec->cur_eapd) ? 0 : HDA_AMP_MUTE;
1256         /* NOTE: Conexat codec needs the index for *OUTPUT* amp of
1257          * pin widgets unlike other codecs.  In this case, we need to
1258          * set index 0x01 for the volume from the mixer amp 0x19.
1259          */
1260         snd_hda_codec_amp_stereo(codec, 0x1d, HDA_OUTPUT, 0x01,
1261                                  HDA_AMP_MUTE, bits);
1262         bits = spec->cur_eapd ? 0 : HDA_AMP_MUTE;
1263         snd_hda_codec_amp_stereo(codec, 0x13, HDA_OUTPUT, 0,
1264                                  HDA_AMP_MUTE, bits);
1265         return 1;
1266 }
1267
1268 /* mute internal speaker if HP is plugged */
1269 static void cxt5047_hp_automute(struct hda_codec *codec)
1270 {
1271         struct conexant_spec *spec = codec->spec;
1272         unsigned int bits;
1273
1274         spec->hp_present = snd_hda_jack_detect(codec, 0x13);
1275
1276         bits = (spec->hp_present || !spec->cur_eapd) ? HDA_AMP_MUTE : 0;
1277         /* See the note in cxt5047_hp_master_sw_put */
1278         snd_hda_codec_amp_stereo(codec, 0x1d, HDA_OUTPUT, 0x01,
1279                                  HDA_AMP_MUTE, bits);
1280 }
1281
1282 /* toggle input of built-in and mic jack appropriately */
1283 static void cxt5047_hp_automic(struct hda_codec *codec)
1284 {
1285         static const struct hda_verb mic_jack_on[] = {
1286                 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1287                 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1288                 {}
1289         };
1290         static const struct hda_verb mic_jack_off[] = {
1291                 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1292                 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1293                 {}
1294         };
1295         unsigned int present;
1296
1297         present = snd_hda_jack_detect(codec, 0x15);
1298         if (present)
1299                 snd_hda_sequence_write(codec, mic_jack_on);
1300         else
1301                 snd_hda_sequence_write(codec, mic_jack_off);
1302 }
1303
1304 /* unsolicited event for HP jack sensing */
1305 static void cxt5047_hp_unsol_event(struct hda_codec *codec,
1306                                   unsigned int res)
1307 {
1308         switch (res >> 26) {
1309         case CONEXANT_HP_EVENT:
1310                 cxt5047_hp_automute(codec);
1311                 break;
1312         case CONEXANT_MIC_EVENT:
1313                 cxt5047_hp_automic(codec);
1314                 break;
1315         }
1316 }
1317
1318 static const struct snd_kcontrol_new cxt5047_base_mixers[] = {
1319         HDA_CODEC_VOLUME("Mic Playback Volume", 0x19, 0x02, HDA_INPUT),
1320         HDA_CODEC_MUTE("Mic Playback Switch", 0x19, 0x02, HDA_INPUT),
1321         HDA_CODEC_VOLUME("Mic Boost Volume", 0x1a, 0x0, HDA_OUTPUT),
1322         HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x03, HDA_INPUT),
1323         HDA_CODEC_MUTE("Capture Switch", 0x12, 0x03, HDA_INPUT),
1324         HDA_CODEC_VOLUME("PCM Volume", 0x10, 0x00, HDA_OUTPUT),
1325         HDA_CODEC_MUTE("PCM Switch", 0x10, 0x00, HDA_OUTPUT),
1326         {
1327                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1328                 .name = "Master Playback Switch",
1329                 .info = cxt_eapd_info,
1330                 .get = cxt_eapd_get,
1331                 .put = cxt5047_hp_master_sw_put,
1332                 .private_value = 0x13,
1333         },
1334
1335         {}
1336 };
1337
1338 static const struct snd_kcontrol_new cxt5047_hp_spk_mixers[] = {
1339         /* See the note in cxt5047_hp_master_sw_put */
1340         HDA_CODEC_VOLUME("Speaker Playback Volume", 0x1d, 0x01, HDA_OUTPUT),
1341         HDA_CODEC_VOLUME("Headphone Playback Volume", 0x13, 0x00, HDA_OUTPUT),
1342         {}
1343 };
1344
1345 static const struct snd_kcontrol_new cxt5047_hp_only_mixers[] = {
1346         HDA_CODEC_VOLUME("Master Playback Volume", 0x13, 0x00, HDA_OUTPUT),
1347         { } /* end */
1348 };
1349
1350 static const struct hda_verb cxt5047_init_verbs[] = {
1351         /* Line in, Mic, Built-in Mic */
1352         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1353         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_50 },
1354         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_50 },
1355         /* HP, Speaker  */
1356         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
1357         {0x13, AC_VERB_SET_CONNECT_SEL, 0x0}, /* mixer(0x19) */
1358         {0x1d, AC_VERB_SET_CONNECT_SEL, 0x1}, /* mixer(0x19) */
1359         /* Record selector: Mic */
1360         {0x12, AC_VERB_SET_CONNECT_SEL,0x03},
1361         {0x19, AC_VERB_SET_AMP_GAIN_MUTE,
1362          AC_AMP_SET_INPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x17},
1363         {0x1A, AC_VERB_SET_CONNECT_SEL,0x02},
1364         {0x1A, AC_VERB_SET_AMP_GAIN_MUTE,
1365          AC_AMP_SET_OUTPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x00},
1366         {0x1A, AC_VERB_SET_AMP_GAIN_MUTE,
1367          AC_AMP_SET_OUTPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x03},
1368         /* SPDIF route: PCM */
1369         { 0x18, AC_VERB_SET_CONNECT_SEL, 0x0 },
1370         /* Enable unsolicited events */
1371         {0x13, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT},
1372         {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT},
1373         { } /* end */
1374 };
1375
1376 /* configuration for Toshiba Laptops */
1377 static const struct hda_verb cxt5047_toshiba_init_verbs[] = {
1378         {0x13, AC_VERB_SET_EAPD_BTLENABLE, 0x0}, /* default off */
1379         {}
1380 };
1381
1382 /* Test configuration for debugging, modelled after the ALC260 test
1383  * configuration.
1384  */
1385 #ifdef CONFIG_SND_DEBUG
1386 static const struct hda_input_mux cxt5047_test_capture_source = {
1387         .num_items = 4,
1388         .items = {
1389                 { "LINE1 pin", 0x0 },
1390                 { "MIC1 pin", 0x1 },
1391                 { "MIC2 pin", 0x2 },
1392                 { "CD pin", 0x3 },
1393         },
1394 };
1395
1396 static const struct snd_kcontrol_new cxt5047_test_mixer[] = {
1397
1398         /* Output only controls */
1399         HDA_CODEC_VOLUME("OutAmp-1 Volume", 0x10, 0x0, HDA_OUTPUT),
1400         HDA_CODEC_MUTE("OutAmp-1 Switch", 0x10,0x0, HDA_OUTPUT),
1401         HDA_CODEC_VOLUME("OutAmp-2 Volume", 0x1c, 0x0, HDA_OUTPUT),
1402         HDA_CODEC_MUTE("OutAmp-2 Switch", 0x1c, 0x0, HDA_OUTPUT),
1403         HDA_CODEC_VOLUME("Speaker Playback Volume", 0x1d, 0x0, HDA_OUTPUT),
1404         HDA_CODEC_MUTE("Speaker Playback Switch", 0x1d, 0x0, HDA_OUTPUT),
1405         HDA_CODEC_VOLUME("HeadPhone Playback Volume", 0x13, 0x0, HDA_OUTPUT),
1406         HDA_CODEC_MUTE("HeadPhone Playback Switch", 0x13, 0x0, HDA_OUTPUT),
1407         HDA_CODEC_VOLUME("Line1-Out Playback Volume", 0x14, 0x0, HDA_OUTPUT),
1408         HDA_CODEC_MUTE("Line1-Out Playback Switch", 0x14, 0x0, HDA_OUTPUT),
1409         HDA_CODEC_VOLUME("Line2-Out Playback Volume", 0x15, 0x0, HDA_OUTPUT),
1410         HDA_CODEC_MUTE("Line2-Out Playback Switch", 0x15, 0x0, HDA_OUTPUT),
1411
1412         /* Modes for retasking pin widgets */
1413         CXT_PIN_MODE("LINE1 pin mode", 0x14, CXT_PIN_DIR_INOUT),
1414         CXT_PIN_MODE("MIC1 pin mode", 0x15, CXT_PIN_DIR_INOUT),
1415
1416         /* EAPD Switch Control */
1417         CXT_EAPD_SWITCH("External Amplifier", 0x13, 0x0),
1418
1419         /* Loopback mixer controls */
1420         HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x12, 0x01, HDA_INPUT),
1421         HDA_CODEC_MUTE("MIC1 Playback Switch", 0x12, 0x01, HDA_INPUT),
1422         HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x12, 0x02, HDA_INPUT),
1423         HDA_CODEC_MUTE("MIC2 Playback Switch", 0x12, 0x02, HDA_INPUT),
1424         HDA_CODEC_VOLUME("LINE Playback Volume", 0x12, 0x0, HDA_INPUT),
1425         HDA_CODEC_MUTE("LINE Playback Switch", 0x12, 0x0, HDA_INPUT),
1426         HDA_CODEC_VOLUME("CD Playback Volume", 0x12, 0x04, HDA_INPUT),
1427         HDA_CODEC_MUTE("CD Playback Switch", 0x12, 0x04, HDA_INPUT),
1428
1429         HDA_CODEC_VOLUME("Capture-1 Volume", 0x19, 0x0, HDA_INPUT),
1430         HDA_CODEC_MUTE("Capture-1 Switch", 0x19, 0x0, HDA_INPUT),
1431         HDA_CODEC_VOLUME("Capture-2 Volume", 0x19, 0x1, HDA_INPUT),
1432         HDA_CODEC_MUTE("Capture-2 Switch", 0x19, 0x1, HDA_INPUT),
1433         HDA_CODEC_VOLUME("Capture-3 Volume", 0x19, 0x2, HDA_INPUT),
1434         HDA_CODEC_MUTE("Capture-3 Switch", 0x19, 0x2, HDA_INPUT),
1435         HDA_CODEC_VOLUME("Capture-4 Volume", 0x19, 0x3, HDA_INPUT),
1436         HDA_CODEC_MUTE("Capture-4 Switch", 0x19, 0x3, HDA_INPUT),
1437         {
1438                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1439                 .name = "Input Source",
1440                 .info = conexant_mux_enum_info,
1441                 .get = conexant_mux_enum_get,
1442                 .put = conexant_mux_enum_put,
1443         },
1444         HDA_CODEC_VOLUME("Mic Boost Volume", 0x1a, 0x0, HDA_OUTPUT),
1445
1446         { } /* end */
1447 };
1448
1449 static const struct hda_verb cxt5047_test_init_verbs[] = {
1450         /* Enable retasking pins as output, initially without power amp */
1451         {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1452         {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1453         {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1454
1455         /* Disable digital (SPDIF) pins initially, but users can enable
1456          * them via a mixer switch.  In the case of SPDIF-out, this initverb
1457          * payload also sets the generation to 0, output to be in "consumer"
1458          * PCM format, copyright asserted, no pre-emphasis and no validity
1459          * control.
1460          */
1461         {0x18, AC_VERB_SET_DIGI_CONVERT_1, 0},
1462
1463         /* Ensure mic1, mic2, line1 pin widgets take input from the 
1464          * OUT1 sum bus when acting as an output.
1465          */
1466         {0x1a, AC_VERB_SET_CONNECT_SEL, 0},
1467         {0x1b, AC_VERB_SET_CONNECT_SEL, 0},
1468
1469         /* Start with output sum widgets muted and their output gains at min */
1470         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1471         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1472
1473         /* Unmute retasking pin widget output buffers since the default
1474          * state appears to be output.  As the pin mode is changed by the
1475          * user the pin mode control will take care of enabling the pin's
1476          * input/output buffers as needed.
1477          */
1478         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1479         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1480         {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1481
1482         /* Mute capture amp left and right */
1483         {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1484
1485         /* Set ADC connection select to match default mixer setting (mic1
1486          * pin)
1487          */
1488         {0x12, AC_VERB_SET_CONNECT_SEL, 0x00},
1489
1490         /* Mute all inputs to mixer widget (even unconnected ones) */
1491         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
1492         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
1493         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
1494         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
1495         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
1496         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
1497         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
1498         {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
1499
1500         { }
1501 };
1502 #endif
1503
1504
1505 /* initialize jack-sensing, too */
1506 static int cxt5047_hp_init(struct hda_codec *codec)
1507 {
1508         conexant_init(codec);
1509         cxt5047_hp_automute(codec);
1510         return 0;
1511 }
1512
1513
1514 enum {
1515         CXT5047_LAPTOP,         /* Laptops w/o EAPD support */
1516         CXT5047_LAPTOP_HP,      /* Some HP laptops */
1517         CXT5047_LAPTOP_EAPD,    /* Laptops with EAPD support */
1518 #ifdef CONFIG_SND_DEBUG
1519         CXT5047_TEST,
1520 #endif
1521         CXT5047_AUTO,
1522         CXT5047_MODELS
1523 };
1524
1525 static const char * const cxt5047_models[CXT5047_MODELS] = {
1526         [CXT5047_LAPTOP]        = "laptop",
1527         [CXT5047_LAPTOP_HP]     = "laptop-hp",
1528         [CXT5047_LAPTOP_EAPD]   = "laptop-eapd",
1529 #ifdef CONFIG_SND_DEBUG
1530         [CXT5047_TEST]          = "test",
1531 #endif
1532         [CXT5047_AUTO]          = "auto",
1533 };
1534
1535 static const struct snd_pci_quirk cxt5047_cfg_tbl[] = {
1536         SND_PCI_QUIRK(0x103c, 0x30a5, "HP DV5200T/DV8000T", CXT5047_LAPTOP_HP),
1537         SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3000, "HP DV Series",
1538                            CXT5047_LAPTOP),
1539         SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba P100", CXT5047_LAPTOP_EAPD),
1540         {}
1541 };
1542
1543 static int patch_cxt5047(struct hda_codec *codec)
1544 {
1545         struct conexant_spec *spec;
1546         int board_config;
1547
1548         board_config = snd_hda_check_board_config(codec, CXT5047_MODELS,
1549                                                   cxt5047_models,
1550                                                   cxt5047_cfg_tbl);
1551         if (board_config < 0)
1552                 board_config = CXT5047_AUTO; /* model=auto as default */
1553         if (board_config == CXT5047_AUTO)
1554                 return patch_conexant_auto(codec);
1555
1556         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1557         if (!spec)
1558                 return -ENOMEM;
1559         codec->spec = spec;
1560         codec->pin_amp_workaround = 1;
1561
1562         spec->multiout.max_channels = 2;
1563         spec->multiout.num_dacs = ARRAY_SIZE(cxt5047_dac_nids);
1564         spec->multiout.dac_nids = cxt5047_dac_nids;
1565         spec->multiout.dig_out_nid = CXT5047_SPDIF_OUT;
1566         spec->num_adc_nids = 1;
1567         spec->adc_nids = cxt5047_adc_nids;
1568         spec->capsrc_nids = cxt5047_capsrc_nids;
1569         spec->num_mixers = 1;
1570         spec->mixers[0] = cxt5047_base_mixers;
1571         spec->num_init_verbs = 1;
1572         spec->init_verbs[0] = cxt5047_init_verbs;
1573         spec->spdif_route = 0;
1574         spec->num_channel_mode = ARRAY_SIZE(cxt5047_modes),
1575         spec->channel_mode = cxt5047_modes,
1576
1577         codec->patch_ops = conexant_patch_ops;
1578
1579         switch (board_config) {
1580         case CXT5047_LAPTOP:
1581                 spec->num_mixers = 2;
1582                 spec->mixers[1] = cxt5047_hp_spk_mixers;
1583                 codec->patch_ops.unsol_event = cxt5047_hp_unsol_event;
1584                 break;
1585         case CXT5047_LAPTOP_HP:
1586                 spec->num_mixers = 2;
1587                 spec->mixers[1] = cxt5047_hp_only_mixers;
1588                 codec->patch_ops.unsol_event = cxt5047_hp_unsol_event;
1589                 codec->patch_ops.init = cxt5047_hp_init;
1590                 break;
1591         case CXT5047_LAPTOP_EAPD:
1592                 spec->input_mux = &cxt5047_toshiba_capture_source;
1593                 spec->num_mixers = 2;
1594                 spec->mixers[1] = cxt5047_hp_spk_mixers;
1595                 spec->num_init_verbs = 2;
1596                 spec->init_verbs[1] = cxt5047_toshiba_init_verbs;
1597                 codec->patch_ops.unsol_event = cxt5047_hp_unsol_event;
1598                 break;
1599 #ifdef CONFIG_SND_DEBUG
1600         case CXT5047_TEST:
1601                 spec->input_mux = &cxt5047_test_capture_source;
1602                 spec->mixers[0] = cxt5047_test_mixer;
1603                 spec->init_verbs[0] = cxt5047_test_init_verbs;
1604                 codec->patch_ops.unsol_event = cxt5047_hp_unsol_event;
1605 #endif  
1606         }
1607         spec->vmaster_nid = 0x13;
1608
1609         switch (codec->subsystem_id >> 16) {
1610         case 0x103c:
1611                 /* HP laptops have really bad sound over 0 dB on NID 0x10.
1612                  * Fix max PCM level to 0 dB (originally it has 0x1e steps
1613                  * with 0 dB offset 0x17)
1614                  */
1615                 snd_hda_override_amp_caps(codec, 0x10, HDA_INPUT,
1616                                           (0x17 << AC_AMPCAP_OFFSET_SHIFT) |
1617                                           (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) |
1618                                           (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) |
1619                                           (1 << AC_AMPCAP_MUTE_SHIFT));
1620                 break;
1621         }
1622
1623         return 0;
1624 }
1625
1626 /* Conexant 5051 specific */
1627 static const hda_nid_t cxt5051_dac_nids[1] = { 0x10 };
1628 static const hda_nid_t cxt5051_adc_nids[2] = { 0x14, 0x15 };
1629
1630 static const struct hda_channel_mode cxt5051_modes[1] = {
1631         { 2, NULL },
1632 };
1633
1634 static void cxt5051_update_speaker(struct hda_codec *codec)
1635 {
1636         struct conexant_spec *spec = codec->spec;
1637         unsigned int pinctl;
1638         /* headphone pin */
1639         pinctl = (spec->hp_present && spec->cur_eapd) ? PIN_HP : 0;
1640         snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
1641                             pinctl);
1642         /* speaker pin */
1643         pinctl = (!spec->hp_present && spec->cur_eapd) ? PIN_OUT : 0;
1644         snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
1645                             pinctl);
1646         /* on ideapad there is an aditional speaker (subwoofer) to mute */
1647         if (spec->ideapad)
1648                 snd_hda_codec_write(codec, 0x1b, 0,
1649                                     AC_VERB_SET_PIN_WIDGET_CONTROL,
1650                                     pinctl);
1651 }
1652
1653 /* turn on/off EAPD (+ mute HP) as a master switch */
1654 static int cxt5051_hp_master_sw_put(struct snd_kcontrol *kcontrol,
1655                                     struct snd_ctl_elem_value *ucontrol)
1656 {
1657         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1658
1659         if (!cxt_eapd_put(kcontrol, ucontrol))
1660                 return 0;
1661         cxt5051_update_speaker(codec);
1662         return 1;
1663 }
1664
1665 /* toggle input of built-in and mic jack appropriately */
1666 static void cxt5051_portb_automic(struct hda_codec *codec)
1667 {
1668         struct conexant_spec *spec = codec->spec;
1669         unsigned int present;
1670
1671         if (!(spec->auto_mic & AUTO_MIC_PORTB))
1672                 return;
1673         present = snd_hda_jack_detect(codec, 0x17);
1674         snd_hda_codec_write(codec, 0x14, 0,
1675                             AC_VERB_SET_CONNECT_SEL,
1676                             present ? 0x01 : 0x00);
1677 }
1678
1679 /* switch the current ADC according to the jack state */
1680 static void cxt5051_portc_automic(struct hda_codec *codec)
1681 {
1682         struct conexant_spec *spec = codec->spec;
1683         unsigned int present;
1684         hda_nid_t new_adc;
1685
1686         if (!(spec->auto_mic & AUTO_MIC_PORTC))
1687                 return;
1688         present = snd_hda_jack_detect(codec, 0x18);
1689         if (present)
1690                 spec->cur_adc_idx = 1;
1691         else
1692                 spec->cur_adc_idx = 0;
1693         new_adc = spec->adc_nids[spec->cur_adc_idx];
1694         if (spec->cur_adc && spec->cur_adc != new_adc) {
1695                 /* stream is running, let's swap the current ADC */
1696                 __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1);
1697                 spec->cur_adc = new_adc;
1698                 snd_hda_codec_setup_stream(codec, new_adc,
1699                                            spec->cur_adc_stream_tag, 0,
1700                                            spec->cur_adc_format);
1701         }
1702 }
1703
1704 /* mute internal speaker if HP is plugged */
1705 static void cxt5051_hp_automute(struct hda_codec *codec)
1706 {
1707         struct conexant_spec *spec = codec->spec;
1708
1709         spec->hp_present = snd_hda_jack_detect(codec, 0x16);
1710         cxt5051_update_speaker(codec);
1711 }
1712
1713 /* unsolicited event for HP jack sensing */
1714 static void cxt5051_hp_unsol_event(struct hda_codec *codec,
1715                                    unsigned int res)
1716 {
1717         switch (res >> 26) {
1718         case CONEXANT_HP_EVENT:
1719                 cxt5051_hp_automute(codec);
1720                 break;
1721         case CXT5051_PORTB_EVENT:
1722                 cxt5051_portb_automic(codec);
1723                 break;
1724         case CXT5051_PORTC_EVENT:
1725                 cxt5051_portc_automic(codec);
1726                 break;
1727         }
1728 }
1729
1730 static const struct snd_kcontrol_new cxt5051_playback_mixers[] = {
1731         HDA_CODEC_VOLUME("Master Playback Volume", 0x10, 0x00, HDA_OUTPUT),
1732         {
1733                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1734                 .name = "Master Playback Switch",
1735                 .info = cxt_eapd_info,
1736                 .get = cxt_eapd_get,
1737                 .put = cxt5051_hp_master_sw_put,
1738                 .private_value = 0x1a,
1739         },
1740         {}
1741 };
1742
1743 static const struct snd_kcontrol_new cxt5051_capture_mixers[] = {
1744         HDA_CODEC_VOLUME("Internal Mic Volume", 0x14, 0x00, HDA_INPUT),
1745         HDA_CODEC_MUTE("Internal Mic Switch", 0x14, 0x00, HDA_INPUT),
1746         HDA_CODEC_VOLUME("Mic Volume", 0x14, 0x01, HDA_INPUT),
1747         HDA_CODEC_MUTE("Mic Switch", 0x14, 0x01, HDA_INPUT),
1748         HDA_CODEC_VOLUME("Docking Mic Volume", 0x15, 0x00, HDA_INPUT),
1749         HDA_CODEC_MUTE("Docking Mic Switch", 0x15, 0x00, HDA_INPUT),
1750         {}
1751 };
1752
1753 static const struct snd_kcontrol_new cxt5051_hp_mixers[] = {
1754         HDA_CODEC_VOLUME("Internal Mic Volume", 0x14, 0x00, HDA_INPUT),
1755         HDA_CODEC_MUTE("Internal Mic Switch", 0x14, 0x00, HDA_INPUT),
1756         HDA_CODEC_VOLUME("Mic Volume", 0x15, 0x00, HDA_INPUT),
1757         HDA_CODEC_MUTE("Mic Switch", 0x15, 0x00, HDA_INPUT),
1758         {}
1759 };
1760
1761 static const struct snd_kcontrol_new cxt5051_hp_dv6736_mixers[] = {
1762         HDA_CODEC_VOLUME("Capture Volume", 0x14, 0x00, HDA_INPUT),
1763         HDA_CODEC_MUTE("Capture Switch", 0x14, 0x00, HDA_INPUT),
1764         {}
1765 };
1766
1767 static const struct snd_kcontrol_new cxt5051_f700_mixers[] = {
1768         HDA_CODEC_VOLUME("Capture Volume", 0x14, 0x01, HDA_INPUT),
1769         HDA_CODEC_MUTE("Capture Switch", 0x14, 0x01, HDA_INPUT),
1770         {}
1771 };
1772
1773 static const struct snd_kcontrol_new cxt5051_toshiba_mixers[] = {
1774         HDA_CODEC_VOLUME("Internal Mic Volume", 0x14, 0x00, HDA_INPUT),
1775         HDA_CODEC_MUTE("Internal Mic Switch", 0x14, 0x00, HDA_INPUT),
1776         HDA_CODEC_VOLUME("Mic Volume", 0x14, 0x01, HDA_INPUT),
1777         HDA_CODEC_MUTE("Mic Switch", 0x14, 0x01, HDA_INPUT),
1778         {}
1779 };
1780
1781 static const struct hda_verb cxt5051_init_verbs[] = {
1782         /* Line in, Mic */
1783         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03},
1784         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1785         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03},
1786         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1787         {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1788         {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03},
1789         /* SPK  */
1790         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1791         {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
1792         /* HP, Amp  */
1793         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1794         {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
1795         /* DAC1 */      
1796         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1797         /* Record selector: Internal mic */
1798         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x44},
1799         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1) | 0x44},
1800         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x44},
1801         /* SPDIF route: PCM */
1802         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1803         {0x1c, AC_VERB_SET_CONNECT_SEL, 0x0},
1804         /* EAPD */
1805         {0x1a, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */ 
1806         {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CONEXANT_HP_EVENT},
1807         { } /* end */
1808 };
1809
1810 static const struct hda_verb cxt5051_hp_dv6736_init_verbs[] = {
1811         /* Line in, Mic */
1812         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03},
1813         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1814         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0},
1815         {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0},
1816         /* SPK  */
1817         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1818         {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
1819         /* HP, Amp  */
1820         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1821         {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
1822         /* DAC1 */
1823         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1824         /* Record selector: Internal mic */
1825         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1) | 0x44},
1826         {0x14, AC_VERB_SET_CONNECT_SEL, 0x1},
1827         /* SPDIF route: PCM */
1828         {0x1c, AC_VERB_SET_CONNECT_SEL, 0x0},
1829         /* EAPD */
1830         {0x1a, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
1831         {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CONEXANT_HP_EVENT},
1832         { } /* end */
1833 };
1834
1835 static const struct hda_verb cxt5051_f700_init_verbs[] = {
1836         /* Line in, Mic */
1837         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03},
1838         {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1839         {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0},
1840         {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0},
1841         /* SPK  */
1842         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1843         {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
1844         /* HP, Amp  */
1845         {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1846         {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
1847         /* DAC1 */
1848         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1849         /* Record selector: Internal mic */
1850         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1) | 0x44},
1851         {0x14, AC_VERB_SET_CONNECT_SEL, 0x1},
1852         /* SPDIF route: PCM */
1853         {0x1c, AC_VERB_SET_CONNECT_SEL, 0x0},
1854         /* EAPD */
1855         {0x1a, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
1856         {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CONEXANT_HP_EVENT},
1857         { } /* end */
1858 };
1859
1860 static void cxt5051_init_mic_port(struct hda_codec *codec, hda_nid_t nid,
1861                                  unsigned int event)
1862 {
1863         snd_hda_codec_write(codec, nid, 0,
1864                             AC_VERB_SET_UNSOLICITED_ENABLE,
1865                             AC_USRSP_EN | event);
1866 }
1867
1868 static const struct hda_verb cxt5051_ideapad_init_verbs[] = {
1869         /* Subwoofer */
1870         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1871         {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1872         { } /* end */
1873 };
1874
1875 /* initialize jack-sensing, too */
1876 static int cxt5051_init(struct hda_codec *codec)
1877 {
1878         struct conexant_spec *spec = codec->spec;
1879
1880         conexant_init(codec);
1881
1882         if (spec->auto_mic & AUTO_MIC_PORTB)
1883                 cxt5051_init_mic_port(codec, 0x17, CXT5051_PORTB_EVENT);
1884         if (spec->auto_mic & AUTO_MIC_PORTC)
1885                 cxt5051_init_mic_port(codec, 0x18, CXT5051_PORTC_EVENT);
1886
1887         if (codec->patch_ops.unsol_event) {
1888                 cxt5051_hp_automute(codec);
1889                 cxt5051_portb_automic(codec);
1890                 cxt5051_portc_automic(codec);
1891         }
1892         return 0;
1893 }
1894
1895
1896 enum {
1897         CXT5051_LAPTOP,  /* Laptops w/ EAPD support */
1898         CXT5051_HP,     /* no docking */
1899         CXT5051_HP_DV6736,      /* HP without mic switch */
1900         CXT5051_F700,       /* HP Compaq Presario F700 */
1901         CXT5051_TOSHIBA,        /* Toshiba M300 & co */
1902         CXT5051_IDEAPAD,        /* Lenovo IdeaPad Y430 */
1903         CXT5051_AUTO,           /* auto-parser */
1904         CXT5051_MODELS
1905 };
1906
1907 static const char *const cxt5051_models[CXT5051_MODELS] = {
1908         [CXT5051_LAPTOP]        = "laptop",
1909         [CXT5051_HP]            = "hp",
1910         [CXT5051_HP_DV6736]     = "hp-dv6736",
1911         [CXT5051_F700]          = "hp-700",
1912         [CXT5051_TOSHIBA]       = "toshiba",
1913         [CXT5051_IDEAPAD]       = "ideapad",
1914         [CXT5051_AUTO]          = "auto",
1915 };
1916
1917 static const struct snd_pci_quirk cxt5051_cfg_tbl[] = {
1918         SND_PCI_QUIRK(0x103c, 0x30cf, "HP DV6736", CXT5051_HP_DV6736),
1919         SND_PCI_QUIRK(0x103c, 0x360b, "Compaq Presario CQ60", CXT5051_HP),
1920         SND_PCI_QUIRK(0x103c, 0x30ea, "Compaq Presario F700", CXT5051_F700),
1921         SND_PCI_QUIRK(0x1179, 0xff50, "Toshiba M30x", CXT5051_TOSHIBA),
1922         SND_PCI_QUIRK(0x14f1, 0x0101, "Conexant Reference board",
1923                       CXT5051_LAPTOP),
1924         SND_PCI_QUIRK(0x14f1, 0x5051, "HP Spartan 1.1", CXT5051_HP),
1925         SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo IdeaPad", CXT5051_IDEAPAD),
1926         {}
1927 };
1928
1929 static int patch_cxt5051(struct hda_codec *codec)
1930 {
1931         struct conexant_spec *spec;
1932         int board_config;
1933
1934         board_config = snd_hda_check_board_config(codec, CXT5051_MODELS,
1935                                                   cxt5051_models,
1936                                                   cxt5051_cfg_tbl);
1937         if (board_config < 0)
1938                 board_config = CXT5051_AUTO; /* model=auto as default */
1939         if (board_config == CXT5051_AUTO)
1940                 return patch_conexant_auto(codec);
1941
1942         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1943         if (!spec)
1944                 return -ENOMEM;
1945         codec->spec = spec;
1946         codec->pin_amp_workaround = 1;
1947
1948         codec->patch_ops = conexant_patch_ops;
1949         codec->patch_ops.init = cxt5051_init;
1950
1951         spec->multiout.max_channels = 2;
1952         spec->multiout.num_dacs = ARRAY_SIZE(cxt5051_dac_nids);
1953         spec->multiout.dac_nids = cxt5051_dac_nids;
1954         spec->multiout.dig_out_nid = CXT5051_SPDIF_OUT;
1955         spec->num_adc_nids = 1; /* not 2; via auto-mic switch */
1956         spec->adc_nids = cxt5051_adc_nids;
1957         spec->num_mixers = 2;
1958         spec->mixers[0] = cxt5051_capture_mixers;
1959         spec->mixers[1] = cxt5051_playback_mixers;
1960         spec->num_init_verbs = 1;
1961         spec->init_verbs[0] = cxt5051_init_verbs;
1962         spec->spdif_route = 0;
1963         spec->num_channel_mode = ARRAY_SIZE(cxt5051_modes);
1964         spec->channel_mode = cxt5051_modes;
1965         spec->cur_adc = 0;
1966         spec->cur_adc_idx = 0;
1967
1968         set_beep_amp(spec, 0x13, 0, HDA_OUTPUT);
1969
1970         codec->patch_ops.unsol_event = cxt5051_hp_unsol_event;
1971
1972         spec->auto_mic = AUTO_MIC_PORTB | AUTO_MIC_PORTC;
1973         switch (board_config) {
1974         case CXT5051_HP:
1975                 spec->mixers[0] = cxt5051_hp_mixers;
1976                 break;
1977         case CXT5051_HP_DV6736:
1978                 spec->init_verbs[0] = cxt5051_hp_dv6736_init_verbs;
1979                 spec->mixers[0] = cxt5051_hp_dv6736_mixers;
1980                 spec->auto_mic = 0;
1981                 break;
1982         case CXT5051_F700:
1983                 spec->init_verbs[0] = cxt5051_f700_init_verbs;
1984                 spec->mixers[0] = cxt5051_f700_mixers;
1985                 spec->auto_mic = 0;
1986                 break;
1987         case CXT5051_TOSHIBA:
1988                 spec->mixers[0] = cxt5051_toshiba_mixers;
1989                 spec->auto_mic = AUTO_MIC_PORTB;
1990                 break;
1991         case CXT5051_IDEAPAD:
1992                 spec->init_verbs[spec->num_init_verbs++] =
1993                         cxt5051_ideapad_init_verbs;
1994                 spec->ideapad = 1;
1995                 break;
1996         }
1997
1998         if (spec->beep_amp)
1999                 snd_hda_attach_beep_device(codec, spec->beep_amp);
2000
2001         return 0;
2002 }
2003
2004 /* Conexant 5066 specific */
2005
2006 static const hda_nid_t cxt5066_dac_nids[1] = { 0x10 };
2007 static const hda_nid_t cxt5066_adc_nids[3] = { 0x14, 0x15, 0x16 };
2008 static const hda_nid_t cxt5066_capsrc_nids[1] = { 0x17 };
2009 static const hda_nid_t cxt5066_digout_pin_nids[2] = { 0x20, 0x22 };
2010
2011 /* OLPC's microphone port is DC coupled for use with external sensors,
2012  * therefore we use a 50% mic bias in order to center the input signal with
2013  * the DC input range of the codec. */
2014 #define CXT5066_OLPC_EXT_MIC_BIAS PIN_VREF50
2015
2016 static const struct hda_channel_mode cxt5066_modes[1] = {
2017         { 2, NULL },
2018 };
2019
2020 #define HP_PRESENT_PORT_A       (1 << 0)
2021 #define HP_PRESENT_PORT_D       (1 << 1)
2022 #define hp_port_a_present(spec) ((spec)->hp_present & HP_PRESENT_PORT_A)
2023 #define hp_port_d_present(spec) ((spec)->hp_present & HP_PRESENT_PORT_D)
2024
2025 static void cxt5066_update_speaker(struct hda_codec *codec)
2026 {
2027         struct conexant_spec *spec = codec->spec;
2028         unsigned int pinctl;
2029
2030         snd_printdd("CXT5066: update speaker, hp_present=%d, cur_eapd=%d\n",
2031                     spec->hp_present, spec->cur_eapd);
2032
2033         /* Port A (HP) */
2034         pinctl = (hp_port_a_present(spec) && spec->cur_eapd) ? PIN_HP : 0;
2035         snd_hda_codec_write(codec, 0x19, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
2036                         pinctl);
2037
2038         /* Port D (HP/LO) */
2039         pinctl = spec->cur_eapd ? spec->port_d_mode : 0;
2040         if (spec->dell_automute || spec->thinkpad) {
2041                 /* Mute if Port A is connected */
2042                 if (hp_port_a_present(spec))
2043                         pinctl = 0;
2044         } else {
2045                 /* Thinkpad/Dell doesn't give pin-D status */
2046                 if (!hp_port_d_present(spec))
2047                         pinctl = 0;
2048         }
2049         snd_hda_codec_write(codec, 0x1c, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
2050                         pinctl);
2051
2052         /* CLASS_D AMP */
2053         pinctl = (!spec->hp_present && spec->cur_eapd) ? PIN_OUT : 0;
2054         snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
2055                         pinctl);
2056 }
2057
2058 /* turn on/off EAPD (+ mute HP) as a master switch */
2059 static int cxt5066_hp_master_sw_put(struct snd_kcontrol *kcontrol,
2060                                     struct snd_ctl_elem_value *ucontrol)
2061 {
2062         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2063
2064         if (!cxt_eapd_put(kcontrol, ucontrol))
2065                 return 0;
2066
2067         cxt5066_update_speaker(codec);
2068         return 1;
2069 }
2070
2071 static const struct hda_input_mux cxt5066_olpc_dc_bias = {
2072         .num_items = 3,
2073         .items = {
2074                 { "Off", PIN_IN },
2075                 { "50%", PIN_VREF50 },
2076                 { "80%", PIN_VREF80 },
2077         },
2078 };
2079
2080 static int cxt5066_set_olpc_dc_bias(struct hda_codec *codec)
2081 {
2082         struct conexant_spec *spec = codec->spec;
2083         /* Even though port F is the DC input, the bias is controlled on port B.
2084          * we also leave that port as an active input (but unselected) in DC mode
2085          * just in case that is necessary to make the bias setting take effect. */
2086         return snd_hda_codec_write_cache(codec, 0x1a, 0,
2087                 AC_VERB_SET_PIN_WIDGET_CONTROL,
2088                 cxt5066_olpc_dc_bias.items[spec->dc_input_bias].index);
2089 }
2090
2091 /* OLPC defers mic widget control until when capture is started because the
2092  * microphone LED comes on as soon as these settings are put in place. if we
2093  * did this before recording, it would give the false indication that recording
2094  * is happening when it is not. */
2095 static void cxt5066_olpc_select_mic(struct hda_codec *codec)
2096 {
2097         struct conexant_spec *spec = codec->spec;
2098         if (!spec->recording)
2099                 return;
2100
2101         if (spec->dc_enable) {
2102                 /* in DC mode we ignore presence detection and just use the jack
2103                  * through our special DC port */
2104                 const struct hda_verb enable_dc_mode[] = {
2105                         /* disble internal mic, port C */
2106                         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2107
2108                         /* enable DC capture, port F */
2109                         {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2110                         {},
2111                 };
2112
2113                 snd_hda_sequence_write(codec, enable_dc_mode);
2114                 /* port B input disabled (and bias set) through the following call */
2115                 cxt5066_set_olpc_dc_bias(codec);
2116                 return;
2117         }
2118
2119         /* disable DC (port F) */
2120         snd_hda_codec_write(codec, 0x1e, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
2121
2122         /* external mic, port B */
2123         snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
2124                 spec->ext_mic_present ? CXT5066_OLPC_EXT_MIC_BIAS : 0);
2125
2126         /* internal mic, port C */
2127         snd_hda_codec_write(codec, 0x1b, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
2128                 spec->ext_mic_present ? 0 : PIN_VREF80);
2129 }
2130
2131 /* toggle input of built-in and mic jack appropriately */
2132 static void cxt5066_olpc_automic(struct hda_codec *codec)
2133 {
2134         struct conexant_spec *spec = codec->spec;
2135         unsigned int present;
2136
2137         if (spec->dc_enable) /* don't do presence detection in DC mode */
2138                 return;
2139
2140         present = snd_hda_codec_read(codec, 0x1a, 0,
2141                                      AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2142         if (present)
2143                 snd_printdd("CXT5066: external microphone detected\n");
2144         else
2145                 snd_printdd("CXT5066: external microphone absent\n");
2146
2147         snd_hda_codec_write(codec, 0x17, 0, AC_VERB_SET_CONNECT_SEL,
2148                 present ? 0 : 1);
2149         spec->ext_mic_present = !!present;
2150
2151         cxt5066_olpc_select_mic(codec);
2152 }
2153
2154 /* toggle input of built-in digital mic and mic jack appropriately */
2155 static void cxt5066_vostro_automic(struct hda_codec *codec)
2156 {
2157         unsigned int present;
2158
2159         struct hda_verb ext_mic_present[] = {
2160                 /* enable external mic, port B */
2161                 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2162
2163                 /* switch to external mic input */
2164                 {0x17, AC_VERB_SET_CONNECT_SEL, 0},
2165                 {0x14, AC_VERB_SET_CONNECT_SEL, 0},
2166
2167                 /* disable internal digital mic */
2168                 {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2169                 {}
2170         };
2171         static const struct hda_verb ext_mic_absent[] = {
2172                 /* enable internal mic, port C */
2173                 {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2174
2175                 /* switch to internal mic input */
2176                 {0x14, AC_VERB_SET_CONNECT_SEL, 2},
2177
2178                 /* disable external mic, port B */
2179                 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2180                 {}
2181         };
2182
2183         present = snd_hda_jack_detect(codec, 0x1a);
2184         if (present) {
2185                 snd_printdd("CXT5066: external microphone detected\n");
2186                 snd_hda_sequence_write(codec, ext_mic_present);
2187         } else {
2188                 snd_printdd("CXT5066: external microphone absent\n");
2189                 snd_hda_sequence_write(codec, ext_mic_absent);
2190         }
2191 }
2192
2193 /* toggle input of built-in digital mic and mic jack appropriately */
2194 static void cxt5066_ideapad_automic(struct hda_codec *codec)
2195 {
2196         unsigned int present;
2197
2198         struct hda_verb ext_mic_present[] = {
2199                 {0x14, AC_VERB_SET_CONNECT_SEL, 0},
2200                 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2201                 {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2202                 {}
2203         };
2204         static const struct hda_verb ext_mic_absent[] = {
2205                 {0x14, AC_VERB_SET_CONNECT_SEL, 2},
2206                 {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2207                 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2208                 {}
2209         };
2210
2211         present = snd_hda_jack_detect(codec, 0x1b);
2212         if (present) {
2213                 snd_printdd("CXT5066: external microphone detected\n");
2214                 snd_hda_sequence_write(codec, ext_mic_present);
2215         } else {
2216                 snd_printdd("CXT5066: external microphone absent\n");
2217                 snd_hda_sequence_write(codec, ext_mic_absent);
2218         }
2219 }
2220
2221
2222 /* toggle input of built-in digital mic and mic jack appropriately */
2223 static void cxt5066_asus_automic(struct hda_codec *codec)
2224 {
2225         unsigned int present;
2226
2227         present = snd_hda_jack_detect(codec, 0x1b);
2228         snd_printdd("CXT5066: external microphone present=%d\n", present);
2229         snd_hda_codec_write(codec, 0x17, 0, AC_VERB_SET_CONNECT_SEL,
2230                             present ? 1 : 0);
2231 }
2232
2233
2234 /* toggle input of built-in digital mic and mic jack appropriately */
2235 static void cxt5066_hp_laptop_automic(struct hda_codec *codec)
2236 {
2237         unsigned int present;
2238
2239         present = snd_hda_jack_detect(codec, 0x1b);
2240         snd_printdd("CXT5066: external microphone present=%d\n", present);
2241         snd_hda_codec_write(codec, 0x17, 0, AC_VERB_SET_CONNECT_SEL,
2242                             present ? 1 : 3);
2243 }
2244
2245
2246 /* toggle input of built-in digital mic and mic jack appropriately
2247    order is: external mic -> dock mic -> interal mic */
2248 static void cxt5066_thinkpad_automic(struct hda_codec *codec)
2249 {
2250         unsigned int ext_present, dock_present;
2251
2252         static const struct hda_verb ext_mic_present[] = {
2253                 {0x14, AC_VERB_SET_CONNECT_SEL, 0},
2254                 {0x17, AC_VERB_SET_CONNECT_SEL, 1},
2255                 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2256                 {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2257                 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2258                 {}
2259         };
2260         static const struct hda_verb dock_mic_present[] = {
2261                 {0x14, AC_VERB_SET_CONNECT_SEL, 0},
2262                 {0x17, AC_VERB_SET_CONNECT_SEL, 0},
2263                 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2264                 {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2265                 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2266                 {}
2267         };
2268         static const struct hda_verb ext_mic_absent[] = {
2269                 {0x14, AC_VERB_SET_CONNECT_SEL, 2},
2270                 {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2271                 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2272                 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2273                 {}
2274         };
2275
2276         ext_present = snd_hda_jack_detect(codec, 0x1b);
2277         dock_present = snd_hda_jack_detect(codec, 0x1a);
2278         if (ext_present) {
2279                 snd_printdd("CXT5066: external microphone detected\n");
2280                 snd_hda_sequence_write(codec, ext_mic_present);
2281         } else if (dock_present) {
2282                 snd_printdd("CXT5066: dock microphone detected\n");
2283                 snd_hda_sequence_write(codec, dock_mic_present);
2284         } else {
2285                 snd_printdd("CXT5066: external microphone absent\n");
2286                 snd_hda_sequence_write(codec, ext_mic_absent);
2287         }
2288 }
2289
2290 /* mute internal speaker if HP is plugged */
2291 static void cxt5066_hp_automute(struct hda_codec *codec)
2292 {
2293         struct conexant_spec *spec = codec->spec;
2294         unsigned int portA, portD;
2295
2296         /* Port A */
2297         portA = snd_hda_jack_detect(codec, 0x19);
2298
2299         /* Port D */
2300         portD = snd_hda_jack_detect(codec, 0x1c);
2301
2302         spec->hp_present = portA ? HP_PRESENT_PORT_A : 0;
2303         spec->hp_present |= portD ? HP_PRESENT_PORT_D : 0;
2304         snd_printdd("CXT5066: hp automute portA=%x portD=%x present=%d\n",
2305                 portA, portD, spec->hp_present);
2306         cxt5066_update_speaker(codec);
2307 }
2308
2309 /* Dispatch the right mic autoswitch function */
2310 static void cxt5066_automic(struct hda_codec *codec)
2311 {
2312         struct conexant_spec *spec = codec->spec;
2313
2314         if (spec->dell_vostro)
2315                 cxt5066_vostro_automic(codec);
2316         else if (spec->ideapad)
2317                 cxt5066_ideapad_automic(codec);
2318         else if (spec->thinkpad)
2319                 cxt5066_thinkpad_automic(codec);
2320         else if (spec->hp_laptop)
2321                 cxt5066_hp_laptop_automic(codec);
2322         else if (spec->asus)
2323                 cxt5066_asus_automic(codec);
2324 }
2325
2326 /* unsolicited event for jack sensing */
2327 static void cxt5066_olpc_unsol_event(struct hda_codec *codec, unsigned int res)
2328 {
2329         struct conexant_spec *spec = codec->spec;
2330         snd_printdd("CXT5066: unsol event %x (%x)\n", res, res >> 26);
2331         switch (res >> 26) {
2332         case CONEXANT_HP_EVENT:
2333                 cxt5066_hp_automute(codec);
2334                 break;
2335         case CONEXANT_MIC_EVENT:
2336                 /* ignore mic events in DC mode; we're always using the jack */
2337                 if (!spec->dc_enable)
2338                         cxt5066_olpc_automic(codec);
2339                 break;
2340         }
2341 }
2342
2343 /* unsolicited event for jack sensing */
2344 static void cxt5066_unsol_event(struct hda_codec *codec, unsigned int res)
2345 {
2346         snd_printdd("CXT5066: unsol event %x (%x)\n", res, res >> 26);
2347         switch (res >> 26) {
2348         case CONEXANT_HP_EVENT:
2349                 cxt5066_hp_automute(codec);
2350                 break;
2351         case CONEXANT_MIC_EVENT:
2352                 cxt5066_automic(codec);
2353                 break;
2354         }
2355 }
2356
2357
2358 static const struct hda_input_mux cxt5066_analog_mic_boost = {
2359         .num_items = 5,
2360         .items = {
2361                 { "0dB",  0 },
2362                 { "10dB", 1 },
2363                 { "20dB", 2 },
2364                 { "30dB", 3 },
2365                 { "40dB", 4 },
2366         },
2367 };
2368
2369 static void cxt5066_set_mic_boost(struct hda_codec *codec)
2370 {
2371         struct conexant_spec *spec = codec->spec;
2372         snd_hda_codec_write_cache(codec, 0x17, 0,
2373                 AC_VERB_SET_AMP_GAIN_MUTE,
2374                 AC_AMP_SET_RIGHT | AC_AMP_SET_LEFT | AC_AMP_SET_OUTPUT |
2375                         cxt5066_analog_mic_boost.items[spec->mic_boost].index);
2376         if (spec->ideapad || spec->thinkpad) {
2377                 /* adjust the internal mic as well...it is not through 0x17 */
2378                 snd_hda_codec_write_cache(codec, 0x23, 0,
2379                         AC_VERB_SET_AMP_GAIN_MUTE,
2380                         AC_AMP_SET_RIGHT | AC_AMP_SET_LEFT | AC_AMP_SET_INPUT |
2381                                 cxt5066_analog_mic_boost.
2382                                         items[spec->mic_boost].index);
2383         }
2384 }
2385
2386 static int cxt5066_mic_boost_mux_enum_info(struct snd_kcontrol *kcontrol,
2387                                            struct snd_ctl_elem_info *uinfo)
2388 {
2389         return snd_hda_input_mux_info(&cxt5066_analog_mic_boost, uinfo);
2390 }
2391
2392 static int cxt5066_mic_boost_mux_enum_get(struct snd_kcontrol *kcontrol,
2393                                           struct snd_ctl_elem_value *ucontrol)
2394 {
2395         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2396         struct conexant_spec *spec = codec->spec;
2397         ucontrol->value.enumerated.item[0] = spec->mic_boost;
2398         return 0;
2399 }
2400
2401 static int cxt5066_mic_boost_mux_enum_put(struct snd_kcontrol *kcontrol,
2402                                           struct snd_ctl_elem_value *ucontrol)
2403 {
2404         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2405         struct conexant_spec *spec = codec->spec;
2406         const struct hda_input_mux *imux = &cxt5066_analog_mic_boost;
2407         unsigned int idx;
2408         idx = ucontrol->value.enumerated.item[0];
2409         if (idx >= imux->num_items)
2410                 idx = imux->num_items - 1;
2411
2412         spec->mic_boost = idx;
2413         if (!spec->dc_enable)
2414                 cxt5066_set_mic_boost(codec);
2415         return 1;
2416 }
2417
2418 static void cxt5066_enable_dc(struct hda_codec *codec)
2419 {
2420         const struct hda_verb enable_dc_mode[] = {
2421                 /* disable gain */
2422                 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2423
2424                 /* switch to DC input */
2425                 {0x17, AC_VERB_SET_CONNECT_SEL, 3},
2426                 {}
2427         };
2428
2429         /* configure as input source */
2430         snd_hda_sequence_write(codec, enable_dc_mode);
2431         cxt5066_olpc_select_mic(codec); /* also sets configured bias */
2432 }
2433
2434 static void cxt5066_disable_dc(struct hda_codec *codec)
2435 {
2436         /* reconfigure input source */
2437         cxt5066_set_mic_boost(codec);
2438         /* automic also selects the right mic if we're recording */
2439         cxt5066_olpc_automic(codec);
2440 }
2441
2442 static int cxt5066_olpc_dc_get(struct snd_kcontrol *kcontrol,
2443                              struct snd_ctl_elem_value *ucontrol)
2444 {
2445         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2446         struct conexant_spec *spec = codec->spec;
2447         ucontrol->value.integer.value[0] = spec->dc_enable;
2448         return 0;
2449 }
2450
2451 static int cxt5066_olpc_dc_put(struct snd_kcontrol *kcontrol,
2452                              struct snd_ctl_elem_value *ucontrol)
2453 {
2454         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2455         struct conexant_spec *spec = codec->spec;
2456         int dc_enable = !!ucontrol->value.integer.value[0];
2457
2458         if (dc_enable == spec->dc_enable)
2459                 return 0;
2460
2461         spec->dc_enable = dc_enable;
2462         if (dc_enable)
2463                 cxt5066_enable_dc(codec);
2464         else
2465                 cxt5066_disable_dc(codec);
2466
2467         return 1;
2468 }
2469
2470 static int cxt5066_olpc_dc_bias_enum_info(struct snd_kcontrol *kcontrol,
2471                                            struct snd_ctl_elem_info *uinfo)
2472 {
2473         return snd_hda_input_mux_info(&cxt5066_olpc_dc_bias, uinfo);
2474 }
2475
2476 static int cxt5066_olpc_dc_bias_enum_get(struct snd_kcontrol *kcontrol,
2477                                           struct snd_ctl_elem_value *ucontrol)
2478 {
2479         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2480         struct conexant_spec *spec = codec->spec;
2481         ucontrol->value.enumerated.item[0] = spec->dc_input_bias;
2482         return 0;
2483 }
2484
2485 static int cxt5066_olpc_dc_bias_enum_put(struct snd_kcontrol *kcontrol,
2486                                           struct snd_ctl_elem_value *ucontrol)
2487 {
2488         struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2489         struct conexant_spec *spec = codec->spec;
2490         const struct hda_input_mux *imux = &cxt5066_analog_mic_boost;
2491         unsigned int idx;
2492
2493         idx = ucontrol->value.enumerated.item[0];
2494         if (idx >= imux->num_items)
2495                 idx = imux->num_items - 1;
2496
2497         spec->dc_input_bias = idx;
2498         if (spec->dc_enable)
2499                 cxt5066_set_olpc_dc_bias(codec);
2500         return 1;
2501 }
2502
2503 static void cxt5066_olpc_capture_prepare(struct hda_codec *codec)
2504 {
2505         struct conexant_spec *spec = codec->spec;
2506         /* mark as recording and configure the microphone widget so that the
2507          * recording LED comes on. */
2508         spec->recording = 1;
2509         cxt5066_olpc_select_mic(codec);
2510 }
2511
2512 static void cxt5066_olpc_capture_cleanup(struct hda_codec *codec)
2513 {
2514         struct conexant_spec *spec = codec->spec;
2515         const struct hda_verb disable_mics[] = {
2516                 /* disable external mic, port B */
2517                 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2518
2519                 /* disble internal mic, port C */
2520                 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2521
2522                 /* disable DC capture, port F */
2523                 {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2524                 {},
2525         };
2526
2527         snd_hda_sequence_write(codec, disable_mics);
2528         spec->recording = 0;
2529 }
2530
2531 static void conexant_check_dig_outs(struct hda_codec *codec,
2532                                     const hda_nid_t *dig_pins,
2533                                     int num_pins)
2534 {
2535         struct conexant_spec *spec = codec->spec;
2536         hda_nid_t *nid_loc = &spec->multiout.dig_out_nid;
2537         int i;
2538
2539         for (i = 0; i < num_pins; i++, dig_pins++) {
2540                 unsigned int cfg = snd_hda_codec_get_pincfg(codec, *dig_pins);
2541                 if (get_defcfg_connect(cfg) == AC_JACK_PORT_NONE)
2542                         continue;
2543                 if (snd_hda_get_connections(codec, *dig_pins, nid_loc, 1) != 1)
2544                         continue;
2545                 if (spec->slave_dig_outs[0])
2546                         nid_loc++;
2547                 else
2548                         nid_loc = spec->slave_dig_outs;
2549         }
2550 }
2551
2552 static const struct hda_input_mux cxt5066_capture_source = {
2553         .num_items = 4,
2554         .items = {
2555                 { "Mic B", 0 },
2556                 { "Mic C", 1 },
2557                 { "Mic E", 2 },
2558                 { "Mic F", 3 },
2559         },
2560 };
2561
2562 static const struct hda_bind_ctls cxt5066_bind_capture_vol_others = {
2563         .ops = &snd_hda_bind_vol,
2564         .values = {
2565                 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_INPUT),
2566                 HDA_COMPOSE_AMP_VAL(0x14, 3, 2, HDA_INPUT),
2567                 0
2568         },
2569 };
2570
2571 static const struct hda_bind_ctls cxt5066_bind_capture_sw_others = {
2572         .ops = &snd_hda_bind_sw,
2573         .values = {
2574                 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_INPUT),
2575                 HDA_COMPOSE_AMP_VAL(0x14, 3, 2, HDA_INPUT),
2576                 0
2577         },
2578 };
2579
2580 static const struct snd_kcontrol_new cxt5066_mixer_master[] = {
2581         HDA_CODEC_VOLUME("Master Playback Volume", 0x10, 0x00, HDA_OUTPUT),
2582         {}
2583 };
2584
2585 static const struct snd_kcontrol_new cxt5066_mixer_master_olpc[] = {
2586         {
2587                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2588                 .name = "Master Playback Volume",
2589                 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
2590                                   SNDRV_CTL_ELEM_ACCESS_TLV_READ |
2591                                   SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK,
2592                 .subdevice = HDA_SUBDEV_AMP_FLAG,
2593                 .info = snd_hda_mixer_amp_volume_info,
2594                 .get = snd_hda_mixer_amp_volume_get,
2595                 .put = snd_hda_mixer_amp_volume_put,
2596                 .tlv = { .c = snd_hda_mixer_amp_tlv },
2597                 /* offset by 28 volume steps to limit minimum gain to -46dB */
2598                 .private_value =
2599                         HDA_COMPOSE_AMP_VAL_OFS(0x10, 3, 0, HDA_OUTPUT, 28),
2600         },
2601         {}
2602 };
2603
2604 static const struct snd_kcontrol_new cxt5066_mixer_olpc_dc[] = {
2605         {
2606                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2607                 .name = "DC Mode Enable Switch",
2608                 .info = snd_ctl_boolean_mono_info,
2609                 .get = cxt5066_olpc_dc_get,
2610                 .put = cxt5066_olpc_dc_put,
2611         },
2612         {
2613                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2614                 .name = "DC Input Bias Enum",
2615                 .info = cxt5066_olpc_dc_bias_enum_info,
2616                 .get = cxt5066_olpc_dc_bias_enum_get,
2617                 .put = cxt5066_olpc_dc_bias_enum_put,
2618         },
2619         {}
2620 };
2621
2622 static const struct snd_kcontrol_new cxt5066_mixers[] = {
2623         {
2624                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2625                 .name = "Master Playback Switch",
2626                 .info = cxt_eapd_info,
2627                 .get = cxt_eapd_get,
2628                 .put = cxt5066_hp_master_sw_put,
2629                 .private_value = 0x1d,
2630         },
2631
2632         {
2633                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2634                 .name = "Analog Mic Boost Capture Enum",
2635                 .info = cxt5066_mic_boost_mux_enum_info,
2636                 .get = cxt5066_mic_boost_mux_enum_get,
2637                 .put = cxt5066_mic_boost_mux_enum_put,
2638         },
2639
2640         HDA_BIND_VOL("Capture Volume", &cxt5066_bind_capture_vol_others),
2641         HDA_BIND_SW("Capture Switch", &cxt5066_bind_capture_sw_others),
2642         {}
2643 };
2644
2645 static const struct snd_kcontrol_new cxt5066_vostro_mixers[] = {
2646         {
2647                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2648                 .name = "Internal Mic Boost Capture Enum",
2649                 .info = cxt5066_mic_boost_mux_enum_info,
2650                 .get = cxt5066_mic_boost_mux_enum_get,
2651                 .put = cxt5066_mic_boost_mux_enum_put,
2652                 .private_value = 0x23 | 0x100,
2653         },
2654         {}
2655 };
2656
2657 static const struct hda_verb cxt5066_init_verbs[] = {
2658         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, /* Port B */
2659         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, /* Port C */
2660         {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Port F */
2661         {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Port E */
2662
2663         /* Speakers  */
2664         {0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2665         {0x1f, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
2666
2667         /* HP, Amp  */
2668         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2669         {0x19, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
2670
2671         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2672         {0x1c, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
2673
2674         /* DAC1 */
2675         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2676
2677         /* Node 14 connections: 0x17 0x18 0x23 0x24 0x27 */
2678         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x50},
2679         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2680         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2) | 0x50},
2681         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2682         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2683
2684         /* no digital microphone support yet */
2685         {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2686
2687         /* Audio input selector */
2688         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x3},
2689
2690         /* SPDIF route: PCM */
2691         {0x20, AC_VERB_SET_CONNECT_SEL, 0x0},
2692         {0x22, AC_VERB_SET_CONNECT_SEL, 0x0},
2693
2694         {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2695         {0x22, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2696
2697         /* EAPD */
2698         {0x1d, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
2699
2700         /* not handling these yet */
2701         {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, 0},
2702         {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, 0},
2703         {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, 0},
2704         {0x1c, AC_VERB_SET_UNSOLICITED_ENABLE, 0},
2705         {0x1d, AC_VERB_SET_UNSOLICITED_ENABLE, 0},
2706         {0x1e, AC_VERB_SET_UNSOLICITED_ENABLE, 0},
2707         {0x20, AC_VERB_SET_UNSOLICITED_ENABLE, 0},
2708         {0x22, AC_VERB_SET_UNSOLICITED_ENABLE, 0},
2709         { } /* end */
2710 };
2711
2712 static const struct hda_verb cxt5066_init_verbs_olpc[] = {
2713         /* Port A: headphones */
2714         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2715         {0x19, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
2716
2717         /* Port B: external microphone */
2718         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2719
2720         /* Port C: internal microphone */
2721         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2722
2723         /* Port D: unused */
2724         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2725
2726         /* Port E: unused, but has primary EAPD */
2727         {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2728         {0x1d, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
2729
2730         /* Port F: external DC input through microphone port */
2731         {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2732
2733         /* Port G: internal speakers */
2734         {0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2735         {0x1f, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
2736
2737         /* DAC1 */
2738         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2739
2740         /* DAC2: unused */
2741         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2742
2743         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x50},
2744         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2745         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2746         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2747         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2748         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2749         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2750         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2751         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2752         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2753         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2754         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2755
2756         /* Disable digital microphone port */
2757         {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2758
2759         /* Audio input selectors */
2760         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x3},
2761         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2762
2763         /* Disable SPDIF */
2764         {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2765         {0x22, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2766
2767         /* enable unsolicited events for Port A and B */
2768         {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT},
2769         {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT},
2770         { } /* end */
2771 };
2772
2773 static const struct hda_verb cxt5066_init_verbs_vostro[] = {
2774         /* Port A: headphones */
2775         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2776         {0x19, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
2777
2778         /* Port B: external microphone */
2779         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2780
2781         /* Port C: unused */
2782         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2783
2784         /* Port D: unused */
2785         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2786
2787         /* Port E: unused, but has primary EAPD */
2788         {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2789         {0x1d, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
2790
2791         /* Port F: unused */
2792         {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2793
2794         /* Port G: internal speakers */
2795         {0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2796         {0x1f, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
2797
2798         /* DAC1 */
2799         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2800
2801         /* DAC2: unused */
2802         {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2803
2804         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2805         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2806         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2807         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2808         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2809         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2810         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2811         {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2812         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2813         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2814         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2815         {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2816
2817         /* Digital microphone port */
2818         {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2819
2820         /* Audio input selectors */
2821         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x3},
2822         {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2823
2824         /* Disable SPDIF */
2825         {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2826         {0x22, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2827
2828         /* enable unsolicited events for Port A and B */
2829         {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT},
2830         {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT},
2831         { } /* end */
2832 };
2833
2834 static const struct hda_verb cxt5066_init_verbs_ideapad[] = {
2835         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, /* Port B */
2836         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, /* Port C */
2837         {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Port F */
2838         {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Port E */
2839
2840         /* Speakers  */
2841         {0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2842         {0x1f, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
2843
2844         /* HP, Amp  */
2845         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2846         {0x19, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
2847
2848         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2849         {0x1c, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
2850
2851         /* DAC1 */
2852         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2853
2854         /* Node 14 connections: 0x17 0x18 0x23 0x24 0x27 */
2855         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x50},
2856         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2857         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2) | 0x50},
2858         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2859         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2860         {0x14, AC_VERB_SET_CONNECT_SEL, 2},     /* default to internal mic */
2861
2862         /* Audio input selector */
2863         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x2},
2864         {0x17, AC_VERB_SET_CONNECT_SEL, 1},     /* route ext mic */
2865
2866         /* SPDIF route: PCM */
2867         {0x20, AC_VERB_SET_CONNECT_SEL, 0x0},
2868         {0x22, AC_VERB_SET_CONNECT_SEL, 0x0},
2869
2870         {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2871         {0x22, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2872
2873         /* internal microphone */
2874         {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* enable internal mic */
2875
2876         /* EAPD */
2877         {0x1d, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
2878
2879         {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT},
2880         {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT},
2881         { } /* end */
2882 };
2883
2884 static const struct hda_verb cxt5066_init_verbs_thinkpad[] = {
2885         {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Port F */
2886         {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Port E */
2887
2888         /* Port G: internal speakers  */
2889         {0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2890         {0x1f, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
2891
2892         /* Port A: HP, Amp  */
2893         {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2894         {0x19, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
2895
2896         /* Port B: Mic Dock */
2897         {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2898
2899         /* Port C: Mic */
2900         {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2901
2902         /* Port D: HP Dock, Amp */
2903         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2904         {0x1c, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
2905
2906         /* DAC1 */
2907         {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2908
2909         /* Node 14 connections: 0x17 0x18 0x23 0x24 0x27 */
2910         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x50},
2911         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2912         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2) | 0x50},
2913         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2914         {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2915         {0x14, AC_VERB_SET_CONNECT_SEL, 2},     /* default to internal mic */
2916
2917         /* Audio input selector */
2918         {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x2},
2919         {0x17, AC_VERB_SET_CONNECT_SEL, 1},     /* route ext mic */
2920
2921         /* SPDIF route: PCM */
2922         {0x20, AC_VERB_SET_CONNECT_SEL, 0x0},
2923         {0x22, AC_VERB_SET_CONNECT_SEL, 0x0},
2924
2925         {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2926         {0x22, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2927
2928         /* internal microphone */
2929         {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* enable internal mic */
2930
2931         /* EAPD */
2932         {0x1d, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
2933
2934         /* enable unsolicited events for Port A, B, C and D */
2935         {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT},
2936         {0x1c, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT},
2937         {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT},
2938         {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT},
2939         { } /* end */
2940 };
2941
2942 static const struct hda_verb cxt5066_init_verbs_portd_lo[] = {
2943         {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2944         { } /* end */
2945 };
2946
2947
2948 static const struct hda_verb cxt5066_init_verbs_hp_laptop[] = {
2949         {0x14, AC_VERB_SET_CONNECT_SEL, 0x0},
2950         {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT},
2951         {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT},
2952         { } /* end */
2953 };
2954
2955 /* initialize jack-sensing, too */
2956 static int cxt5066_init(struct hda_codec *codec)
2957 {
2958         snd_printdd("CXT5066: init\n");
2959         conexant_init(codec);
2960         if (codec->patch_ops.unsol_event) {
2961                 cxt5066_hp_automute(codec);
2962                 cxt5066_automic(codec);
2963         }
2964         cxt5066_set_mic_boost(codec);
2965         return 0;
2966 }
2967
2968 static int cxt5066_olpc_init(struct hda_codec *codec)
2969 {
2970         struct conexant_spec *spec = codec->spec;
2971         snd_printdd("CXT5066: init\n");
2972         conexant_init(codec);
2973         cxt5066_hp_automute(codec);
2974         if (!spec->dc_enable) {
2975                 cxt5066_set_mic_boost(codec);
2976                 cxt5066_olpc_automic(codec);
2977         } else {
2978                 cxt5066_enable_dc(codec);
2979         }
2980         return 0;
2981 }
2982
2983 enum {
2984         CXT5066_LAPTOP,         /* Laptops w/ EAPD support */
2985         CXT5066_DELL_LAPTOP,    /* Dell Laptop */
2986         CXT5066_OLPC_XO_1_5,    /* OLPC XO 1.5 */
2987         CXT5066_DELL_VOSTRO,    /* Dell Vostro 1015i */
2988         CXT5066_IDEAPAD,        /* Lenovo IdeaPad U150 */
2989         CXT5066_THINKPAD,       /* Lenovo ThinkPad T410s, others? */
2990         CXT5066_ASUS,           /* Asus K52JU, Lenovo G560 - Int mic at 0x1a and Ext mic at 0x1b */
2991         CXT5066_HP_LAPTOP,      /* HP Laptop */
2992         CXT5066_AUTO,           /* BIOS auto-parser */
2993         CXT5066_MODELS
2994 };
2995
2996 static const char * const cxt5066_models[CXT5066_MODELS] = {
2997         [CXT5066_LAPTOP]        = "laptop",
2998         [CXT5066_DELL_LAPTOP]   = "dell-laptop",
2999         [CXT5066_OLPC_XO_1_5]   = "olpc-xo-1_5",
3000         [CXT5066_DELL_VOSTRO]   = "dell-vostro",
3001         [CXT5066_IDEAPAD]       = "ideapad",
3002         [CXT5066_THINKPAD]      = "thinkpad",
3003         [CXT5066_ASUS]          = "asus",
3004         [CXT5066_HP_LAPTOP]     = "hp-laptop",
3005         [CXT5066_AUTO]          = "auto",
3006 };
3007
3008 static const struct snd_pci_quirk cxt5066_cfg_tbl[] = {
3009         SND_PCI_QUIRK(0x1025, 0x054c, "Acer Aspire 3830TG", CXT5066_AUTO),
3010         SND_PCI_QUIRK_MASK(0x1025, 0xff00, 0x0400, "Acer", CXT5066_IDEAPAD),
3011         SND_PCI_QUIRK(0x1028, 0x02d8, "Dell Vostro", CXT5066_DELL_VOSTRO),
3012         SND_PCI_QUIRK(0x1028, 0x02f5, "Dell Vostro 320", CXT5066_IDEAPAD),
3013         SND_PCI_QUIRK(0x1028, 0x0401, "Dell Vostro 1014", CXT5066_DELL_VOSTRO),
3014         SND_PCI_QUIRK(0x1028, 0x0402, "Dell Vostro", CXT5066_DELL_VOSTRO),
3015         SND_PCI_QUIRK(0x1028, 0x0408, "Dell Inspiron One 19T", CXT5066_IDEAPAD),
3016         SND_PCI_QUIRK(0x1028, 0x050f, "Dell Inspiron", CXT5066_IDEAPAD),
3017         SND_PCI_QUIRK(0x1028, 0x0510, "Dell Vostro", CXT5066_IDEAPAD),
3018         SND_PCI_QUIRK(0x103c, 0x360b, "HP G60", CXT5066_HP_LAPTOP),
3019         SND_PCI_QUIRK(0x1043, 0x13f3, "Asus A52J", CXT5066_ASUS),
3020         SND_PCI_QUIRK(0x1043, 0x1643, "Asus K52JU", CXT5066_ASUS),
3021         SND_PCI_QUIRK(0x1043, 0x1993, "Asus U50F", CXT5066_ASUS),
3022         SND_PCI_QUIRK(0x1179, 0xff1e, "Toshiba Satellite C650D", CXT5066_IDEAPAD),
3023         SND_PCI_QUIRK(0x1179, 0xff50, "Toshiba Satellite P500-PSPGSC-01800T", CXT5066_OLPC_XO_1_5),
3024         SND_PCI_QUIRK(0x14f1, 0x0101, "Conexant Reference board",
3025                       CXT5066_LAPTOP),
3026         SND_PCI_QUIRK(0x152d, 0x0833, "OLPC XO-1.5", CXT5066_OLPC_XO_1_5),
3027         SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo T400s", CXT5066_THINKPAD),
3028         SND_PCI_QUIRK(0x17aa, 0x21c5, "Thinkpad Edge 13", CXT5066_THINKPAD),
3029         SND_PCI_QUIRK(0x17aa, 0x21c6, "Thinkpad Edge 13", CXT5066_ASUS),
3030         SND_PCI_QUIRK(0x17aa, 0x215e, "Lenovo T510", CXT5066_AUTO),
3031         SND_PCI_QUIRK(0x17aa, 0x21cf, "Lenovo T520 & W520", CXT5066_AUTO),
3032         SND_PCI_QUIRK(0x17aa, 0x21da, "Lenovo X220", CXT5066_THINKPAD),
3033         SND_PCI_QUIRK(0x17aa, 0x21db, "Lenovo X220-tablet", CXT5066_THINKPAD),
3034         SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo U350", CXT5066_ASUS),
3035         SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo G560", CXT5066_ASUS),
3036         SND_PCI_QUIRK(0x17aa, 0x3938, "Lenovo G565", CXT5066_AUTO),
3037         SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", CXT5066_IDEAPAD), /* Fallback for Lenovos without dock mic */
3038         SND_PCI_QUIRK(0x1b0a, 0x2092, "CyberpowerPC Gamer Xplorer N57001", CXT5066_AUTO),
3039         {}
3040 };
3041
3042 static int patch_cxt5066(struct hda_codec *codec)
3043 {
3044         struct conexant_spec *spec;
3045         int board_config;
3046
3047         board_config = snd_hda_check_board_config(codec, CXT5066_MODELS,
3048                                                   cxt5066_models, cxt5066_cfg_tbl);
3049         if (board_config < 0)
3050                 board_config = CXT5066_AUTO; /* model=auto as default */
3051         if (board_config == CXT5066_AUTO)
3052                 return patch_conexant_auto(codec);
3053
3054         spec = kzalloc(sizeof(*spec), GFP_KERNEL);
3055         if (!spec)
3056                 return -ENOMEM;
3057         codec->spec = spec;
3058
3059         codec->patch_ops = conexant_patch_ops;
3060         codec->patch_ops.init = conexant_init;
3061
3062         spec->dell_automute = 0;
3063         spec->multiout.max_channels = 2;
3064         spec->multiout.num_dacs = ARRAY_SIZE(cxt5066_dac_nids);
3065         spec->multiout.dac_nids = cxt5066_dac_nids;
3066         conexant_check_dig_outs(codec, cxt5066_digout_pin_nids,
3067             ARRAY_SIZE(cxt5066_digout_pin_nids));
3068         spec->num_adc_nids = 1;
3069         spec->adc_nids = cxt5066_adc_nids;
3070         spec->capsrc_nids = cxt5066_capsrc_nids;
3071         spec->input_mux = &cxt5066_capture_source;
3072
3073         spec->port_d_mode = PIN_HP;
3074
3075         spec->num_init_verbs = 1;
3076         spec->init_verbs[0] = cxt5066_init_verbs;
3077         spec->num_channel_mode = ARRAY_SIZE(cxt5066_modes);
3078         spec->channel_mode = cxt5066_modes;
3079         spec->cur_adc = 0;
3080         spec->cur_adc_idx = 0;
3081
3082         set_beep_amp(spec, 0x13, 0, HDA_OUTPUT);
3083
3084         switch (board_config) {
3085         default:
3086         case CXT5066_LAPTOP:
3087                 spec->mixers[spec->num_mixers++] = cxt5066_mixer_master;
3088                 spec->mixers[spec->num_mixers++] = cxt5066_mixers;
3089                 break;
3090         case CXT5066_DELL_LAPTOP:
3091                 spec->mixers[spec->num_mixers++] = cxt5066_mixer_master;
3092                 spec->mixers[spec->num_mixers++] = cxt5066_mixers;
3093
3094                 spec->port_d_mode = PIN_OUT;
3095                 spec->init_verbs[spec->num_init_verbs] = cxt5066_init_verbs_portd_lo;
3096                 spec->num_init_verbs++;
3097                 spec->dell_automute = 1;
3098                 break;
3099         case CXT5066_ASUS:
3100         case CXT5066_HP_LAPTOP:
3101                 codec->patch_ops.init = cxt5066_init;
3102                 codec->patch_ops.unsol_event = cxt5066_unsol_event;
3103                 spec->init_verbs[spec->num_init_verbs] =
3104                         cxt5066_init_verbs_hp_laptop;
3105                 spec->num_init_verbs++;
3106                 spec->hp_laptop = board_config == CXT5066_HP_LAPTOP;
3107                 spec->asus = board_config == CXT5066_ASUS;
3108                 spec->mixers[spec->num_mixers++] = cxt5066_mixer_master;
3109                 spec->mixers[spec->num_mixers++] = cxt5066_mixers;
3110                 /* no S/PDIF out */
3111                 if (board_config == CXT5066_HP_LAPTOP)
3112                         spec->multiout.dig_out_nid = 0;
3113                 /* input source automatically selected */
3114                 spec->input_mux = NULL;
3115                 spec->port_d_mode = 0;
3116                 spec->mic_boost = 3; /* default 30dB gain */
3117                 break;
3118
3119         case CXT5066_OLPC_XO_1_5:
3120                 codec->patch_ops.init = cxt5066_olpc_init;
3121                 codec->patch_ops.unsol_event = cxt5066_olpc_unsol_event;
3122                 spec->init_verbs[0] = cxt5066_init_verbs_olpc;
3123                 spec->mixers[spec->num_mixers++] = cxt5066_mixer_master_olpc;
3124                 spec->mixers[spec->num_mixers++] = cxt5066_mixer_olpc_dc;
3125                 spec->mixers[spec->num_mixers++] = cxt5066_mixers;
3126                 spec->port_d_mode = 0;
3127                 spec->mic_boost = 3; /* default 30dB gain */
3128
3129                 /* no S/PDIF out */
3130                 spec->multiout.dig_out_nid = 0;
3131
3132                 /* input source automatically selected */
3133                 spec->input_mux = NULL;
3134
3135                 /* our capture hooks which allow us to turn on the microphone LED
3136                  * at the right time */
3137                 spec->capture_prepare = cxt5066_olpc_capture_prepare;
3138                 spec->capture_cleanup = cxt5066_olpc_capture_cleanup;
3139                 break;
3140         case CXT5066_DELL_VOSTRO:
3141                 codec->patch_ops.init = cxt5066_init;
3142                 codec->patch_ops.unsol_event = cxt5066_unsol_event;
3143                 spec->init_verbs[0] = cxt5066_init_verbs_vostro;
3144                 spec->mixers[spec->num_mixers++] = cxt5066_mixer_master_olpc;
3145                 spec->mixers[spec->num_mixers++] = cxt5066_mixers;
3146                 spec->mixers[spec->num_mixers++] = cxt5066_vostro_mixers;
3147                 spec->port_d_mode = 0;
3148                 spec->dell_vostro = 1;
3149                 spec->mic_boost = 3; /* default 30dB gain */
3150
3151                 /* no S/PDIF out */
3152                 spec->multiout.dig_out_nid = 0;
3153
3154                 /* input source automatically selected */
3155                 spec->input_mux = NULL;
3156                 break;
3157         case CXT5066_IDEAPAD:
3158                 codec->patch_ops.init = cxt5066_init;
3159                 codec->patch_ops.unsol_event = cxt5066_unsol_event;
3160                 spec->mixers[spec->num_mixers++] = cxt5066_mixer_master;
3161                 spec->mixers[spec->num_mixers++] = cxt5066_mixers;
3162                 spec->init_verbs[0] = cxt5066_init_verbs_ideapad;
3163                 spec->port_d_mode = 0;
3164                 spec->ideapad = 1;
3165                 spec->mic_boost = 2;    /* default 20dB gain */
3166
3167                 /* no S/PDIF out */
3168                 spec->multiout.dig_out_nid = 0;
3169
3170                 /* input source automatically selected */
3171                 spec->input_mux = NULL;
3172                 break;
3173         case CXT5066_THINKPAD:
3174                 codec->patch_ops.init = cxt5066_init;
3175                 codec->patch_ops.unsol_event = cxt5066_unsol_event;
3176                 spec->mixers[spec->num_mixers++] = cxt5066_mixer_master;
3177                 spec->mixers[spec->num_mixers++] = cxt5066_mixers;
3178                 spec->init_verbs[0] = cxt5066_init_verbs_thinkpad;
3179                 spec->thinkpad = 1;
3180                 spec->port_d_mode = PIN_OUT;
3181                 spec->mic_boost = 2;    /* default 20dB gain */
3182
3183                 /* no S/PDIF out */
3184                 spec->multiout.dig_out_nid = 0;
3185
3186                 /* input source automatically selected */
3187                 spec->input_mux = NULL;
3188                 break;
3189         }
3190
3191         if (spec->beep_amp)
3192                 snd_hda_attach_beep_device(codec, spec->beep_amp);
3193
3194         return 0;
3195 }
3196
3197 /*
3198  * Automatic parser for CX20641 & co
3199  */
3200
3201 static int cx_auto_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
3202                                        struct hda_codec *codec,
3203                                        unsigned int stream_tag,
3204                                        unsigned int format,
3205                                        struct snd_pcm_substream *substream)
3206 {
3207         struct conexant_spec *spec = codec->spec;
3208         hda_nid_t adc = spec->imux_info[spec->cur_mux[0]].adc;
3209         if (spec->adc_switching) {
3210                 spec->cur_adc = adc;
3211                 spec->cur_adc_stream_tag = stream_tag;
3212                 spec->cur_adc_format = format;
3213         }
3214         snd_hda_codec_setup_stream(codec, adc, stream_tag, 0, format);
3215         return 0;
3216 }
3217
3218 static int cx_auto_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
3219                                        struct hda_codec *codec,
3220                                        struct snd_pcm_substream *substream)
3221 {
3222         struct conexant_spec *spec = codec->spec;
3223         snd_hda_codec_cleanup_stream(codec, spec->cur_adc);
3224         spec->cur_adc = 0;
3225         return 0;
3226 }
3227
3228 static const struct hda_pcm_stream cx_auto_pcm_analog_capture = {
3229         .substreams = 1,
3230         .channels_min = 2,
3231         .channels_max = 2,
3232         .nid = 0, /* fill later */
3233         .ops = {
3234                 .prepare = cx_auto_capture_pcm_prepare,
3235                 .cleanup = cx_auto_capture_pcm_cleanup
3236         },
3237 };
3238
3239 static const hda_nid_t cx_auto_adc_nids[] = { 0x14 };
3240
3241 #define get_connection_index(codec, mux, nid)\
3242         snd_hda_get_conn_index(codec, mux, nid, 0)
3243
3244 /* get an unassigned DAC from the given list.
3245  * Return the nid if found and reduce the DAC list, or return zero if
3246  * not found
3247  */
3248 static hda_nid_t get_unassigned_dac(struct hda_codec *codec, hda_nid_t pin,
3249                                     hda_nid_t *dacs, int *num_dacs)
3250 {
3251         int i, nums = *num_dacs;
3252         hda_nid_t ret = 0;
3253
3254         for (i = 0; i < nums; i++) {
3255                 if (get_connection_index(codec, pin, dacs[i]) >= 0) {
3256                         ret = dacs[i];
3257                         break;
3258                 }
3259         }
3260      &n