source: src/linux/universal/linux-3.2/sound/pci/hda/patch_conexant.c @ 18324

Last change on this file since 18324 was 18324, checked in by BrainSlayer, 16 months ago

update to 3.2.2

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