linux/sound/pci/hda/patch_analog.c
<<
>>
Prefs
   1/*
   2 * HD audio interface patch for AD1882, AD1884, AD1981HD, AD1983, AD1984,
   3 *   AD1986A, AD1988
   4 *
   5 * Copyright (c) 2005-2007 Takashi Iwai <tiwai@suse.de>
   6 *
   7 *  This driver is free software; you can redistribute it and/or modify
   8 *  it under the terms of the GNU General Public License as published by
   9 *  the Free Software Foundation; either version 2 of the License, or
  10 *  (at your option) any later version.
  11 *
  12 *  This driver is distributed in the hope that it will be useful,
  13 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  14 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15 *  GNU General Public License for more details.
  16 *
  17 *  You should have received a copy of the GNU General Public License
  18 *  along with this program; if not, write to the Free Software
  19 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  20 */
  21
  22#include <linux/init.h>
  23#include <linux/delay.h>
  24#include <linux/slab.h>
  25#include <linux/pci.h>
  26
  27#include <sound/core.h>
  28#include "hda_codec.h"
  29#include "hda_local.h"
  30#include "hda_beep.h"
  31
  32struct ad198x_spec {
  33        struct snd_kcontrol_new *mixers[6];
  34        int num_mixers;
  35        unsigned int beep_amp;  /* beep amp value, set via set_beep_amp() */
  36        const struct hda_verb *init_verbs[6];   /* initialization verbs
  37                                                 * don't forget NULL termination!
  38                                                 */
  39        unsigned int num_init_verbs;
  40
  41        /* playback */
  42        struct hda_multi_out multiout;  /* playback set-up
  43                                         * max_channels, dacs must be set
  44                                         * dig_out_nid and hp_nid are optional
  45                                         */
  46        unsigned int cur_eapd;
  47        unsigned int need_dac_fix;
  48
  49        hda_nid_t *alt_dac_nid;
  50        struct hda_pcm_stream *stream_analog_alt_playback;
  51
  52        /* capture */
  53        unsigned int num_adc_nids;
  54        hda_nid_t *adc_nids;
  55        hda_nid_t dig_in_nid;           /* digital-in NID; optional */
  56
  57        /* capture source */
  58        const struct hda_input_mux *input_mux;
  59        hda_nid_t *capsrc_nids;
  60        unsigned int cur_mux[3];
  61
  62        /* channel model */
  63        const struct hda_channel_mode *channel_mode;
  64        int num_channel_mode;
  65
  66        /* PCM information */
  67        struct hda_pcm pcm_rec[3];      /* used in alc_build_pcms() */
  68
  69        unsigned int spdif_route;
  70
  71        /* dynamic controls, init_verbs and input_mux */
  72        struct auto_pin_cfg autocfg;
  73        struct snd_array kctls;
  74        struct hda_input_mux private_imux;
  75        hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
  76
  77        unsigned int jack_present: 1;
  78        unsigned int inv_jack_detect: 1;/* inverted jack-detection */
  79        unsigned int inv_eapd: 1;       /* inverted EAPD implementation */
  80        unsigned int analog_beep: 1;    /* analog beep input present */
  81
  82#ifdef CONFIG_SND_HDA_POWER_SAVE
  83        struct hda_loopback_check loopback;
  84#endif
  85        /* for virtual master */
  86        hda_nid_t vmaster_nid;
  87        const char * const *slave_vols;
  88        const char * const *slave_sws;
  89};
  90
  91/*
  92 * input MUX handling (common part)
  93 */
  94static int ad198x_mux_enum_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
  95{
  96        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  97        struct ad198x_spec *spec = codec->spec;
  98
  99        return snd_hda_input_mux_info(spec->input_mux, uinfo);
 100}
 101
 102static int ad198x_mux_enum_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 103{
 104        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 105        struct ad198x_spec *spec = codec->spec;
 106        unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
 107
 108        ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
 109        return 0;
 110}
 111
 112static int ad198x_mux_enum_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 113{
 114        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 115        struct ad198x_spec *spec = codec->spec;
 116        unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
 117
 118        return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol,
 119                                     spec->capsrc_nids[adc_idx],
 120                                     &spec->cur_mux[adc_idx]);
 121}
 122
 123/*
 124 * initialization (common callbacks)
 125 */
 126static int ad198x_init(struct hda_codec *codec)
 127{
 128        struct ad198x_spec *spec = codec->spec;
 129        int i;
 130
 131        for (i = 0; i < spec->num_init_verbs; i++)
 132                snd_hda_sequence_write(codec, spec->init_verbs[i]);
 133        return 0;
 134}
 135
 136static const char * const ad_slave_vols[] = {
 137        "Front Playback Volume",
 138        "Surround Playback Volume",
 139        "Center Playback Volume",
 140        "LFE Playback Volume",
 141        "Side Playback Volume",
 142        "Headphone Playback Volume",
 143        "Mono Playback Volume",
 144        "Speaker Playback Volume",
 145        "IEC958 Playback Volume",
 146        NULL
 147};
 148
 149static const char * const ad_slave_sws[] = {
 150        "Front Playback Switch",
 151        "Surround Playback Switch",
 152        "Center Playback Switch",
 153        "LFE Playback Switch",
 154        "Side Playback Switch",
 155        "Headphone Playback Switch",
 156        "Mono Playback Switch",
 157        "Speaker Playback Switch",
 158        "IEC958 Playback Switch",
 159        NULL
 160};
 161
 162static const char * const ad1988_6stack_fp_slave_vols[] = {
 163        "Front Playback Volume",
 164        "Surround Playback Volume",
 165        "Center Playback Volume",
 166        "LFE Playback Volume",
 167        "Side Playback Volume",
 168        "IEC958 Playback Volume",
 169        NULL
 170};
 171
 172static const char * const ad1988_6stack_fp_slave_sws[] = {
 173        "Front Playback Switch",
 174        "Surround Playback Switch",
 175        "Center Playback Switch",
 176        "LFE Playback Switch",
 177        "Side Playback Switch",
 178        "IEC958 Playback Switch",
 179        NULL
 180};
 181static void ad198x_free_kctls(struct hda_codec *codec);
 182
 183#ifdef CONFIG_SND_HDA_INPUT_BEEP
 184/* additional beep mixers; the actual parameters are overwritten at build */
 185static struct snd_kcontrol_new ad_beep_mixer[] = {
 186        HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_OUTPUT),
 187        HDA_CODEC_MUTE_BEEP("Beep Playback Switch", 0, 0, HDA_OUTPUT),
 188        { } /* end */
 189};
 190
 191static struct snd_kcontrol_new ad_beep2_mixer[] = {
 192        HDA_CODEC_VOLUME("Digital Beep Playback Volume", 0, 0, HDA_OUTPUT),
 193        HDA_CODEC_MUTE_BEEP("Digital Beep Playback Switch", 0, 0, HDA_OUTPUT),
 194        { } /* end */
 195};
 196
 197#define set_beep_amp(spec, nid, idx, dir) \
 198        ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 1, idx, dir)) /* mono */
 199#else
 200#define set_beep_amp(spec, nid, idx, dir) /* NOP */
 201#endif
 202
 203static int ad198x_build_controls(struct hda_codec *codec)
 204{
 205        struct ad198x_spec *spec = codec->spec;
 206        struct snd_kcontrol *kctl;
 207        unsigned int i;
 208        int err;
 209
 210        for (i = 0; i < spec->num_mixers; i++) {
 211                err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
 212                if (err < 0)
 213                        return err;
 214        }
 215        if (spec->multiout.dig_out_nid) {
 216                err = snd_hda_create_spdif_out_ctls(codec, spec->multiout.dig_out_nid);
 217                if (err < 0)
 218                        return err;
 219                err = snd_hda_create_spdif_share_sw(codec,
 220                                                    &spec->multiout);
 221                if (err < 0)
 222                        return err;
 223                spec->multiout.share_spdif = 1;
 224        } 
 225        if (spec->dig_in_nid) {
 226                err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
 227                if (err < 0)
 228                        return err;
 229        }
 230
 231        /* create beep controls if needed */
 232#ifdef CONFIG_SND_HDA_INPUT_BEEP
 233        if (spec->beep_amp) {
 234                struct snd_kcontrol_new *knew;
 235                knew = spec->analog_beep ? ad_beep2_mixer : ad_beep_mixer;
 236                for ( ; knew->name; knew++) {
 237                        struct snd_kcontrol *kctl;
 238                        kctl = snd_ctl_new1(knew, codec);
 239                        if (!kctl)
 240                                return -ENOMEM;
 241                        kctl->private_value = spec->beep_amp;
 242                        err = snd_hda_ctl_add(codec, 0, kctl);
 243                        if (err < 0)
 244                                return err;
 245                }
 246        }
 247#endif
 248
 249        /* if we have no master control, let's create it */
 250        if (!snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
 251                unsigned int vmaster_tlv[4];
 252                snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
 253                                        HDA_OUTPUT, vmaster_tlv);
 254                err = snd_hda_add_vmaster(codec, "Master Playback Volume",
 255                                          vmaster_tlv,
 256                                          (spec->slave_vols ?
 257                                           spec->slave_vols : ad_slave_vols));
 258                if (err < 0)
 259                        return err;
 260        }
 261        if (!snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
 262                err = snd_hda_add_vmaster(codec, "Master Playback Switch",
 263                                          NULL,
 264                                          (spec->slave_sws ?
 265                                           spec->slave_sws : ad_slave_sws));
 266                if (err < 0)
 267                        return err;
 268        }
 269
 270        ad198x_free_kctls(codec); /* no longer needed */
 271
 272        /* assign Capture Source enums to NID */
 273        kctl = snd_hda_find_mixer_ctl(codec, "Capture Source");
 274        if (!kctl)
 275                kctl = snd_hda_find_mixer_ctl(codec, "Input Source");
 276        for (i = 0; kctl && i < kctl->count; i++) {
 277                err = snd_hda_add_nid(codec, kctl, i, spec->capsrc_nids[i]);
 278                if (err < 0)
 279                        return err;
 280        }
 281
 282        /* assign IEC958 enums to NID */
 283        kctl = snd_hda_find_mixer_ctl(codec,
 284                        SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source");
 285        if (kctl) {
 286                err = snd_hda_add_nid(codec, kctl, 0,
 287                                      spec->multiout.dig_out_nid);
 288                if (err < 0)
 289                        return err;
 290        }
 291
 292        return 0;
 293}
 294
 295#ifdef CONFIG_SND_HDA_POWER_SAVE
 296static int ad198x_check_power_status(struct hda_codec *codec, hda_nid_t nid)
 297{
 298        struct ad198x_spec *spec = codec->spec;
 299        return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
 300}
 301#endif
 302
 303/*
 304 * Analog playback callbacks
 305 */
 306static int ad198x_playback_pcm_open(struct hda_pcm_stream *hinfo,
 307                                    struct hda_codec *codec,
 308                                    struct snd_pcm_substream *substream)
 309{
 310        struct ad198x_spec *spec = codec->spec;
 311        return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
 312                                             hinfo);
 313}
 314
 315static int ad198x_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
 316                                       struct hda_codec *codec,
 317                                       unsigned int stream_tag,
 318                                       unsigned int format,
 319                                       struct snd_pcm_substream *substream)
 320{
 321        struct ad198x_spec *spec = codec->spec;
 322        return snd_hda_multi_out_analog_prepare(codec, &spec->multiout, stream_tag,
 323                                                format, substream);
 324}
 325
 326static int ad198x_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
 327                                       struct hda_codec *codec,
 328                                       struct snd_pcm_substream *substream)
 329{
 330        struct ad198x_spec *spec = codec->spec;
 331        return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
 332}
 333
 334static struct hda_pcm_stream ad198x_pcm_analog_alt_playback = {
 335        .substreams = 1,
 336        .channels_min = 2,
 337        .channels_max = 2,
 338        /* NID is set in ad198x_build_pcms */
 339};
 340
 341/*
 342 * Digital out
 343 */
 344static int ad198x_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
 345                                        struct hda_codec *codec,
 346                                        struct snd_pcm_substream *substream)
 347{
 348        struct ad198x_spec *spec = codec->spec;
 349        return snd_hda_multi_out_dig_open(codec, &spec->multiout);
 350}
 351
 352static int ad198x_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
 353                                         struct hda_codec *codec,
 354                                         struct snd_pcm_substream *substream)
 355{
 356        struct ad198x_spec *spec = codec->spec;
 357        return snd_hda_multi_out_dig_close(codec, &spec->multiout);
 358}
 359
 360static int ad198x_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
 361                                           struct hda_codec *codec,
 362                                           unsigned int stream_tag,
 363                                           unsigned int format,
 364                                           struct snd_pcm_substream *substream)
 365{
 366        struct ad198x_spec *spec = codec->spec;
 367        return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, stream_tag,
 368                                             format, substream);
 369}
 370
 371static int ad198x_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
 372                                           struct hda_codec *codec,
 373                                           struct snd_pcm_substream *substream)
 374{
 375        struct ad198x_spec *spec = codec->spec;
 376        return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout);
 377}
 378
 379/*
 380 * Analog capture
 381 */
 382static int ad198x_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
 383                                      struct hda_codec *codec,
 384                                      unsigned int stream_tag,
 385                                      unsigned int format,
 386                                      struct snd_pcm_substream *substream)
 387{
 388        struct ad198x_spec *spec = codec->spec;
 389        snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
 390                                   stream_tag, 0, format);
 391        return 0;
 392}
 393
 394static int ad198x_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
 395                                      struct hda_codec *codec,
 396                                      struct snd_pcm_substream *substream)
 397{
 398        struct ad198x_spec *spec = codec->spec;
 399        snd_hda_codec_cleanup_stream(codec, spec->adc_nids[substream->number]);
 400        return 0;
 401}
 402
 403
 404/*
 405 */
 406static struct hda_pcm_stream ad198x_pcm_analog_playback = {
 407        .substreams = 1,
 408        .channels_min = 2,
 409        .channels_max = 6, /* changed later */
 410        .nid = 0, /* fill later */
 411        .ops = {
 412                .open = ad198x_playback_pcm_open,
 413                .prepare = ad198x_playback_pcm_prepare,
 414                .cleanup = ad198x_playback_pcm_cleanup
 415        },
 416};
 417
 418static struct hda_pcm_stream ad198x_pcm_analog_capture = {
 419        .substreams = 1,
 420        .channels_min = 2,
 421        .channels_max = 2,
 422        .nid = 0, /* fill later */
 423        .ops = {
 424                .prepare = ad198x_capture_pcm_prepare,
 425                .cleanup = ad198x_capture_pcm_cleanup
 426        },
 427};
 428
 429static struct hda_pcm_stream ad198x_pcm_digital_playback = {
 430        .substreams = 1,
 431        .channels_min = 2,
 432        .channels_max = 2,
 433        .nid = 0, /* fill later */
 434        .ops = {
 435                .open = ad198x_dig_playback_pcm_open,
 436                .close = ad198x_dig_playback_pcm_close,
 437                .prepare = ad198x_dig_playback_pcm_prepare,
 438                .cleanup = ad198x_dig_playback_pcm_cleanup
 439        },
 440};
 441
 442static struct hda_pcm_stream ad198x_pcm_digital_capture = {
 443        .substreams = 1,
 444        .channels_min = 2,
 445        .channels_max = 2,
 446        /* NID is set in alc_build_pcms */
 447};
 448
 449static int ad198x_build_pcms(struct hda_codec *codec)
 450{
 451        struct ad198x_spec *spec = codec->spec;
 452        struct hda_pcm *info = spec->pcm_rec;
 453
 454        codec->num_pcms = 1;
 455        codec->pcm_info = info;
 456
 457        info->name = "AD198x Analog";
 458        info->stream[SNDRV_PCM_STREAM_PLAYBACK] = ad198x_pcm_analog_playback;
 459        info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->multiout.max_channels;
 460        info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
 461        info->stream[SNDRV_PCM_STREAM_CAPTURE] = ad198x_pcm_analog_capture;
 462        info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = spec->num_adc_nids;
 463        info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
 464
 465        if (spec->multiout.dig_out_nid) {
 466                info++;
 467                codec->num_pcms++;
 468                info->name = "AD198x Digital";
 469                info->pcm_type = HDA_PCM_TYPE_SPDIF;
 470                info->stream[SNDRV_PCM_STREAM_PLAYBACK] = ad198x_pcm_digital_playback;
 471                info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
 472                if (spec->dig_in_nid) {
 473                        info->stream[SNDRV_PCM_STREAM_CAPTURE] = ad198x_pcm_digital_capture;
 474                        info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
 475                }
 476        }
 477
 478        if (spec->alt_dac_nid && spec->stream_analog_alt_playback) {
 479                codec->num_pcms++;
 480                info = spec->pcm_rec + 2;
 481                info->name = "AD198x Headphone";
 482                info->pcm_type = HDA_PCM_TYPE_AUDIO;
 483                info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
 484                        *spec->stream_analog_alt_playback;
 485                info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
 486                        spec->alt_dac_nid[0];
 487        }
 488
 489        return 0;
 490}
 491
 492static inline void ad198x_shutup(struct hda_codec *codec)
 493{
 494        snd_hda_shutup_pins(codec);
 495}
 496
 497static void ad198x_free_kctls(struct hda_codec *codec)
 498{
 499        struct ad198x_spec *spec = codec->spec;
 500
 501        if (spec->kctls.list) {
 502                struct snd_kcontrol_new *kctl = spec->kctls.list;
 503                int i;
 504                for (i = 0; i < spec->kctls.used; i++)
 505                        kfree(kctl[i].name);
 506        }
 507        snd_array_free(&spec->kctls);
 508}
 509
 510static void ad198x_power_eapd_write(struct hda_codec *codec, hda_nid_t front,
 511                                hda_nid_t hp)
 512{
 513        struct ad198x_spec *spec = codec->spec;
 514        snd_hda_codec_write(codec, front, 0, AC_VERB_SET_EAPD_BTLENABLE,
 515                            !spec->inv_eapd ? 0x00 : 0x02);
 516        snd_hda_codec_write(codec, hp, 0, AC_VERB_SET_EAPD_BTLENABLE,
 517                            !spec->inv_eapd ? 0x00 : 0x02);
 518}
 519
 520static void ad198x_power_eapd(struct hda_codec *codec)
 521{
 522        /* We currently only handle front, HP */
 523        switch (codec->vendor_id) {
 524        case 0x11d41882:
 525        case 0x11d4882a:
 526        case 0x11d41884:
 527        case 0x11d41984:
 528        case 0x11d41883:
 529        case 0x11d4184a:
 530        case 0x11d4194a:
 531        case 0x11d4194b:
 532                ad198x_power_eapd_write(codec, 0x12, 0x11);
 533                break;
 534        case 0x11d41981:
 535        case 0x11d41983:
 536                ad198x_power_eapd_write(codec, 0x05, 0x06);
 537                break;
 538        case 0x11d41986:
 539                ad198x_power_eapd_write(codec, 0x1b, 0x1a);
 540                break;
 541        case 0x11d41988:
 542        case 0x11d4198b:
 543        case 0x11d4989a:
 544        case 0x11d4989b:
 545                ad198x_power_eapd_write(codec, 0x29, 0x22);
 546                break;
 547        }
 548}
 549
 550static void ad198x_free(struct hda_codec *codec)
 551{
 552        struct ad198x_spec *spec = codec->spec;
 553
 554        if (!spec)
 555                return;
 556
 557        ad198x_shutup(codec);
 558        ad198x_free_kctls(codec);
 559        kfree(spec);
 560        snd_hda_detach_beep_device(codec);
 561}
 562
 563#ifdef SND_HDA_NEEDS_RESUME
 564static int ad198x_suspend(struct hda_codec *codec, pm_message_t state)
 565{
 566        ad198x_shutup(codec);
 567        ad198x_power_eapd(codec);
 568        return 0;
 569}
 570#endif
 571
 572static struct hda_codec_ops ad198x_patch_ops = {
 573        .build_controls = ad198x_build_controls,
 574        .build_pcms = ad198x_build_pcms,
 575        .init = ad198x_init,
 576        .free = ad198x_free,
 577#ifdef CONFIG_SND_HDA_POWER_SAVE
 578        .check_power_status = ad198x_check_power_status,
 579#endif
 580#ifdef SND_HDA_NEEDS_RESUME
 581        .suspend = ad198x_suspend,
 582#endif
 583        .reboot_notify = ad198x_shutup,
 584};
 585
 586
 587/*
 588 * EAPD control
 589 * the private value = nid
 590 */
 591#define ad198x_eapd_info        snd_ctl_boolean_mono_info
 592
 593static int ad198x_eapd_get(struct snd_kcontrol *kcontrol,
 594                           struct snd_ctl_elem_value *ucontrol)
 595{
 596        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 597        struct ad198x_spec *spec = codec->spec;
 598        if (spec->inv_eapd)
 599                ucontrol->value.integer.value[0] = ! spec->cur_eapd;
 600        else
 601                ucontrol->value.integer.value[0] = spec->cur_eapd;
 602        return 0;
 603}
 604
 605static int ad198x_eapd_put(struct snd_kcontrol *kcontrol,
 606                           struct snd_ctl_elem_value *ucontrol)
 607{
 608        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 609        struct ad198x_spec *spec = codec->spec;
 610        hda_nid_t nid = kcontrol->private_value & 0xff;
 611        unsigned int eapd;
 612        eapd = !!ucontrol->value.integer.value[0];
 613        if (spec->inv_eapd)
 614                eapd = !eapd;
 615        if (eapd == spec->cur_eapd)
 616                return 0;
 617        spec->cur_eapd = eapd;
 618        snd_hda_codec_write_cache(codec, nid,
 619                                  0, AC_VERB_SET_EAPD_BTLENABLE,
 620                                  eapd ? 0x02 : 0x00);
 621        return 1;
 622}
 623
 624static int ad198x_ch_mode_info(struct snd_kcontrol *kcontrol,
 625                               struct snd_ctl_elem_info *uinfo);
 626static int ad198x_ch_mode_get(struct snd_kcontrol *kcontrol,
 627                              struct snd_ctl_elem_value *ucontrol);
 628static int ad198x_ch_mode_put(struct snd_kcontrol *kcontrol,
 629                              struct snd_ctl_elem_value *ucontrol);
 630
 631
 632/*
 633 * AD1986A specific
 634 */
 635
 636#define AD1986A_SPDIF_OUT       0x02
 637#define AD1986A_FRONT_DAC       0x03
 638#define AD1986A_SURR_DAC        0x04
 639#define AD1986A_CLFE_DAC        0x05
 640#define AD1986A_ADC             0x06
 641
 642static hda_nid_t ad1986a_dac_nids[3] = {
 643        AD1986A_FRONT_DAC, AD1986A_SURR_DAC, AD1986A_CLFE_DAC
 644};
 645static hda_nid_t ad1986a_adc_nids[1] = { AD1986A_ADC };
 646static hda_nid_t ad1986a_capsrc_nids[1] = { 0x12 };
 647
 648static struct hda_input_mux ad1986a_capture_source = {
 649        .num_items = 7,
 650        .items = {
 651                { "Mic", 0x0 },
 652                { "CD", 0x1 },
 653                { "Aux", 0x3 },
 654                { "Line", 0x4 },
 655                { "Mix", 0x5 },
 656                { "Mono", 0x6 },
 657                { "Phone", 0x7 },
 658        },
 659};
 660
 661
 662static struct hda_bind_ctls ad1986a_bind_pcm_vol = {
 663        .ops = &snd_hda_bind_vol,
 664        .values = {
 665                HDA_COMPOSE_AMP_VAL(AD1986A_FRONT_DAC, 3, 0, HDA_OUTPUT),
 666                HDA_COMPOSE_AMP_VAL(AD1986A_SURR_DAC, 3, 0, HDA_OUTPUT),
 667                HDA_COMPOSE_AMP_VAL(AD1986A_CLFE_DAC, 3, 0, HDA_OUTPUT),
 668                0
 669        },
 670};
 671
 672static struct hda_bind_ctls ad1986a_bind_pcm_sw = {
 673        .ops = &snd_hda_bind_sw,
 674        .values = {
 675                HDA_COMPOSE_AMP_VAL(AD1986A_FRONT_DAC, 3, 0, HDA_OUTPUT),
 676                HDA_COMPOSE_AMP_VAL(AD1986A_SURR_DAC, 3, 0, HDA_OUTPUT),
 677                HDA_COMPOSE_AMP_VAL(AD1986A_CLFE_DAC, 3, 0, HDA_OUTPUT),
 678                0
 679        },
 680};
 681
 682/*
 683 * mixers
 684 */
 685static struct snd_kcontrol_new ad1986a_mixers[] = {
 686        /*
 687         * bind volumes/mutes of 3 DACs as a single PCM control for simplicity
 688         */
 689        HDA_BIND_VOL("PCM Playback Volume", &ad1986a_bind_pcm_vol),
 690        HDA_BIND_SW("PCM Playback Switch", &ad1986a_bind_pcm_sw),
 691        HDA_CODEC_VOLUME("Front Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
 692        HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
 693        HDA_CODEC_VOLUME("Surround Playback Volume", 0x1c, 0x0, HDA_OUTPUT),
 694        HDA_CODEC_MUTE("Surround Playback Switch", 0x1c, 0x0, HDA_OUTPUT),
 695        HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x1d, 1, 0x0, HDA_OUTPUT),
 696        HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x1d, 2, 0x0, HDA_OUTPUT),
 697        HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x1d, 1, 0x0, HDA_OUTPUT),
 698        HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x1d, 2, 0x0, HDA_OUTPUT),
 699        HDA_CODEC_VOLUME("Headphone Playback Volume", 0x1a, 0x0, HDA_OUTPUT),
 700        HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x0, HDA_OUTPUT),
 701        HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_OUTPUT),
 702        HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_OUTPUT),
 703        HDA_CODEC_VOLUME("Line Playback Volume", 0x17, 0x0, HDA_OUTPUT),
 704        HDA_CODEC_MUTE("Line Playback Switch", 0x17, 0x0, HDA_OUTPUT),
 705        HDA_CODEC_VOLUME("Aux Playback Volume", 0x16, 0x0, HDA_OUTPUT),
 706        HDA_CODEC_MUTE("Aux Playback Switch", 0x16, 0x0, HDA_OUTPUT),
 707        HDA_CODEC_VOLUME("Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT),
 708        HDA_CODEC_MUTE("Mic Playback Switch", 0x13, 0x0, HDA_OUTPUT),
 709        HDA_CODEC_VOLUME("Mic Boost Volume", 0x0f, 0x0, HDA_OUTPUT),
 710        HDA_CODEC_VOLUME("Mono Playback Volume", 0x1e, 0x0, HDA_OUTPUT),
 711        HDA_CODEC_MUTE("Mono Playback Switch", 0x1e, 0x0, HDA_OUTPUT),
 712        HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x0, HDA_OUTPUT),
 713        HDA_CODEC_MUTE("Capture Switch", 0x12, 0x0, HDA_OUTPUT),
 714        {
 715                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 716                .name = "Capture Source",
 717                .info = ad198x_mux_enum_info,
 718                .get = ad198x_mux_enum_get,
 719                .put = ad198x_mux_enum_put,
 720        },
 721        HDA_CODEC_MUTE("Stereo Downmix Switch", 0x09, 0x0, HDA_OUTPUT),
 722        { } /* end */
 723};
 724
 725/* additional mixers for 3stack mode */
 726static struct snd_kcontrol_new ad1986a_3st_mixers[] = {
 727        {
 728                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 729                .name = "Channel Mode",
 730                .info = ad198x_ch_mode_info,
 731                .get = ad198x_ch_mode_get,
 732                .put = ad198x_ch_mode_put,
 733        },
 734        { } /* end */
 735};
 736
 737/* laptop model - 2ch only */
 738static hda_nid_t ad1986a_laptop_dac_nids[1] = { AD1986A_FRONT_DAC };
 739
 740/* master controls both pins 0x1a and 0x1b */
 741static struct hda_bind_ctls ad1986a_laptop_master_vol = {
 742        .ops = &snd_hda_bind_vol,
 743        .values = {
 744                HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, HDA_OUTPUT),
 745                HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
 746                0,
 747        },
 748};
 749
 750static struct hda_bind_ctls ad1986a_laptop_master_sw = {
 751        .ops = &snd_hda_bind_sw,
 752        .values = {
 753                HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, HDA_OUTPUT),
 754                HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
 755                0,
 756        },
 757};
 758
 759static struct snd_kcontrol_new ad1986a_laptop_mixers[] = {
 760        HDA_CODEC_VOLUME("PCM Playback Volume", 0x03, 0x0, HDA_OUTPUT),
 761        HDA_CODEC_MUTE("PCM Playback Switch", 0x03, 0x0, HDA_OUTPUT),
 762        HDA_BIND_VOL("Master Playback Volume", &ad1986a_laptop_master_vol),
 763        HDA_BIND_SW("Master Playback Switch", &ad1986a_laptop_master_sw),
 764        HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_OUTPUT),
 765        HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_OUTPUT),
 766        HDA_CODEC_VOLUME("Line Playback Volume", 0x17, 0x0, HDA_OUTPUT),
 767        HDA_CODEC_MUTE("Line Playback Switch", 0x17, 0x0, HDA_OUTPUT),
 768        HDA_CODEC_VOLUME("Aux Playback Volume", 0x16, 0x0, HDA_OUTPUT),
 769        HDA_CODEC_MUTE("Aux Playback Switch", 0x16, 0x0, HDA_OUTPUT),
 770        HDA_CODEC_VOLUME("Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT),
 771        HDA_CODEC_MUTE("Mic Playback Switch", 0x13, 0x0, HDA_OUTPUT),
 772        HDA_CODEC_VOLUME("Mic Boost Volume", 0x0f, 0x0, HDA_OUTPUT),
 773        /* 
 774           HDA_CODEC_VOLUME("Mono Playback Volume", 0x1e, 0x0, HDA_OUTPUT),
 775           HDA_CODEC_MUTE("Mono Playback Switch", 0x1e, 0x0, HDA_OUTPUT), */
 776        HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x0, HDA_OUTPUT),
 777        HDA_CODEC_MUTE("Capture Switch", 0x12, 0x0, HDA_OUTPUT),
 778        {
 779                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 780                .name = "Capture Source",
 781                .info = ad198x_mux_enum_info,
 782                .get = ad198x_mux_enum_get,
 783                .put = ad198x_mux_enum_put,
 784        },
 785        { } /* end */
 786};
 787
 788/* laptop-eapd model - 2ch only */
 789
 790static struct hda_input_mux ad1986a_laptop_eapd_capture_source = {
 791        .num_items = 3,
 792        .items = {
 793                { "Mic", 0x0 },
 794                { "Internal Mic", 0x4 },
 795                { "Mix", 0x5 },
 796        },
 797};
 798
 799static struct hda_input_mux ad1986a_automic_capture_source = {
 800        .num_items = 2,
 801        .items = {
 802                { "Mic", 0x0 },
 803                { "Mix", 0x5 },
 804        },
 805};
 806
 807static struct snd_kcontrol_new ad1986a_laptop_master_mixers[] = {
 808        HDA_BIND_VOL("Master Playback Volume", &ad1986a_laptop_master_vol),
 809        HDA_BIND_SW("Master Playback Switch", &ad1986a_laptop_master_sw),
 810        { } /* end */
 811};
 812
 813static struct snd_kcontrol_new ad1986a_laptop_eapd_mixers[] = {
 814        HDA_CODEC_VOLUME("PCM Playback Volume", 0x03, 0x0, HDA_OUTPUT),
 815        HDA_CODEC_MUTE("PCM Playback Switch", 0x03, 0x0, HDA_OUTPUT),
 816        HDA_CODEC_VOLUME("Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT),
 817        HDA_CODEC_MUTE("Mic Playback Switch", 0x13, 0x0, HDA_OUTPUT),
 818        HDA_CODEC_VOLUME("Mic Boost Volume", 0x0f, 0x0, HDA_OUTPUT),
 819        HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x0, HDA_OUTPUT),
 820        HDA_CODEC_MUTE("Capture Switch", 0x12, 0x0, HDA_OUTPUT),
 821        {
 822                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 823                .name = "Capture Source",
 824                .info = ad198x_mux_enum_info,
 825                .get = ad198x_mux_enum_get,
 826                .put = ad198x_mux_enum_put,
 827        },
 828        {
 829                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 830                .name = "External Amplifier",
 831                .subdevice = HDA_SUBDEV_NID_FLAG | 0x1b,
 832                .info = ad198x_eapd_info,
 833                .get = ad198x_eapd_get,
 834                .put = ad198x_eapd_put,
 835                .private_value = 0x1b, /* port-D */
 836        },
 837        { } /* end */
 838};
 839
 840static struct snd_kcontrol_new ad1986a_laptop_intmic_mixers[] = {
 841        HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x17, 0, HDA_OUTPUT),
 842        HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x17, 0, HDA_OUTPUT),
 843        { } /* end */
 844};
 845
 846/* re-connect the mic boost input according to the jack sensing */
 847static void ad1986a_automic(struct hda_codec *codec)
 848{
 849        unsigned int present;
 850        present = snd_hda_jack_detect(codec, 0x1f);
 851        /* 0 = 0x1f, 2 = 0x1d, 4 = mixed */
 852        snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_CONNECT_SEL,
 853                            present ? 0 : 2);
 854}
 855
 856#define AD1986A_MIC_EVENT               0x36
 857
 858static void ad1986a_automic_unsol_event(struct hda_codec *codec,
 859                                            unsigned int res)
 860{
 861        if ((res >> 26) != AD1986A_MIC_EVENT)
 862                return;
 863        ad1986a_automic(codec);
 864}
 865
 866static int ad1986a_automic_init(struct hda_codec *codec)
 867{
 868        ad198x_init(codec);
 869        ad1986a_automic(codec);
 870        return 0;
 871}
 872
 873/* laptop-automute - 2ch only */
 874
 875static void ad1986a_update_hp(struct hda_codec *codec)
 876{
 877        struct ad198x_spec *spec = codec->spec;
 878        unsigned int mute;
 879
 880        if (spec->jack_present)
 881                mute = HDA_AMP_MUTE; /* mute internal speaker */
 882        else
 883                /* unmute internal speaker if necessary */
 884                mute = snd_hda_codec_amp_read(codec, 0x1a, 0, HDA_OUTPUT, 0);
 885        snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
 886                                 HDA_AMP_MUTE, mute);
 887}
 888
 889static void ad1986a_hp_automute(struct hda_codec *codec)
 890{
 891        struct ad198x_spec *spec = codec->spec;
 892
 893        spec->jack_present = snd_hda_jack_detect(codec, 0x1a);
 894        if (spec->inv_jack_detect)
 895                spec->jack_present = !spec->jack_present;
 896        ad1986a_update_hp(codec);
 897}
 898
 899#define AD1986A_HP_EVENT                0x37
 900
 901static void ad1986a_hp_unsol_event(struct hda_codec *codec, unsigned int res)
 902{
 903        if ((res >> 26) != AD1986A_HP_EVENT)
 904                return;
 905        ad1986a_hp_automute(codec);
 906}
 907
 908static int ad1986a_hp_init(struct hda_codec *codec)
 909{
 910        ad198x_init(codec);
 911        ad1986a_hp_automute(codec);
 912        return 0;
 913}
 914
 915/* bind hp and internal speaker mute (with plug check) */
 916static int ad1986a_hp_master_sw_put(struct snd_kcontrol *kcontrol,
 917                                    struct snd_ctl_elem_value *ucontrol)
 918{
 919        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 920        long *valp = ucontrol->value.integer.value;
 921        int change;
 922
 923        change = snd_hda_codec_amp_update(codec, 0x1a, 0, HDA_OUTPUT, 0,
 924                                          HDA_AMP_MUTE,
 925                                          valp[0] ? 0 : HDA_AMP_MUTE);
 926        change |= snd_hda_codec_amp_update(codec, 0x1a, 1, HDA_OUTPUT, 0,
 927                                           HDA_AMP_MUTE,
 928                                           valp[1] ? 0 : HDA_AMP_MUTE);
 929        if (change)
 930                ad1986a_update_hp(codec);
 931        return change;
 932}
 933
 934static struct snd_kcontrol_new ad1986a_automute_master_mixers[] = {
 935        HDA_BIND_VOL("Master Playback Volume", &ad1986a_laptop_master_vol),
 936        {
 937                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 938                .name = "Master Playback Switch",
 939                .subdevice = HDA_SUBDEV_AMP_FLAG,
 940                .info = snd_hda_mixer_amp_switch_info,
 941                .get = snd_hda_mixer_amp_switch_get,
 942                .put = ad1986a_hp_master_sw_put,
 943                .private_value = HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, HDA_OUTPUT),
 944        },
 945        { } /* end */
 946};
 947
 948
 949/*
 950 * initialization verbs
 951 */
 952static struct hda_verb ad1986a_init_verbs[] = {
 953        /* Front, Surround, CLFE DAC; mute as default */
 954        {0x03, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
 955        {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
 956        {0x05, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
 957        /* Downmix - off */
 958        {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
 959        /* HP, Line-Out, Surround, CLFE selectors */
 960        {0x0a, AC_VERB_SET_CONNECT_SEL, 0x0},
 961        {0x0b, AC_VERB_SET_CONNECT_SEL, 0x0},
 962        {0x0c, AC_VERB_SET_CONNECT_SEL, 0x0},
 963        {0x0d, AC_VERB_SET_CONNECT_SEL, 0x0},
 964        /* Mono selector */
 965        {0x0e, AC_VERB_SET_CONNECT_SEL, 0x0},
 966        /* Mic selector: Mic 1/2 pin */
 967        {0x0f, AC_VERB_SET_CONNECT_SEL, 0x0},
 968        /* Line-in selector: Line-in */
 969        {0x10, AC_VERB_SET_CONNECT_SEL, 0x0},
 970        /* Mic 1/2 swap */
 971        {0x11, AC_VERB_SET_CONNECT_SEL, 0x0},
 972        /* Record selector: mic */
 973        {0x12, AC_VERB_SET_CONNECT_SEL, 0x0},
 974        /* Mic, Phone, CD, Aux, Line-In amp; mute as default */
 975        {0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
 976        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
 977        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
 978        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
 979        {0x17, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
 980        /* PC beep */
 981        {0x18, AC_VERB_SET_CONNECT_SEL, 0x0},
 982        /* HP, Line-Out, Surround, CLFE, Mono pins; mute as default */
 983        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
 984        {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
 985        {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
 986        {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
 987        {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
 988        /* HP Pin */
 989        {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
 990        /* Front, Surround, CLFE Pins */
 991        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
 992        {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
 993        {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
 994        /* Mono Pin */
 995        {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
 996        /* Mic Pin */
 997        {0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
 998        /* Line, Aux, CD, Beep-In Pin */
 999        {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
1000        {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
1001        {0x22, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
1002        {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
1003        {0x24, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
1004        { } /* end */
1005};
1006
1007static struct hda_verb ad1986a_ch2_init[] = {
1008        /* Surround out -> Line In */
1009        { 0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1010        /* Line-in selectors */
1011        { 0x10, AC_VERB_SET_CONNECT_SEL, 0x1 },
1012        /* CLFE -> Mic in */
1013        { 0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1014        /* Mic selector, mix C/LFE (backmic) and Mic (frontmic) */
1015        { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x4 },
1016        { } /* end */
1017};
1018
1019static struct hda_verb ad1986a_ch4_init[] = {
1020        /* Surround out -> Surround */
1021        { 0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1022        { 0x10, AC_VERB_SET_CONNECT_SEL, 0x0 },
1023        /* CLFE -> Mic in */
1024        { 0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1025        { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x4 },
1026        { } /* end */
1027};
1028
1029static struct hda_verb ad1986a_ch6_init[] = {
1030        /* Surround out -> Surround out */
1031        { 0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1032        { 0x10, AC_VERB_SET_CONNECT_SEL, 0x0 },
1033        /* CLFE -> CLFE */
1034        { 0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1035        { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x0 },
1036        { } /* end */
1037};
1038
1039static struct hda_channel_mode ad1986a_modes[3] = {
1040        { 2, ad1986a_ch2_init },
1041        { 4, ad1986a_ch4_init },
1042        { 6, ad1986a_ch6_init },
1043};
1044
1045/* eapd initialization */
1046static struct hda_verb ad1986a_eapd_init_verbs[] = {
1047        {0x1b, AC_VERB_SET_EAPD_BTLENABLE, 0x00 },
1048        {}
1049};
1050
1051static struct hda_verb ad1986a_automic_verbs[] = {
1052        {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1053        {0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1054        /*{0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},*/
1055        {0x0f, AC_VERB_SET_CONNECT_SEL, 0x0},
1056        {0x1f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1986A_MIC_EVENT},
1057        {}
1058};
1059
1060/* Ultra initialization */
1061static struct hda_verb ad1986a_ultra_init[] = {
1062        /* eapd initialization */
1063        { 0x1b, AC_VERB_SET_EAPD_BTLENABLE, 0x00 },
1064        /* CLFE -> Mic in */
1065        { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x2 },
1066        { 0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
1067        { 0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
1068        { } /* end */
1069};
1070
1071/* pin sensing on HP jack */
1072static struct hda_verb ad1986a_hp_init_verbs[] = {
1073        {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1986A_HP_EVENT},
1074        {}
1075};
1076
1077static void ad1986a_samsung_p50_unsol_event(struct hda_codec *codec,
1078                                            unsigned int res)
1079{
1080        switch (res >> 26) {
1081        case AD1986A_HP_EVENT:
1082                ad1986a_hp_automute(codec);
1083                break;
1084        case AD1986A_MIC_EVENT:
1085                ad1986a_automic(codec);
1086                break;
1087        }
1088}
1089
1090static int ad1986a_samsung_p50_init(struct hda_codec *codec)
1091{
1092        ad198x_init(codec);
1093        ad1986a_hp_automute(codec);
1094        ad1986a_automic(codec);
1095        return 0;
1096}
1097
1098
1099/* models */
1100enum {
1101        AD1986A_6STACK,
1102        AD1986A_3STACK,
1103        AD1986A_LAPTOP,
1104        AD1986A_LAPTOP_EAPD,
1105        AD1986A_LAPTOP_AUTOMUTE,
1106        AD1986A_ULTRA,
1107        AD1986A_SAMSUNG,
1108        AD1986A_SAMSUNG_P50,
1109        AD1986A_MODELS
1110};
1111
1112static const char * const ad1986a_models[AD1986A_MODELS] = {
1113        [AD1986A_6STACK]        = "6stack",
1114        [AD1986A_3STACK]        = "3stack",
1115        [AD1986A_LAPTOP]        = "laptop",
1116        [AD1986A_LAPTOP_EAPD]   = "laptop-eapd",
1117        [AD1986A_LAPTOP_AUTOMUTE] = "laptop-automute",
1118        [AD1986A_ULTRA]         = "ultra",
1119        [AD1986A_SAMSUNG]       = "samsung",
1120        [AD1986A_SAMSUNG_P50]   = "samsung-p50",
1121};
1122
1123static struct snd_pci_quirk ad1986a_cfg_tbl[] = {
1124        SND_PCI_QUIRK(0x103c, 0x30af, "HP B2800", AD1986A_LAPTOP_EAPD),
1125        SND_PCI_QUIRK(0x1043, 0x1153, "ASUS M9", AD1986A_LAPTOP_EAPD),
1126        SND_PCI_QUIRK(0x1043, 0x11f7, "ASUS U5A", AD1986A_LAPTOP_EAPD),
1127        SND_PCI_QUIRK(0x1043, 0x1213, "ASUS A6J", AD1986A_LAPTOP_EAPD),
1128        SND_PCI_QUIRK(0x1043, 0x1263, "ASUS U5F", AD1986A_LAPTOP_EAPD),
1129        SND_PCI_QUIRK(0x1043, 0x1297, "ASUS Z62F", AD1986A_LAPTOP_EAPD),
1130        SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS V1j", AD1986A_LAPTOP_EAPD),
1131        SND_PCI_QUIRK(0x1043, 0x1302, "ASUS W3j", AD1986A_LAPTOP_EAPD),
1132        SND_PCI_QUIRK(0x1043, 0x1443, "ASUS VX1", AD1986A_LAPTOP),
1133        SND_PCI_QUIRK(0x1043, 0x1447, "ASUS A8J", AD1986A_3STACK),
1134        SND_PCI_QUIRK(0x1043, 0x817f, "ASUS P5", AD1986A_3STACK),
1135        SND_PCI_QUIRK(0x1043, 0x818f, "ASUS P5", AD1986A_LAPTOP),
1136        SND_PCI_QUIRK(0x1043, 0x81b3, "ASUS P5", AD1986A_3STACK),
1137        SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS M2N", AD1986A_3STACK),
1138        SND_PCI_QUIRK(0x1043, 0x8234, "ASUS M2N", AD1986A_3STACK),
1139        SND_PCI_QUIRK(0x10de, 0xcb84, "ASUS A8N-VM", AD1986A_3STACK),
1140        SND_PCI_QUIRK(0x1179, 0xff40, "Toshiba Satellite L40-10Q", AD1986A_3STACK),
1141        SND_PCI_QUIRK(0x144d, 0xb03c, "Samsung R55", AD1986A_3STACK),
1142        SND_PCI_QUIRK(0x144d, 0xc01e, "FSC V2060", AD1986A_LAPTOP),
1143        SND_PCI_QUIRK(0x144d, 0xc024, "Samsung P50", AD1986A_SAMSUNG_P50),
1144        SND_PCI_QUIRK(0x144d, 0xc027, "Samsung Q1", AD1986A_ULTRA),
1145        SND_PCI_QUIRK_MASK(0x144d, 0xff00, 0xc000, "Samsung", AD1986A_SAMSUNG),
1146        SND_PCI_QUIRK(0x144d, 0xc504, "Samsung Q35", AD1986A_3STACK),
1147        SND_PCI_QUIRK(0x17aa, 0x1011, "Lenovo M55", AD1986A_LAPTOP),
1148        SND_PCI_QUIRK(0x17aa, 0x1017, "Lenovo A60", AD1986A_3STACK),
1149        SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo N100", AD1986A_LAPTOP_AUTOMUTE),
1150        SND_PCI_QUIRK(0x17c0, 0x2017, "Samsung M50", AD1986A_LAPTOP),
1151        {}
1152};
1153
1154#ifdef CONFIG_SND_HDA_POWER_SAVE
1155static struct hda_amp_list ad1986a_loopbacks[] = {
1156        { 0x13, HDA_OUTPUT, 0 }, /* Mic */
1157        { 0x14, HDA_OUTPUT, 0 }, /* Phone */
1158        { 0x15, HDA_OUTPUT, 0 }, /* CD */
1159        { 0x16, HDA_OUTPUT, 0 }, /* Aux */
1160        { 0x17, HDA_OUTPUT, 0 }, /* Line */
1161        { } /* end */
1162};
1163#endif
1164
1165static int is_jack_available(struct hda_codec *codec, hda_nid_t nid)
1166{
1167        unsigned int conf = snd_hda_codec_get_pincfg(codec, nid);
1168        return get_defcfg_connect(conf) != AC_JACK_PORT_NONE;
1169}
1170
1171static int patch_ad1986a(struct hda_codec *codec)
1172{
1173        struct ad198x_spec *spec;
1174        int err, board_config;
1175
1176        spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1177        if (spec == NULL)
1178                return -ENOMEM;
1179
1180        codec->spec = spec;
1181
1182        err = snd_hda_attach_beep_device(codec, 0x19);
1183        if (err < 0) {
1184                ad198x_free(codec);
1185                return err;
1186        }
1187        set_beep_amp(spec, 0x18, 0, HDA_OUTPUT);
1188
1189        spec->multiout.max_channels = 6;
1190        spec->multiout.num_dacs = ARRAY_SIZE(ad1986a_dac_nids);
1191        spec->multiout.dac_nids = ad1986a_dac_nids;
1192        spec->multiout.dig_out_nid = AD1986A_SPDIF_OUT;
1193        spec->num_adc_nids = 1;
1194        spec->adc_nids = ad1986a_adc_nids;
1195        spec->capsrc_nids = ad1986a_capsrc_nids;
1196        spec->input_mux = &ad1986a_capture_source;
1197        spec->num_mixers = 1;
1198        spec->mixers[0] = ad1986a_mixers;
1199        spec->num_init_verbs = 1;
1200        spec->init_verbs[0] = ad1986a_init_verbs;
1201#ifdef CONFIG_SND_HDA_POWER_SAVE
1202        spec->loopback.amplist = ad1986a_loopbacks;
1203#endif
1204        spec->vmaster_nid = 0x1b;
1205        spec->inv_eapd = 1; /* AD1986A has the inverted EAPD implementation */
1206
1207        codec->patch_ops = ad198x_patch_ops;
1208
1209        /* override some parameters */
1210        board_config = snd_hda_check_board_config(codec, AD1986A_MODELS,
1211                                                  ad1986a_models,
1212                                                  ad1986a_cfg_tbl);
1213        switch (board_config) {
1214        case AD1986A_3STACK:
1215                spec->num_mixers = 2;
1216                spec->mixers[1] = ad1986a_3st_mixers;
1217                spec->num_init_verbs = 2;
1218                spec->init_verbs[1] = ad1986a_ch2_init;
1219                spec->channel_mode = ad1986a_modes;
1220                spec->num_channel_mode = ARRAY_SIZE(ad1986a_modes);
1221                spec->need_dac_fix = 1;
1222                spec->multiout.max_channels = 2;
1223                spec->multiout.num_dacs = 1;
1224                break;
1225        case AD1986A_LAPTOP:
1226                spec->mixers[0] = ad1986a_laptop_mixers;
1227                spec->multiout.max_channels = 2;
1228                spec->multiout.num_dacs = 1;
1229                spec->multiout.dac_nids = ad1986a_laptop_dac_nids;
1230                break;
1231        case AD1986A_LAPTOP_EAPD:
1232                spec->num_mixers = 3;
1233                spec->mixers[0] = ad1986a_laptop_master_mixers;
1234                spec->mixers[1] = ad1986a_laptop_eapd_mixers;
1235                spec->mixers[2] = ad1986a_laptop_intmic_mixers;
1236                spec->num_init_verbs = 2;
1237                spec->init_verbs[1] = ad1986a_eapd_init_verbs;
1238                spec->multiout.max_channels = 2;
1239                spec->multiout.num_dacs = 1;
1240                spec->multiout.dac_nids = ad1986a_laptop_dac_nids;
1241                if (!is_jack_available(codec, 0x25))
1242                        spec->multiout.dig_out_nid = 0;
1243                spec->input_mux = &ad1986a_laptop_eapd_capture_source;
1244                break;
1245        case AD1986A_SAMSUNG:
1246                spec->num_mixers = 2;
1247                spec->mixers[0] = ad1986a_laptop_master_mixers;
1248                spec->mixers[1] = ad1986a_laptop_eapd_mixers;
1249                spec->num_init_verbs = 3;
1250                spec->init_verbs[1] = ad1986a_eapd_init_verbs;
1251                spec->init_verbs[2] = ad1986a_automic_verbs;
1252                spec->multiout.max_channels = 2;
1253                spec->multiout.num_dacs = 1;
1254                spec->multiout.dac_nids = ad1986a_laptop_dac_nids;
1255                if (!is_jack_available(codec, 0x25))
1256                        spec->multiout.dig_out_nid = 0;
1257                spec->input_mux = &ad1986a_automic_capture_source;
1258                codec->patch_ops.unsol_event = ad1986a_automic_unsol_event;
1259                codec->patch_ops.init = ad1986a_automic_init;
1260                break;
1261        case AD1986A_SAMSUNG_P50:
1262                spec->num_mixers = 2;
1263                spec->mixers[0] = ad1986a_automute_master_mixers;
1264                spec->mixers[1] = ad1986a_laptop_eapd_mixers;
1265                spec->num_init_verbs = 4;
1266                spec->init_verbs[1] = ad1986a_eapd_init_verbs;
1267                spec->init_verbs[2] = ad1986a_automic_verbs;
1268                spec->init_verbs[3] = ad1986a_hp_init_verbs;
1269                spec->multiout.max_channels = 2;
1270                spec->multiout.num_dacs = 1;
1271                spec->multiout.dac_nids = ad1986a_laptop_dac_nids;
1272                if (!is_jack_available(codec, 0x25))
1273                        spec->multiout.dig_out_nid = 0;
1274                spec->input_mux = &ad1986a_automic_capture_source;
1275                codec->patch_ops.unsol_event = ad1986a_samsung_p50_unsol_event;
1276                codec->patch_ops.init = ad1986a_samsung_p50_init;
1277                break;
1278        case AD1986A_LAPTOP_AUTOMUTE:
1279                spec->num_mixers = 3;
1280                spec->mixers[0] = ad1986a_automute_master_mixers;
1281                spec->mixers[1] = ad1986a_laptop_eapd_mixers;
1282                spec->mixers[2] = ad1986a_laptop_intmic_mixers;
1283                spec->num_init_verbs = 3;
1284                spec->init_verbs[1] = ad1986a_eapd_init_verbs;
1285                spec->init_verbs[2] = ad1986a_hp_init_verbs;
1286                spec->multiout.max_channels = 2;
1287                spec->multiout.num_dacs = 1;
1288                spec->multiout.dac_nids = ad1986a_laptop_dac_nids;
1289                if (!is_jack_available(codec, 0x25))
1290                        spec->multiout.dig_out_nid = 0;
1291                spec->input_mux = &ad1986a_laptop_eapd_capture_source;
1292                codec->patch_ops.unsol_event = ad1986a_hp_unsol_event;
1293                codec->patch_ops.init = ad1986a_hp_init;
1294                /* Lenovo N100 seems to report the reversed bit
1295                 * for HP jack-sensing
1296                 */
1297                spec->inv_jack_detect = 1;
1298                break;
1299        case AD1986A_ULTRA:
1300                spec->mixers[0] = ad1986a_laptop_eapd_mixers;
1301                spec->num_init_verbs = 2;
1302                spec->init_verbs[1] = ad1986a_ultra_init;
1303                spec->multiout.max_channels = 2;
1304                spec->multiout.num_dacs = 1;
1305                spec->multiout.dac_nids = ad1986a_laptop_dac_nids;
1306                spec->multiout.dig_out_nid = 0;
1307                break;
1308        }
1309
1310        /* AD1986A has a hardware problem that it can't share a stream
1311         * with multiple output pins.  The copy of front to surrounds
1312         * causes noisy or silent outputs at a certain timing, e.g.
1313         * changing the volume.
1314         * So, let's disable the shared stream.
1315         */
1316        spec->multiout.no_share_stream = 1;
1317
1318        codec->no_trigger_sense = 1;
1319        codec->no_sticky_stream = 1;
1320
1321        return 0;
1322}
1323
1324/*
1325 * AD1983 specific
1326 */
1327
1328#define AD1983_SPDIF_OUT        0x02
1329#define AD1983_DAC              0x03
1330#define AD1983_ADC              0x04
1331
1332static hda_nid_t ad1983_dac_nids[1] = { AD1983_DAC };
1333static hda_nid_t ad1983_adc_nids[1] = { AD1983_ADC };
1334static hda_nid_t ad1983_capsrc_nids[1] = { 0x15 };
1335
1336static struct hda_input_mux ad1983_capture_source = {
1337        .num_items = 4,
1338        .items = {
1339                { "Mic", 0x0 },
1340                { "Line", 0x1 },
1341                { "Mix", 0x2 },
1342                { "Mix Mono", 0x3 },
1343        },
1344};
1345
1346/*
1347 * SPDIF playback route
1348 */
1349static int ad1983_spdif_route_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
1350{
1351        static char *texts[] = { "PCM", "ADC" };
1352
1353        uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1354        uinfo->count = 1;
1355        uinfo->value.enumerated.items = 2;
1356        if (uinfo->value.enumerated.item > 1)
1357                uinfo->value.enumerated.item = 1;
1358        strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
1359        return 0;
1360}
1361
1362static int ad1983_spdif_route_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1363{
1364        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1365        struct ad198x_spec *spec = codec->spec;
1366
1367        ucontrol->value.enumerated.item[0] = spec->spdif_route;
1368        return 0;
1369}
1370
1371static int ad1983_spdif_route_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1372{
1373        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1374        struct ad198x_spec *spec = codec->spec;
1375
1376        if (ucontrol->value.enumerated.item[0] > 1)
1377                return -EINVAL;
1378        if (spec->spdif_route != ucontrol->value.enumerated.item[0]) {
1379                spec->spdif_route = ucontrol->value.enumerated.item[0];
1380                snd_hda_codec_write_cache(codec, spec->multiout.dig_out_nid, 0,
1381                                          AC_VERB_SET_CONNECT_SEL,
1382                                          spec->spdif_route);
1383                return 1;
1384        }
1385        return 0;
1386}
1387
1388static struct snd_kcontrol_new ad1983_mixers[] = {
1389        HDA_CODEC_VOLUME("Front Playback Volume", 0x05, 0x0, HDA_OUTPUT),
1390        HDA_CODEC_MUTE("Front Playback Switch", 0x05, 0x0, HDA_OUTPUT),
1391        HDA_CODEC_VOLUME("Headphone Playback Volume", 0x06, 0x0, HDA_OUTPUT),
1392        HDA_CODEC_MUTE("Headphone Playback Switch", 0x06, 0x0, HDA_OUTPUT),
1393        HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x07, 1, 0x0, HDA_OUTPUT),
1394        HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x07, 1, 0x0, HDA_OUTPUT),
1395        HDA_CODEC_VOLUME("PCM Playback Volume", 0x11, 0x0, HDA_OUTPUT),
1396        HDA_CODEC_MUTE("PCM Playback Switch", 0x11, 0x0, HDA_OUTPUT),
1397        HDA_CODEC_VOLUME("Mic Playback Volume", 0x12, 0x0, HDA_OUTPUT),
1398        HDA_CODEC_MUTE("Mic Playback Switch", 0x12, 0x0, HDA_OUTPUT),
1399        HDA_CODEC_VOLUME("Line Playback Volume", 0x13, 0x0, HDA_OUTPUT),
1400        HDA_CODEC_MUTE("Line Playback Switch", 0x13, 0x0, HDA_OUTPUT),
1401        HDA_CODEC_VOLUME("Mic Boost Volume", 0x0c, 0x0, HDA_OUTPUT),
1402        HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT),
1403        HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_OUTPUT),
1404        {
1405                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1406                .name = "Capture Source",
1407                .info = ad198x_mux_enum_info,
1408                .get = ad198x_mux_enum_get,
1409                .put = ad198x_mux_enum_put,
1410        },
1411        {
1412                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1413                .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
1414                .info = ad1983_spdif_route_info,
1415                .get = ad1983_spdif_route_get,
1416                .put = ad1983_spdif_route_put,
1417        },
1418        { } /* end */
1419};
1420
1421static struct hda_verb ad1983_init_verbs[] = {
1422        /* Front, HP, Mono; mute as default */
1423        {0x05, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1424        {0x06, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1425        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1426        /* Beep, PCM, Mic, Line-In: mute */
1427        {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1428        {0x11, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1429        {0x12, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1430        {0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1431        /* Front, HP selectors; from Mix */
1432        {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
1433        {0x06, AC_VERB_SET_CONNECT_SEL, 0x01},
1434        /* Mono selector; from Mix */
1435        {0x0b, AC_VERB_SET_CONNECT_SEL, 0x03},
1436        /* Mic selector; Mic */
1437        {0x0c, AC_VERB_SET_CONNECT_SEL, 0x0},
1438        /* Line-in selector: Line-in */
1439        {0x0d, AC_VERB_SET_CONNECT_SEL, 0x0},
1440        /* Mic boost: 0dB */
1441        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
1442        /* Record selector: mic */
1443        {0x15, AC_VERB_SET_CONNECT_SEL, 0x0},
1444        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1445        /* SPDIF route: PCM */
1446        {0x02, AC_VERB_SET_CONNECT_SEL, 0x0},
1447        /* Front Pin */
1448        {0x05, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
1449        /* HP Pin */
1450        {0x06, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
1451        /* Mono Pin */
1452        {0x07, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
1453        /* Mic Pin */
1454        {0x08, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
1455        /* Line Pin */
1456        {0x09, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
1457        { } /* end */
1458};
1459
1460#ifdef CONFIG_SND_HDA_POWER_SAVE
1461static struct hda_amp_list ad1983_loopbacks[] = {
1462        { 0x12, HDA_OUTPUT, 0 }, /* Mic */
1463        { 0x13, HDA_OUTPUT, 0 }, /* Line */
1464        { } /* end */
1465};
1466#endif
1467
1468static int patch_ad1983(struct hda_codec *codec)
1469{
1470        struct ad198x_spec *spec;
1471        int err;
1472
1473        spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1474        if (spec == NULL)
1475                return -ENOMEM;
1476
1477        codec->spec = spec;
1478
1479        err = snd_hda_attach_beep_device(codec, 0x10);
1480        if (err < 0) {
1481                ad198x_free(codec);
1482                return err;
1483        }
1484        set_beep_amp(spec, 0x10, 0, HDA_OUTPUT);
1485
1486        spec->multiout.max_channels = 2;
1487        spec->multiout.num_dacs = ARRAY_SIZE(ad1983_dac_nids);
1488        spec->multiout.dac_nids = ad1983_dac_nids;
1489        spec->multiout.dig_out_nid = AD1983_SPDIF_OUT;
1490        spec->num_adc_nids = 1;
1491        spec->adc_nids = ad1983_adc_nids;
1492        spec->capsrc_nids = ad1983_capsrc_nids;
1493        spec->input_mux = &ad1983_capture_source;
1494        spec->num_mixers = 1;
1495        spec->mixers[0] = ad1983_mixers;
1496        spec->num_init_verbs = 1;
1497        spec->init_verbs[0] = ad1983_init_verbs;
1498        spec->spdif_route = 0;
1499#ifdef CONFIG_SND_HDA_POWER_SAVE
1500        spec->loopback.amplist = ad1983_loopbacks;
1501#endif
1502        spec->vmaster_nid = 0x05;
1503
1504        codec->patch_ops = ad198x_patch_ops;
1505
1506        codec->no_trigger_sense = 1;
1507        codec->no_sticky_stream = 1;
1508
1509        return 0;
1510}
1511
1512
1513/*
1514 * AD1981 HD specific
1515 */
1516
1517#define AD1981_SPDIF_OUT        0x02
1518#define AD1981_DAC              0x03
1519#define AD1981_ADC              0x04
1520
1521static hda_nid_t ad1981_dac_nids[1] = { AD1981_DAC };
1522static hda_nid_t ad1981_adc_nids[1] = { AD1981_ADC };
1523static hda_nid_t ad1981_capsrc_nids[1] = { 0x15 };
1524
1525/* 0x0c, 0x09, 0x0e, 0x0f, 0x19, 0x05, 0x18, 0x17 */
1526static struct hda_input_mux ad1981_capture_source = {
1527        .num_items = 7,
1528        .items = {
1529                { "Front Mic", 0x0 },
1530                { "Line", 0x1 },
1531                { "Mix", 0x2 },
1532                { "Mix Mono", 0x3 },
1533                { "CD", 0x4 },
1534                { "Mic", 0x6 },
1535                { "Aux", 0x7 },
1536        },
1537};
1538
1539static struct snd_kcontrol_new ad1981_mixers[] = {
1540        HDA_CODEC_VOLUME("Front Playback Volume", 0x05, 0x0, HDA_OUTPUT),
1541        HDA_CODEC_MUTE("Front Playback Switch", 0x05, 0x0, HDA_OUTPUT),
1542        HDA_CODEC_VOLUME("Headphone Playback Volume", 0x06, 0x0, HDA_OUTPUT),
1543        HDA_CODEC_MUTE("Headphone Playback Switch", 0x06, 0x0, HDA_OUTPUT),
1544        HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x07, 1, 0x0, HDA_OUTPUT),
1545        HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x07, 1, 0x0, HDA_OUTPUT),
1546        HDA_CODEC_VOLUME("PCM Playback Volume", 0x11, 0x0, HDA_OUTPUT),
1547        HDA_CODEC_MUTE("PCM Playback Switch", 0x11, 0x0, HDA_OUTPUT),
1548        HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x12, 0x0, HDA_OUTPUT),
1549        HDA_CODEC_MUTE("Front Mic Playback Switch", 0x12, 0x0, HDA_OUTPUT),
1550        HDA_CODEC_VOLUME("Line Playback Volume", 0x13, 0x0, HDA_OUTPUT),
1551        HDA_CODEC_MUTE("Line Playback Switch", 0x13, 0x0, HDA_OUTPUT),
1552        HDA_CODEC_VOLUME("Aux Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
1553        HDA_CODEC_MUTE("Aux Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1554        HDA_CODEC_VOLUME("Mic Playback Volume", 0x1c, 0x0, HDA_OUTPUT),
1555        HDA_CODEC_MUTE("Mic Playback Switch", 0x1c, 0x0, HDA_OUTPUT),
1556        HDA_CODEC_VOLUME("CD Playback Volume", 0x1d, 0x0, HDA_OUTPUT),
1557        HDA_CODEC_MUTE("CD Playback Switch", 0x1d, 0x0, HDA_OUTPUT),
1558        HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x08, 0x0, HDA_INPUT),
1559        HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0x0, HDA_INPUT),
1560        HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT),
1561        HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_OUTPUT),
1562        {
1563                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1564                .name = "Capture Source",
1565                .info = ad198x_mux_enum_info,
1566                .get = ad198x_mux_enum_get,
1567                .put = ad198x_mux_enum_put,
1568        },
1569        /* identical with AD1983 */
1570        {
1571                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1572                .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
1573                .info = ad1983_spdif_route_info,
1574                .get = ad1983_spdif_route_get,
1575                .put = ad1983_spdif_route_put,
1576        },
1577        { } /* end */
1578};
1579
1580static struct hda_verb ad1981_init_verbs[] = {
1581        /* Front, HP, Mono; mute as default */
1582        {0x05, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1583        {0x06, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1584        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1585        /* Beep, PCM, Front Mic, Line, Rear Mic, Aux, CD-In: mute */
1586        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1587        {0x11, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1588        {0x12, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1589        {0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1590        {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1591        {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1592        {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1593        /* Front, HP selectors; from Mix */
1594        {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
1595        {0x06, AC_VERB_SET_CONNECT_SEL, 0x01},
1596        /* Mono selector; from Mix */
1597        {0x0b, AC_VERB_SET_CONNECT_SEL, 0x03},
1598        /* Mic Mixer; select Front Mic */
1599        {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
1600        {0x1f, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1601        /* Mic boost: 0dB */
1602        {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1603        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1604        /* Record selector: Front mic */
1605        {0x15, AC_VERB_SET_CONNECT_SEL, 0x0},
1606        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1607        /* SPDIF route: PCM */
1608        {0x02, AC_VERB_SET_CONNECT_SEL, 0x0},
1609        /* Front Pin */
1610        {0x05, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
1611        /* HP Pin */
1612        {0x06, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
1613        /* Mono Pin */
1614        {0x07, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
1615        /* Front & Rear Mic Pins */
1616        {0x08, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
1617        {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
1618        /* Line Pin */
1619        {0x09, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
1620        /* Digital Beep */
1621        {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
1622        /* Line-Out as Input: disabled */
1623        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1624        { } /* end */
1625};
1626
1627#ifdef CONFIG_SND_HDA_POWER_SAVE
1628static struct hda_amp_list ad1981_loopbacks[] = {
1629        { 0x12, HDA_OUTPUT, 0 }, /* Front Mic */
1630        { 0x13, HDA_OUTPUT, 0 }, /* Line */
1631        { 0x1b, HDA_OUTPUT, 0 }, /* Aux */
1632        { 0x1c, HDA_OUTPUT, 0 }, /* Mic */
1633        { 0x1d, HDA_OUTPUT, 0 }, /* CD */
1634        { } /* end */
1635};
1636#endif
1637
1638/*
1639 * Patch for HP nx6320
1640 *
1641 * nx6320 uses EAPD in the reverse way - EAPD-on means the internal
1642 * speaker output enabled _and_ mute-LED off.
1643 */
1644
1645#define AD1981_HP_EVENT         0x37
1646#define AD1981_MIC_EVENT        0x38
1647
1648static struct hda_verb ad1981_hp_init_verbs[] = {
1649        {0x05, AC_VERB_SET_EAPD_BTLENABLE, 0x00 }, /* default off */
1650        /* pin sensing on HP and Mic jacks */
1651        {0x06, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1981_HP_EVENT},
1652        {0x08, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1981_MIC_EVENT},
1653        {}
1654};
1655
1656/* turn on/off EAPD (+ mute HP) as a master switch */
1657static int ad1981_hp_master_sw_put(struct snd_kcontrol *kcontrol,
1658                                   struct snd_ctl_elem_value *ucontrol)
1659{
1660        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1661        struct ad198x_spec *spec = codec->spec;
1662
1663        if (! ad198x_eapd_put(kcontrol, ucontrol))
1664                return 0;
1665        /* change speaker pin appropriately */
1666        snd_hda_codec_write(codec, 0x05, 0,
1667                            AC_VERB_SET_PIN_WIDGET_CONTROL,
1668                            spec->cur_eapd ? PIN_OUT : 0);
1669        /* toggle HP mute appropriately */
1670        snd_hda_codec_amp_stereo(codec, 0x06, HDA_OUTPUT, 0,
1671                                 HDA_AMP_MUTE,
1672                                 spec->cur_eapd ? 0 : HDA_AMP_MUTE);
1673        return 1;
1674}
1675
1676/* bind volumes of both NID 0x05 and 0x06 */
1677static struct hda_bind_ctls ad1981_hp_bind_master_vol = {
1678        .ops = &snd_hda_bind_vol,
1679        .values = {
1680                HDA_COMPOSE_AMP_VAL(0x05, 3, 0, HDA_OUTPUT),
1681                HDA_COMPOSE_AMP_VAL(0x06, 3, 0, HDA_OUTPUT),
1682                0
1683        },
1684};
1685
1686/* mute internal speaker if HP is plugged */
1687static void ad1981_hp_automute(struct hda_codec *codec)
1688{
1689        unsigned int present;
1690
1691        present = snd_hda_jack_detect(codec, 0x06);
1692        snd_hda_codec_amp_stereo(codec, 0x05, HDA_OUTPUT, 0,
1693                                 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
1694}
1695
1696/* toggle input of built-in and mic jack appropriately */
1697static void ad1981_hp_automic(struct hda_codec *codec)
1698{
1699        static struct hda_verb mic_jack_on[] = {
1700                {0x1f, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1701                {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
1702                {}
1703        };
1704        static struct hda_verb mic_jack_off[] = {
1705                {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1706                {0x1f, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
1707                {}
1708        };
1709        unsigned int present;
1710
1711        present = snd_hda_jack_detect(codec, 0x08);
1712        if (present)
1713                snd_hda_sequence_write(codec, mic_jack_on);
1714        else
1715                snd_hda_sequence_write(codec, mic_jack_off);
1716}
1717
1718/* unsolicited event for HP jack sensing */
1719static void ad1981_hp_unsol_event(struct hda_codec *codec,
1720                                  unsigned int res)
1721{
1722        res >>= 26;
1723        switch (res) {
1724        case AD1981_HP_EVENT:
1725                ad1981_hp_automute(codec);
1726                break;
1727        case AD1981_MIC_EVENT:
1728                ad1981_hp_automic(codec);
1729                break;
1730        }
1731}
1732
1733static struct hda_input_mux ad1981_hp_capture_source = {
1734        .num_items = 3,
1735        .items = {
1736                { "Mic", 0x0 },
1737                { "Docking-Station", 0x1 },
1738                { "Mix", 0x2 },
1739        },
1740};
1741
1742static struct snd_kcontrol_new ad1981_hp_mixers[] = {
1743        HDA_BIND_VOL("Master Playback Volume", &ad1981_hp_bind_master_vol),
1744        {
1745                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1746                .subdevice = HDA_SUBDEV_NID_FLAG | 0x05,
1747                .name = "Master Playback Switch",
1748                .info = ad198x_eapd_info,
1749                .get = ad198x_eapd_get,
1750                .put = ad1981_hp_master_sw_put,
1751                .private_value = 0x05,
1752        },
1753        HDA_CODEC_VOLUME("PCM Playback Volume", 0x11, 0x0, HDA_OUTPUT),
1754        HDA_CODEC_MUTE("PCM Playback Switch", 0x11, 0x0, HDA_OUTPUT),
1755#if 0
1756        /* FIXME: analog mic/line loopback doesn't work with my tests...
1757         *        (although recording is OK)
1758         */
1759        HDA_CODEC_VOLUME("Mic Playback Volume", 0x12, 0x0, HDA_OUTPUT),
1760        HDA_CODEC_MUTE("Mic Playback Switch", 0x12, 0x0, HDA_OUTPUT),
1761        HDA_CODEC_VOLUME("Docking-Station Playback Volume", 0x13, 0x0, HDA_OUTPUT),
1762        HDA_CODEC_MUTE("Docking-Station Playback Switch", 0x13, 0x0, HDA_OUTPUT),
1763        HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x1c, 0x0, HDA_OUTPUT),
1764        HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x1c, 0x0, HDA_OUTPUT),
1765        /* FIXME: does this laptop have analog CD connection? */
1766        HDA_CODEC_VOLUME("CD Playback Volume", 0x1d, 0x0, HDA_OUTPUT),
1767        HDA_CODEC_MUTE("CD Playback Switch", 0x1d, 0x0, HDA_OUTPUT),
1768#endif
1769        HDA_CODEC_VOLUME("Mic Boost Volume", 0x08, 0x0, HDA_INPUT),
1770        HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x18, 0x0, HDA_INPUT),
1771        HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT),
1772        HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_OUTPUT),
1773        {
1774                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1775                .name = "Capture Source",
1776                .info = ad198x_mux_enum_info,
1777                .get = ad198x_mux_enum_get,
1778                .put = ad198x_mux_enum_put,
1779        },
1780        { } /* end */
1781};
1782
1783/* initialize jack-sensing, too */
1784static int ad1981_hp_init(struct hda_codec *codec)
1785{
1786        ad198x_init(codec);
1787        ad1981_hp_automute(codec);
1788        ad1981_hp_automic(codec);
1789        return 0;
1790}
1791
1792/* configuration for Toshiba Laptops */
1793static struct hda_verb ad1981_toshiba_init_verbs[] = {
1794        {0x05, AC_VERB_SET_EAPD_BTLENABLE, 0x01 }, /* default on */
1795        /* pin sensing on HP and Mic jacks */
1796        {0x06, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1981_HP_EVENT},
1797        {0x08, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1981_MIC_EVENT},
1798        {}
1799};
1800
1801static struct snd_kcontrol_new ad1981_toshiba_mixers[] = {
1802        HDA_CODEC_VOLUME("Amp Volume", 0x1a, 0x0, HDA_OUTPUT),
1803        HDA_CODEC_MUTE("Amp Switch", 0x1a, 0x0, HDA_OUTPUT),
1804        { }
1805};
1806
1807/* configuration for Lenovo Thinkpad T60 */
1808static struct snd_kcontrol_new ad1981_thinkpad_mixers[] = {
1809        HDA_CODEC_VOLUME("Master Playback Volume", 0x05, 0x0, HDA_OUTPUT),
1810        HDA_CODEC_MUTE("Master Playback Switch", 0x05, 0x0, HDA_OUTPUT),
1811        HDA_CODEC_VOLUME("PCM Playback Volume", 0x11, 0x0, HDA_OUTPUT),
1812        HDA_CODEC_MUTE("PCM Playback Switch", 0x11, 0x0, HDA_OUTPUT),
1813        HDA_CODEC_VOLUME("Mic Playback Volume", 0x12, 0x0, HDA_OUTPUT),
1814        HDA_CODEC_MUTE("Mic Playback Switch", 0x12, 0x0, HDA_OUTPUT),
1815        HDA_CODEC_VOLUME("CD Playback Volume", 0x1d, 0x0, HDA_OUTPUT),
1816        HDA_CODEC_MUTE("CD Playback Switch", 0x1d, 0x0, HDA_OUTPUT),
1817        HDA_CODEC_VOLUME("Mic Boost Volume", 0x08, 0x0, HDA_INPUT),
1818        HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT),
1819        HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_OUTPUT),
1820        {
1821                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1822                .name = "Capture Source",
1823                .info = ad198x_mux_enum_info,
1824                .get = ad198x_mux_enum_get,
1825                .put = ad198x_mux_enum_put,
1826        },
1827        /* identical with AD1983 */
1828        {
1829                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1830                .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
1831                .info = ad1983_spdif_route_info,
1832                .get = ad1983_spdif_route_get,
1833                .put = ad1983_spdif_route_put,
1834        },
1835        { } /* end */
1836};
1837
1838static struct hda_input_mux ad1981_thinkpad_capture_source = {
1839        .num_items = 3,
1840        .items = {
1841                { "Mic", 0x0 },
1842                { "Mix", 0x2 },
1843                { "CD", 0x4 },
1844        },
1845};
1846
1847/* models */
1848enum {
1849        AD1981_BASIC,
1850        AD1981_HP,
1851        AD1981_THINKPAD,
1852        AD1981_TOSHIBA,
1853        AD1981_MODELS
1854};
1855
1856static const char * const ad1981_models[AD1981_MODELS] = {
1857        [AD1981_HP]             = "hp",
1858        [AD1981_THINKPAD]       = "thinkpad",
1859        [AD1981_BASIC]          = "basic",
1860        [AD1981_TOSHIBA]        = "toshiba"
1861};
1862
1863static struct snd_pci_quirk ad1981_cfg_tbl[] = {
1864        SND_PCI_QUIRK(0x1014, 0x0597, "Lenovo Z60", AD1981_THINKPAD),
1865        SND_PCI_QUIRK(0x1014, 0x05b7, "Lenovo Z60m", AD1981_THINKPAD),
1866        /* All HP models */
1867        SND_PCI_QUIRK_VENDOR(0x103c, "HP nx", AD1981_HP),
1868        SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba U205", AD1981_TOSHIBA),
1869        /* Lenovo Thinkpad T60/X60/Z6xx */
1870        SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo Thinkpad", AD1981_THINKPAD),
1871        /* HP nx6320 (reversed SSID, H/W bug) */
1872        SND_PCI_QUIRK(0x30b0, 0x103c, "HP nx6320", AD1981_HP),
1873        {}
1874};
1875
1876static int patch_ad1981(struct hda_codec *codec)
1877{
1878        struct ad198x_spec *spec;
1879        int err, board_config;
1880
1881        spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1882        if (spec == NULL)
1883                return -ENOMEM;
1884
1885        codec->spec = spec;
1886
1887        err = snd_hda_attach_beep_device(codec, 0x10);
1888        if (err < 0) {
1889                ad198x_free(codec);
1890                return err;
1891        }
1892        set_beep_amp(spec, 0x0d, 0, HDA_OUTPUT);
1893
1894        spec->multiout.max_channels = 2;
1895        spec->multiout.num_dacs = ARRAY_SIZE(ad1981_dac_nids);
1896        spec->multiout.dac_nids = ad1981_dac_nids;
1897        spec->multiout.dig_out_nid = AD1981_SPDIF_OUT;
1898        spec->num_adc_nids = 1;
1899        spec->adc_nids = ad1981_adc_nids;
1900        spec->capsrc_nids = ad1981_capsrc_nids;
1901        spec->input_mux = &ad1981_capture_source;
1902        spec->num_mixers = 1;
1903        spec->mixers[0] = ad1981_mixers;
1904        spec->num_init_verbs = 1;
1905        spec->init_verbs[0] = ad1981_init_verbs;
1906        spec->spdif_route = 0;
1907#ifdef CONFIG_SND_HDA_POWER_SAVE
1908        spec->loopback.amplist = ad1981_loopbacks;
1909#endif
1910        spec->vmaster_nid = 0x05;
1911
1912        codec->patch_ops = ad198x_patch_ops;
1913
1914        /* override some parameters */
1915        board_config = snd_hda_check_board_config(codec, AD1981_MODELS,
1916                                                  ad1981_models,
1917                                                  ad1981_cfg_tbl);
1918        switch (board_config) {
1919        case AD1981_HP:
1920                spec->mixers[0] = ad1981_hp_mixers;
1921                spec->num_init_verbs = 2;
1922                spec->init_verbs[1] = ad1981_hp_init_verbs;
1923                spec->multiout.dig_out_nid = 0;
1924                spec->input_mux = &ad1981_hp_capture_source;
1925
1926                codec->patch_ops.init = ad1981_hp_init;
1927                codec->patch_ops.unsol_event = ad1981_hp_unsol_event;
1928                /* set the upper-limit for mixer amp to 0dB for avoiding the
1929                 * possible damage by overloading
1930                 */
1931                snd_hda_override_amp_caps(codec, 0x11, HDA_INPUT,
1932                                          (0x17 << AC_AMPCAP_OFFSET_SHIFT) |
1933                                          (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) |
1934                                          (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) |
1935                                          (1 << AC_AMPCAP_MUTE_SHIFT));
1936                break;
1937        case AD1981_THINKPAD:
1938                spec->mixers[0] = ad1981_thinkpad_mixers;
1939                spec->input_mux = &ad1981_thinkpad_capture_source;
1940                /* set the upper-limit for mixer amp to 0dB for avoiding the
1941                 * possible damage by overloading
1942                 */
1943                snd_hda_override_amp_caps(codec, 0x11, HDA_INPUT,
1944                                          (0x17 << AC_AMPCAP_OFFSET_SHIFT) |
1945                                          (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) |
1946                                          (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) |
1947                                          (1 << AC_AMPCAP_MUTE_SHIFT));
1948                break;
1949        case AD1981_TOSHIBA:
1950                spec->mixers[0] = ad1981_hp_mixers;
1951                spec->mixers[1] = ad1981_toshiba_mixers;
1952                spec->num_init_verbs = 2;
1953                spec->init_verbs[1] = ad1981_toshiba_init_verbs;
1954                spec->multiout.dig_out_nid = 0;
1955                spec->input_mux = &ad1981_hp_capture_source;
1956                codec->patch_ops.init = ad1981_hp_init;
1957                codec->patch_ops.unsol_event = ad1981_hp_unsol_event;
1958                break;
1959        }
1960
1961        codec->no_trigger_sense = 1;
1962        codec->no_sticky_stream = 1;
1963
1964        return 0;
1965}
1966
1967
1968/*
1969 * AD1988
1970 *
1971 * Output pins and routes
1972 *
1973 *        Pin               Mix     Sel     DAC (*)
1974 * port-A 0x11 (mute/hp) <- 0x22 <- 0x37 <- 03/04/06
1975 * port-B 0x14 (mute/hp) <- 0x2b <- 0x30 <- 03/04/06
1976 * port-C 0x15 (mute)    <- 0x2c <- 0x31 <- 05/0a
1977 * port-D 0x12 (mute/hp) <- 0x29         <- 04
1978 * port-E 0x17 (mute/hp) <- 0x26 <- 0x32 <- 05/0a
1979 * port-F 0x16 (mute)    <- 0x2a         <- 06
1980 * port-G 0x24 (mute)    <- 0x27         <- 05
1981 * port-H 0x25 (mute)    <- 0x28         <- 0a
1982 * mono   0x13 (mute/amp)<- 0x1e <- 0x36 <- 03/04/06
1983 *
1984 * DAC0 = 03h, DAC1 = 04h, DAC2 = 05h, DAC3 = 06h, DAC4 = 0ah
1985 * (*) DAC2/3/4 are swapped to DAC3/4/2 on AD198A rev.2 due to a h/w bug.
1986 *
1987 * Input pins and routes
1988 *
1989 *        pin     boost   mix input # / adc input #
1990 * port-A 0x11 -> 0x38 -> mix 2, ADC 0
1991 * port-B 0x14 -> 0x39 -> mix 0, ADC 1
1992 * port-C 0x15 -> 0x3a -> 33:0 - mix 1, ADC 2
1993 * port-D 0x12 -> 0x3d -> mix 3, ADC 8
1994 * port-E 0x17 -> 0x3c -> 34:0 - mix 4, ADC 4
1995 * port-F 0x16 -> 0x3b -> mix 5, ADC 3
1996 * port-G 0x24 -> N/A  -> 33:1 - mix 1, 34:1 - mix 4, ADC 6
1997 * port-H 0x25 -> N/A  -> 33:2 - mix 1, 34:2 - mix 4, ADC 7
1998 *
1999 *
2000 * DAC assignment
2001 *   6stack - front/surr/CLFE/side/opt DACs - 04/06/05/0a/03
2002 *   3stack - front/surr/CLFE/opt DACs - 04/05/0a/03
2003 *
2004 * Inputs of Analog Mix (0x20)
2005 *   0:Port-B (front mic)
2006 *   1:Port-C/G/H (line-in)
2007 *   2:Port-A
2008 *   3:Port-D (line-in/2)
2009 *   4:Port-E/G/H (mic-in)
2010 *   5:Port-F (mic2-in)
2011 *   6:CD
2012 *   7:Beep
2013 *
2014 * ADC selection
2015 *   0:Port-A
2016 *   1:Port-B (front mic-in)
2017 *   2:Port-C (line-in)
2018 *   3:Port-F (mic2-in)
2019 *   4:Port-E (mic-in)
2020 *   5:CD
2021 *   6:Port-G
2022 *   7:Port-H
2023 *   8:Port-D (line-in/2)
2024 *   9:Mix
2025 *
2026 * Proposed pin assignments by the datasheet
2027 *
2028 * 6-stack
2029 * Port-A front headphone
2030 *      B front mic-in
2031 *      C rear line-in
2032 *      D rear front-out
2033 *      E rear mic-in
2034 *      F rear surround
2035 *      G rear CLFE
2036 *      H rear side
2037 *
2038 * 3-stack
2039 * Port-A front headphone
2040 *      B front mic
2041 *      C rear line-in/surround
2042 *      D rear front-out
2043 *      E rear mic-in/CLFE
2044 *
2045 * laptop
2046 * Port-A headphone
2047 *      B mic-in
2048 *      C docking station
2049 *      D internal speaker (with EAPD)
2050 *      E/F quad mic array
2051 */
2052
2053
2054/* models */
2055enum {
2056        AD1988_6STACK,
2057        AD1988_6STACK_DIG,
2058        AD1988_6STACK_DIG_FP,
2059        AD1988_3STACK,
2060        AD1988_3STACK_DIG,
2061        AD1988_LAPTOP,
2062        AD1988_LAPTOP_DIG,
2063        AD1988_AUTO,
2064        AD1988_MODEL_LAST,
2065};
2066
2067/* reivision id to check workarounds */
2068#define AD1988A_REV2            0x100200
2069
2070#define is_rev2(codec) \
2071        ((codec)->vendor_id == 0x11d41988 && \
2072         (codec)->revision_id == AD1988A_REV2)
2073
2074/*
2075 * mixers
2076 */
2077
2078static hda_nid_t ad1988_6stack_dac_nids[4] = {
2079        0x04, 0x06, 0x05, 0x0a
2080};
2081
2082static hda_nid_t ad1988_3stack_dac_nids[3] = {
2083        0x04, 0x05, 0x0a
2084};
2085
2086/* for AD1988A revision-2, DAC2-4 are swapped */
2087static hda_nid_t ad1988_6stack_dac_nids_rev2[4] = {
2088        0x04, 0x05, 0x0a, 0x06
2089};
2090
2091static hda_nid_t ad1988_alt_dac_nid[1] = {
2092        0x03
2093};
2094
2095static hda_nid_t ad1988_3stack_dac_nids_rev2[3] = {
2096        0x04, 0x0a, 0x06
2097};
2098
2099static hda_nid_t ad1988_adc_nids[3] = {
2100        0x08, 0x09, 0x0f
2101};
2102
2103static hda_nid_t ad1988_capsrc_nids[3] = {
2104        0x0c, 0x0d, 0x0e
2105};
2106
2107#define AD1988_SPDIF_OUT                0x02
2108#define AD1988_SPDIF_OUT_HDMI   0x0b
2109#define AD1988_SPDIF_IN         0x07
2110
2111static hda_nid_t ad1989b_slave_dig_outs[] = {
2112        AD1988_SPDIF_OUT, AD1988_SPDIF_OUT_HDMI, 0
2113};
2114
2115static struct hda_input_mux ad1988_6stack_capture_source = {
2116        .num_items = 5,
2117        .items = {
2118                { "Front Mic", 0x1 },   /* port-B */
2119                { "Line", 0x2 },        /* port-C */
2120                { "Mic", 0x4 },         /* port-E */
2121                { "CD", 0x5 },
2122                { "Mix", 0x9 },
2123        },
2124};
2125
2126static struct hda_input_mux ad1988_laptop_capture_source = {
2127        .num_items = 3,
2128        .items = {
2129                { "Mic/Line", 0x1 },    /* port-B */
2130                { "CD", 0x5 },
2131                { "Mix", 0x9 },
2132        },
2133};
2134
2135/*
2136 */
2137static int ad198x_ch_mode_info(struct snd_kcontrol *kcontrol,
2138                               struct snd_ctl_elem_info *uinfo)
2139{
2140        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2141        struct ad198x_spec *spec = codec->spec;
2142        return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
2143                                    spec->num_channel_mode);
2144}
2145
2146static int ad198x_ch_mode_get(struct snd_kcontrol *kcontrol,
2147                              struct snd_ctl_elem_value *ucontrol)
2148{
2149        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2150        struct ad198x_spec *spec = codec->spec;
2151        return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
2152                                   spec->num_channel_mode, spec->multiout.max_channels);
2153}
2154
2155static int ad198x_ch_mode_put(struct snd_kcontrol *kcontrol,
2156                              struct snd_ctl_elem_value *ucontrol)
2157{
2158        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2159        struct ad198x_spec *spec = codec->spec;
2160        int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
2161                                      spec->num_channel_mode,
2162                                      &spec->multiout.max_channels);
2163        if (err >= 0 && spec->need_dac_fix)
2164                spec->multiout.num_dacs = spec->multiout.max_channels / 2;
2165        return err;
2166}
2167
2168/* 6-stack mode */
2169static struct snd_kcontrol_new ad1988_6stack_mixers1[] = {
2170        HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT),
2171        HDA_CODEC_VOLUME("Surround Playback Volume", 0x06, 0x0, HDA_OUTPUT),
2172        HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x05, 1, 0x0, HDA_OUTPUT),
2173        HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x05, 2, 0x0, HDA_OUTPUT),
2174        HDA_CODEC_VOLUME("Side Playback Volume", 0x0a, 0x0, HDA_OUTPUT),
2175        { } /* end */
2176};
2177
2178static struct snd_kcontrol_new ad1988_6stack_mixers1_rev2[] = {
2179        HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT),
2180        HDA_CODEC_VOLUME("Surround Playback Volume", 0x05, 0x0, HDA_OUTPUT),
2181        HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
2182        HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0a, 2, 0x0, HDA_OUTPUT),
2183        HDA_CODEC_VOLUME("Side Playback Volume", 0x06, 0x0, HDA_OUTPUT),
2184        { } /* end */
2185};
2186
2187static struct snd_kcontrol_new ad1988_6stack_mixers2[] = {
2188        HDA_BIND_MUTE("Front Playback Switch", 0x29, 2, HDA_INPUT),
2189        HDA_BIND_MUTE("Surround Playback Switch", 0x2a, 2, HDA_INPUT),
2190        HDA_BIND_MUTE_MONO("Center Playback Switch", 0x27, 1, 2, HDA_INPUT),
2191        HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x27, 2, 2, HDA_INPUT),
2192        HDA_BIND_MUTE("Side Playback Switch", 0x28, 2, HDA_INPUT),
2193        HDA_BIND_MUTE("Headphone Playback Switch", 0x22, 2, HDA_INPUT),
2194        HDA_BIND_MUTE("Mono Playback Switch", 0x1e, 2, HDA_INPUT),
2195
2196        HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x6, HDA_INPUT),
2197        HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x6, HDA_INPUT),
2198        HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x0, HDA_INPUT),
2199        HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x0, HDA_INPUT),
2200        HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x1, HDA_INPUT),
2201        HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x1, HDA_INPUT),
2202        HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x4, HDA_INPUT),
2203        HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x4, HDA_INPUT),
2204
2205        HDA_CODEC_VOLUME("Analog Mix Playback Volume", 0x21, 0x0, HDA_OUTPUT),
2206        HDA_CODEC_MUTE("Analog Mix Playback Switch", 0x21, 0x0, HDA_OUTPUT),
2207
2208        HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x39, 0x0, HDA_OUTPUT),
2209        HDA_CODEC_VOLUME("Mic Boost Volume", 0x3c, 0x0, HDA_OUTPUT),
2210
2211        { } /* end */
2212};
2213
2214static struct snd_kcontrol_new ad1988_6stack_fp_mixers[] = {
2215        HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
2216
2217        { } /* end */
2218};
2219
2220/* 3-stack mode */
2221static struct snd_kcontrol_new ad1988_3stack_mixers1[] = {
2222        HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT),
2223        HDA_CODEC_VOLUME("Surround Playback Volume", 0x0a, 0x0, HDA_OUTPUT),
2224        HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x05, 1, 0x0, HDA_OUTPUT),
2225        HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x05, 2, 0x0, HDA_OUTPUT),
2226        { } /* end */
2227};
2228
2229static struct snd_kcontrol_new ad1988_3stack_mixers1_rev2[] = {
2230        HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT),
2231        HDA_CODEC_VOLUME("Surround Playback Volume", 0x0a, 0x0, HDA_OUTPUT),
2232        HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x06, 1, 0x0, HDA_OUTPUT),
2233        HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x06, 2, 0x0, HDA_OUTPUT),
2234        { } /* end */
2235};
2236
2237static struct snd_kcontrol_new ad1988_3stack_mixers2[] = {
2238        HDA_BIND_MUTE("Front Playback Switch", 0x29, 2, HDA_INPUT),
2239        HDA_BIND_MUTE("Surround Playback Switch", 0x2c, 2, HDA_INPUT),
2240        HDA_BIND_MUTE_MONO("Center Playback Switch", 0x26, 1, 2, HDA_INPUT),
2241        HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x26, 2, 2, HDA_INPUT),
2242        HDA_BIND_MUTE("Headphone Playback Switch", 0x22, 2, HDA_INPUT),
2243        HDA_BIND_MUTE("Mono Playback Switch", 0x1e, 2, HDA_INPUT),
2244
2245        HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x6, HDA_INPUT),
2246        HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x6, HDA_INPUT),
2247        HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x0, HDA_INPUT),
2248        HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x0, HDA_INPUT),
2249        HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x1, HDA_INPUT),
2250        HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x1, HDA_INPUT),
2251        HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x4, HDA_INPUT),
2252        HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x4, HDA_INPUT),
2253
2254        HDA_CODEC_VOLUME("Analog Mix Playback Volume", 0x21, 0x0, HDA_OUTPUT),
2255        HDA_CODEC_MUTE("Analog Mix Playback Switch", 0x21, 0x0, HDA_OUTPUT),
2256
2257        HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x39, 0x0, HDA_OUTPUT),
2258        HDA_CODEC_VOLUME("Mic Boost Volume", 0x3c, 0x0, HDA_OUTPUT),
2259        {
2260                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2261                .name = "Channel Mode",
2262                .info = ad198x_ch_mode_info,
2263                .get = ad198x_ch_mode_get,
2264                .put = ad198x_ch_mode_put,
2265        },
2266
2267        { } /* end */
2268};
2269
2270/* laptop mode */
2271static struct snd_kcontrol_new ad1988_laptop_mixers[] = {
2272        HDA_CODEC_VOLUME("PCM Playback Volume", 0x04, 0x0, HDA_OUTPUT),
2273        HDA_CODEC_MUTE("PCM Playback Switch", 0x29, 0x0, HDA_INPUT),
2274        HDA_BIND_MUTE("Mono Playback Switch", 0x1e, 2, HDA_INPUT),
2275
2276        HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x6, HDA_INPUT),
2277        HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x6, HDA_INPUT),
2278        HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x0, HDA_INPUT),
2279        HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x0, HDA_INPUT),
2280        HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x1, HDA_INPUT),
2281        HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x1, HDA_INPUT),
2282
2283        HDA_CODEC_VOLUME("Analog Mix Playback Volume", 0x21, 0x0, HDA_OUTPUT),
2284        HDA_CODEC_MUTE("Analog Mix Playback Switch", 0x21, 0x0, HDA_OUTPUT),
2285
2286        HDA_CODEC_VOLUME("Mic Boost Volume", 0x39, 0x0, HDA_OUTPUT),
2287
2288        {
2289                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2290                .name = "External Amplifier",
2291                .subdevice = HDA_SUBDEV_NID_FLAG | 0x12,
2292                .info = ad198x_eapd_info,
2293                .get = ad198x_eapd_get,
2294                .put = ad198x_eapd_put,
2295                .private_value = 0x12, /* port-D */
2296        },
2297
2298        { } /* end */
2299};
2300
2301/* capture */
2302static struct snd_kcontrol_new ad1988_capture_mixers[] = {
2303        HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
2304        HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
2305        HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT),
2306        HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x0d, 0x0, HDA_OUTPUT),
2307        HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x0e, 0x0, HDA_OUTPUT),
2308        HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x0e, 0x0, HDA_OUTPUT),
2309        {
2310                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2311                /* The multiple "Capture Source" controls confuse alsamixer
2312                 * So call somewhat different..
2313                 */
2314                /* .name = "Capture Source", */
2315                .name = "Input Source",
2316                .count = 3,
2317                .info = ad198x_mux_enum_info,
2318                .get = ad198x_mux_enum_get,
2319                .put = ad198x_mux_enum_put,
2320        },
2321        { } /* end */
2322};
2323
2324static int ad1988_spdif_playback_source_info(struct snd_kcontrol *kcontrol,
2325                                             struct snd_ctl_elem_info *uinfo)
2326{
2327        static char *texts[] = {
2328                "PCM", "ADC1", "ADC2", "ADC3"
2329        };
2330        uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2331        uinfo->count = 1;
2332        uinfo->value.enumerated.items = 4;
2333        if (uinfo->value.enumerated.item >= 4)
2334                uinfo->value.enumerated.item = 3;
2335        strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2336        return 0;
2337}
2338
2339static int ad1988_spdif_playback_source_get(struct snd_kcontrol *kcontrol,
2340                                            struct snd_ctl_elem_value *ucontrol)
2341{
2342        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2343        unsigned int sel;
2344
2345        sel = snd_hda_codec_read(codec, 0x1d, 0, AC_VERB_GET_AMP_GAIN_MUTE,
2346                                 AC_AMP_GET_INPUT);
2347        if (!(sel & 0x80))
2348                ucontrol->value.enumerated.item[0] = 0;
2349        else {
2350                sel = snd_hda_codec_read(codec, 0x0b, 0,
2351                                         AC_VERB_GET_CONNECT_SEL, 0);
2352                if (sel < 3)
2353                        sel++;
2354                else
2355                        sel = 0;
2356                ucontrol->value.enumerated.item[0] = sel;
2357        }
2358        return 0;
2359}
2360
2361static int ad1988_spdif_playback_source_put(struct snd_kcontrol *kcontrol,
2362                                            struct snd_ctl_elem_value *ucontrol)
2363{
2364        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2365        unsigned int val, sel;
2366        int change;
2367
2368        val = ucontrol->value.enumerated.item[0];
2369        if (val > 3)
2370                return -EINVAL;
2371        if (!val) {
2372                sel = snd_hda_codec_read(codec, 0x1d, 0,
2373                                         AC_VERB_GET_AMP_GAIN_MUTE,
2374                                         AC_AMP_GET_INPUT);
2375                change = sel & 0x80;
2376                if (change) {
2377                        snd_hda_codec_write_cache(codec, 0x1d, 0,
2378                                                  AC_VERB_SET_AMP_GAIN_MUTE,
2379                                                  AMP_IN_UNMUTE(0));
2380                        snd_hda_codec_write_cache(codec, 0x1d, 0,
2381                                                  AC_VERB_SET_AMP_GAIN_MUTE,
2382                                                  AMP_IN_MUTE(1));
2383                }
2384        } else {
2385                sel = snd_hda_codec_read(codec, 0x1d, 0,
2386                                         AC_VERB_GET_AMP_GAIN_MUTE,
2387                                         AC_AMP_GET_INPUT | 0x01);
2388                change = sel & 0x80;
2389                if (change) {
2390                        snd_hda_codec_write_cache(codec, 0x1d, 0,
2391                                                  AC_VERB_SET_AMP_GAIN_MUTE,
2392                                                  AMP_IN_MUTE(0));
2393                        snd_hda_codec_write_cache(codec, 0x1d, 0,
2394                                                  AC_VERB_SET_AMP_GAIN_MUTE,
2395                                                  AMP_IN_UNMUTE(1));
2396                }
2397                sel = snd_hda_codec_read(codec, 0x0b, 0,
2398                                         AC_VERB_GET_CONNECT_SEL, 0) + 1;
2399                change |= sel != val;
2400                if (change)
2401                        snd_hda_codec_write_cache(codec, 0x0b, 0,
2402                                                  AC_VERB_SET_CONNECT_SEL,
2403                                                  val - 1);
2404        }
2405        return change;
2406}
2407
2408static struct snd_kcontrol_new ad1988_spdif_out_mixers[] = {
2409        HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
2410        {
2411                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2412                .name = "IEC958 Playback Source",
2413                .subdevice = HDA_SUBDEV_NID_FLAG | 0x1b,
2414                .info = ad1988_spdif_playback_source_info,
2415                .get = ad1988_spdif_playback_source_get,
2416                .put = ad1988_spdif_playback_source_put,
2417        },
2418        { } /* end */
2419};
2420
2421static struct snd_kcontrol_new ad1988_spdif_in_mixers[] = {
2422        HDA_CODEC_VOLUME("IEC958 Capture Volume", 0x1c, 0x0, HDA_INPUT),
2423        { } /* end */
2424};
2425
2426static struct snd_kcontrol_new ad1989_spdif_out_mixers[] = {
2427        HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
2428        HDA_CODEC_VOLUME("HDMI Playback Volume", 0x1d, 0x0, HDA_OUTPUT),
2429        { } /* end */
2430};
2431
2432/*
2433 * initialization verbs
2434 */
2435
2436/*
2437 * for 6-stack (+dig)
2438 */
2439static struct hda_verb ad1988_6stack_init_verbs[] = {
2440        /* Front, Surround, CLFE, side DAC; unmute as default */
2441        {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2442        {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2443        {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2444        {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2445        /* Port-A front headphon path */
2446        {0x37, AC_VERB_SET_CONNECT_SEL, 0x01}, /* DAC1:04h */
2447        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2448        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2449        {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2450        {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2451        /* Port-D line-out path */
2452        {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2453        {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2454        {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2455        {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2456        /* Port-F surround path */
2457        {0x2a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2458        {0x2a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2459        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2460        {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2461        /* Port-G CLFE path */
2462        {0x27, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2463        {0x27, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2464        {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2465        {0x24, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2466        /* Port-H side path */
2467        {0x28, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2468        {0x28, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2469        {0x25, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2470        {0x25, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2471        /* Mono out path */
2472        {0x36, AC_VERB_SET_CONNECT_SEL, 0x1}, /* DAC1:04h */
2473        {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2474        {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2475        {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2476        {0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb01f}, /* unmute, 0dB */
2477        /* Port-B front mic-in path */
2478        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2479        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2480        {0x39, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2481        /* Port-C line-in path */
2482        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2483        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2484        {0x3a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2485        {0x33, AC_VERB_SET_CONNECT_SEL, 0x0},
2486        /* Port-E mic-in path */
2487        {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2488        {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2489        {0x3c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2490        {0x34, AC_VERB_SET_CONNECT_SEL, 0x0},
2491        /* Analog CD Input */
2492        {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2493        /* Analog Mix output amp */
2494        {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x1f}, /* 0dB */
2495
2496        { }
2497};
2498
2499static struct hda_verb ad1988_6stack_fp_init_verbs[] = {
2500        /* Headphone; unmute as default */
2501        {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2502        /* Port-A front headphon path */
2503        {0x37, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC0:03h */
2504        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2505        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2506        {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2507        {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2508
2509        { }
2510};
2511
2512static struct hda_verb ad1988_capture_init_verbs[] = {
2513        /* mute analog mix */
2514        {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2515        {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2516        {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2517        {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2518        {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2519        {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
2520        {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2521        {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2522        /* select ADCs - front-mic */
2523        {0x0c, AC_VERB_SET_CONNECT_SEL, 0x1},
2524        {0x0d, AC_VERB_SET_CONNECT_SEL, 0x1},
2525        {0x0e, AC_VERB_SET_CONNECT_SEL, 0x1},
2526
2527        { }
2528};
2529
2530static struct hda_verb ad1988_spdif_init_verbs[] = {
2531        /* SPDIF out sel */
2532        {0x02, AC_VERB_SET_CONNECT_SEL, 0x0}, /* PCM */
2533        {0x0b, AC_VERB_SET_CONNECT_SEL, 0x0}, /* ADC1 */
2534        {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2535        {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2536        /* SPDIF out pin */
2537        {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */
2538
2539        { }
2540};
2541
2542static struct hda_verb ad1988_spdif_in_init_verbs[] = {
2543        /* unmute SPDIF input pin */
2544        {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2545        { }
2546};
2547
2548/* AD1989 has no ADC -> SPDIF route */
2549static struct hda_verb ad1989_spdif_init_verbs[] = {
2550        /* SPDIF-1 out pin */
2551        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2552        {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */
2553        /* SPDIF-2/HDMI out pin */
2554        {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2555        {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */
2556        { }
2557};
2558
2559/*
2560 * verbs for 3stack (+dig)
2561 */
2562static struct hda_verb ad1988_3stack_ch2_init[] = {
2563        /* set port-C to line-in */
2564        { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2565        { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2566        /* set port-E to mic-in */
2567        { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2568        { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2569        { } /* end */
2570};
2571
2572static struct hda_verb ad1988_3stack_ch6_init[] = {
2573        /* set port-C to surround out */
2574        { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2575        { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2576        /* set port-E to CLFE out */
2577        { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2578        { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2579        { } /* end */
2580};
2581
2582static struct hda_channel_mode ad1988_3stack_modes[2] = {
2583        { 2, ad1988_3stack_ch2_init },
2584        { 6, ad1988_3stack_ch6_init },
2585};
2586
2587static struct hda_verb ad1988_3stack_init_verbs[] = {
2588        /* Front, Surround, CLFE, side DAC; unmute as default */
2589        {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2590        {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2591        {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2592        {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2593        /* Port-A front headphon path */
2594        {0x37, AC_VERB_SET_CONNECT_SEL, 0x01}, /* DAC1:04h */
2595        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2596        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2597        {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2598        {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2599        /* Port-D line-out path */
2600        {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2601        {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2602        {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2603        {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2604        /* Mono out path */
2605        {0x36, AC_VERB_SET_CONNECT_SEL, 0x1}, /* DAC1:04h */
2606        {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2607        {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2608        {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2609        {0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb01f}, /* unmute, 0dB */
2610        /* Port-B front mic-in path */
2611        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2612        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2613        {0x39, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2614        /* Port-C line-in/surround path - 6ch mode as default */
2615        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2616        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2617        {0x3a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2618        {0x31, AC_VERB_SET_CONNECT_SEL, 0x0}, /* output sel: DAC 0x05 */
2619        {0x33, AC_VERB_SET_CONNECT_SEL, 0x0},
2620        /* Port-E mic-in/CLFE path - 6ch mode as default */
2621        {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2622        {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2623        {0x3c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2624        {0x32, AC_VERB_SET_CONNECT_SEL, 0x1}, /* output sel: DAC 0x0a */
2625        {0x34, AC_VERB_SET_CONNECT_SEL, 0x0},
2626        /* mute analog mix */
2627        {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2628        {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2629        {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2630        {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2631        {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2632        {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
2633        {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2634        {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2635        /* select ADCs - front-mic */
2636        {0x0c, AC_VERB_SET_CONNECT_SEL, 0x1},
2637        {0x0d, AC_VERB_SET_CONNECT_SEL, 0x1},
2638        {0x0e, AC_VERB_SET_CONNECT_SEL, 0x1},
2639        /* Analog Mix output amp */
2640        {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x1f}, /* 0dB */
2641        { }
2642};
2643
2644/*
2645 * verbs for laptop mode (+dig)
2646 */
2647static struct hda_verb ad1988_laptop_hp_on[] = {
2648        /* unmute port-A and mute port-D */
2649        { 0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2650        { 0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2651        { } /* end */
2652};
2653static struct hda_verb ad1988_laptop_hp_off[] = {
2654        /* mute port-A and unmute port-D */
2655        { 0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2656        { 0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2657        { } /* end */
2658};
2659
2660#define AD1988_HP_EVENT 0x01
2661
2662static struct hda_verb ad1988_laptop_init_verbs[] = {
2663        /* Front, Surround, CLFE, side DAC; unmute as default */
2664        {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2665        {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2666        {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2667        {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2668        /* Port-A front headphon path */
2669        {0x37, AC_VERB_SET_CONNECT_SEL, 0x01}, /* DAC1:04h */
2670        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2671        {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2672        {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2673        {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2674        /* unsolicited event for pin-sense */
2675        {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1988_HP_EVENT },
2676        /* Port-D line-out path + EAPD */
2677        {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2678        {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2679        {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2680        {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2681        {0x12, AC_VERB_SET_EAPD_BTLENABLE, 0x00}, /* EAPD-off */
2682        /* Mono out path */
2683        {0x36, AC_VERB_SET_CONNECT_SEL, 0x1}, /* DAC1:04h */
2684        {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2685        {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2686        {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2687        {0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb01f}, /* unmute, 0dB */
2688        /* Port-B mic-in path */
2689        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2690        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2691        {0x39, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2692        /* Port-C docking station - try to output */
2693        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2694        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2695        {0x3a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2696        {0x33, AC_VERB_SET_CONNECT_SEL, 0x0},
2697        /* mute analog mix */
2698        {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2699        {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2700        {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2701        {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2702        {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2703        {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
2704        {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2705        {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2706        /* select ADCs - mic */
2707        {0x0c, AC_VERB_SET_CONNECT_SEL, 0x1},
2708        {0x0d, AC_VERB_SET_CONNECT_SEL, 0x1},
2709        {0x0e, AC_VERB_SET_CONNECT_SEL, 0x1},
2710        /* Analog Mix output amp */
2711        {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x1f}, /* 0dB */
2712        { }
2713};
2714
2715static void ad1988_laptop_unsol_event(struct hda_codec *codec, unsigned int res)
2716{
2717        if ((res >> 26) != AD1988_HP_EVENT)
2718                return;
2719        if (snd_hda_jack_detect(codec, 0x11))
2720                snd_hda_sequence_write(codec, ad1988_laptop_hp_on);
2721        else
2722                snd_hda_sequence_write(codec, ad1988_laptop_hp_off);
2723} 
2724
2725#ifdef CONFIG_SND_HDA_POWER_SAVE
2726static struct hda_amp_list ad1988_loopbacks[] = {
2727        { 0x20, HDA_INPUT, 0 }, /* Front Mic */
2728        { 0x20, HDA_INPUT, 1 }, /* Line */
2729        { 0x20, HDA_INPUT, 4 }, /* Mic */
2730        { 0x20, HDA_INPUT, 6 }, /* CD */
2731        { } /* end */
2732};
2733#endif
2734
2735/*
2736 * Automatic parse of I/O pins from the BIOS configuration
2737 */
2738
2739enum {
2740        AD_CTL_WIDGET_VOL,
2741        AD_CTL_WIDGET_MUTE,
2742        AD_CTL_BIND_MUTE,
2743};
2744static struct snd_kcontrol_new ad1988_control_templates[] = {
2745        HDA_CODEC_VOLUME(NULL, 0, 0, 0),
2746        HDA_CODEC_MUTE(NULL, 0, 0, 0),
2747        HDA_BIND_MUTE(NULL, 0, 0, 0),
2748};
2749
2750/* add dynamic controls */
2751static int add_control(struct ad198x_spec *spec, int type, const char *name,
2752                       unsigned long val)
2753{
2754        struct snd_kcontrol_new *knew;
2755
2756        snd_array_init(&spec->kctls, sizeof(*knew), 32);
2757        knew = snd_array_new(&spec->kctls);
2758        if (!knew)
2759                return -ENOMEM;
2760        *knew = ad1988_control_templates[type];
2761        knew->name = kstrdup(name, GFP_KERNEL);
2762        if (! knew->name)
2763                return -ENOMEM;
2764        if (get_amp_nid_(val))
2765                knew->subdevice = HDA_SUBDEV_AMP_FLAG;
2766        knew->private_value = val;
2767        return 0;
2768}
2769
2770#define AD1988_PIN_CD_NID               0x18
2771#define AD1988_PIN_BEEP_NID             0x10
2772
2773static hda_nid_t ad1988_mixer_nids[8] = {
2774        /* A     B     C     D     E     F     G     H */
2775        0x22, 0x2b, 0x2c, 0x29, 0x26, 0x2a, 0x27, 0x28
2776};
2777
2778static inline hda_nid_t ad1988_idx_to_dac(struct hda_codec *codec, int idx)
2779{
2780        static hda_nid_t idx_to_dac[8] = {
2781                /* A     B     C     D     E     F     G     H */
2782                0x04, 0x06, 0x05, 0x04, 0x0a, 0x06, 0x05, 0x0a
2783        };
2784        static hda_nid_t idx_to_dac_rev2[8] = {
2785                /* A     B     C     D     E     F     G     H */
2786                0x04, 0x05, 0x0a, 0x04, 0x06, 0x05, 0x0a, 0x06
2787        };
2788        if (is_rev2(codec))
2789                return idx_to_dac_rev2[idx];
2790        else
2791                return idx_to_dac[idx];
2792}
2793
2794static hda_nid_t ad1988_boost_nids[8] = {
2795        0x38, 0x39, 0x3a, 0x3d, 0x3c, 0x3b, 0, 0
2796};
2797
2798static int ad1988_pin_idx(hda_nid_t nid)
2799{
2800        static hda_nid_t ad1988_io_pins[8] = {
2801                0x11, 0x14, 0x15, 0x12, 0x17, 0x16, 0x24, 0x25
2802        };
2803        int i;
2804        for (i = 0; i < ARRAY_SIZE(ad1988_io_pins); i++)
2805                if (ad1988_io_pins[i] == nid)
2806                        return i;
2807        return 0; /* should be -1 */
2808}
2809
2810static int ad1988_pin_to_loopback_idx(hda_nid_t nid)
2811{
2812        static int loopback_idx[8] = {
2813                2, 0, 1, 3, 4, 5, 1, 4
2814        };
2815        switch (nid) {
2816        case AD1988_PIN_CD_NID:
2817                return 6;
2818        default:
2819                return loopback_idx[ad1988_pin_idx(nid)];
2820        }
2821}
2822
2823static int ad1988_pin_to_adc_idx(hda_nid_t nid)
2824{
2825        static int adc_idx[8] = {
2826                0, 1, 2, 8, 4, 3, 6, 7
2827        };
2828        switch (nid) {
2829        case AD1988_PIN_CD_NID:
2830                return 5;
2831        default:
2832                return adc_idx[ad1988_pin_idx(nid)];
2833        }
2834}
2835
2836/* fill in the dac_nids table from the parsed pin configuration */
2837static int ad1988_auto_fill_dac_nids(struct hda_codec *codec,
2838                                     const struct auto_pin_cfg *cfg)
2839{
2840        struct ad198x_spec *spec = codec->spec;
2841        int i, idx;
2842
2843        spec->multiout.dac_nids = spec->private_dac_nids;
2844
2845        /* check the pins hardwired to audio widget */
2846        for (i = 0; i < cfg->line_outs; i++) {
2847                idx = ad1988_pin_idx(cfg->line_out_pins[i]);
2848                spec->multiout.dac_nids[i] = ad1988_idx_to_dac(codec, idx);
2849        }
2850        spec->multiout.num_dacs = cfg->line_outs;
2851        return 0;
2852}
2853
2854/* add playback controls from the parsed DAC table */
2855static int ad1988_auto_create_multi_out_ctls(struct ad198x_spec *spec,
2856                                             const struct auto_pin_cfg *cfg)
2857{
2858        char name[32];
2859        static const char * const chname[4] = {
2860                "Front", "Surround", NULL /*CLFE*/, "Side"
2861        };
2862        hda_nid_t nid;
2863        int i, err;
2864
2865        for (i = 0; i < cfg->line_outs; i++) {
2866                hda_nid_t dac = spec->multiout.dac_nids[i];
2867                if (! dac)
2868                        continue;
2869                nid = ad1988_mixer_nids[ad1988_pin_idx(cfg->line_out_pins[i])];
2870                if (i == 2) {
2871                        /* Center/LFE */
2872                        err = add_control(spec, AD_CTL_WIDGET_VOL,
2873                                          "Center Playback Volume",
2874                                          HDA_COMPOSE_AMP_VAL(dac, 1, 0, HDA_OUTPUT));
2875                        if (err < 0)
2876                                return err;
2877                        err = add_control(spec, AD_CTL_WIDGET_VOL,
2878                                          "LFE Playback Volume",
2879                                          HDA_COMPOSE_AMP_VAL(dac, 2, 0, HDA_OUTPUT));
2880                        if (err < 0)
2881                                return err;
2882                        err = add_control(spec, AD_CTL_BIND_MUTE,
2883                                          "Center Playback Switch",
2884                                          HDA_COMPOSE_AMP_VAL(nid, 1, 2, HDA_INPUT));
2885                        if (err < 0)
2886                                return err;
2887                        err = add_control(spec, AD_CTL_BIND_MUTE,
2888                                          "LFE Playback Switch",
2889                                          HDA_COMPOSE_AMP_VAL(nid, 2, 2, HDA_INPUT));
2890                        if (err < 0)
2891                                return err;
2892                } else {
2893                        sprintf(name, "%s Playback Volume", chname[i]);
2894                        err = add_control(spec, AD_CTL_WIDGET_VOL, name,
2895                                          HDA_COMPOSE_AMP_VAL(dac, 3, 0, HDA_OUTPUT));
2896                        if (err < 0)
2897                                return err;
2898                        sprintf(name, "%s Playback Switch", chname[i]);
2899                        err = add_control(spec, AD_CTL_BIND_MUTE, name,
2900                                          HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
2901                        if (err < 0)
2902                                return err;
2903                }
2904        }
2905        return 0;
2906}
2907
2908/* add playback controls for speaker and HP outputs */
2909static int ad1988_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin,
2910                                        const char *pfx)
2911{
2912        struct ad198x_spec *spec = codec->spec;
2913        hda_nid_t nid;
2914        int i, idx, err;
2915        char name[32];
2916
2917        if (! pin)
2918                return 0;
2919
2920        idx = ad1988_pin_idx(pin);
2921        nid = ad1988_idx_to_dac(codec, idx);
2922        /* check whether the corresponding DAC was already taken */
2923        for (i = 0; i < spec->autocfg.line_outs; i++) {
2924                hda_nid_t pin = spec->autocfg.line_out_pins[i];
2925                hda_nid_t dac = ad1988_idx_to_dac(codec, ad1988_pin_idx(pin));
2926                if (dac == nid)
2927                        break;
2928        }
2929        if (i >= spec->autocfg.line_outs) {
2930                /* specify the DAC as the extra output */
2931                if (!spec->multiout.hp_nid)
2932                        spec->multiout.hp_nid = nid;
2933                else
2934                        spec->multiout.extra_out_nid[0] = nid;
2935                /* control HP volume/switch on the output mixer amp */
2936                sprintf(name, "%s Playback Volume", pfx);
2937                err = add_control(spec, AD_CTL_WIDGET_VOL, name,
2938                                  HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
2939                if (err < 0)
2940                        return err;
2941        }
2942        nid = ad1988_mixer_nids[idx];
2943        sprintf(name, "%s Playback Switch", pfx);
2944        if ((err = add_control(spec, AD_CTL_BIND_MUTE, name,
2945                               HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT))) < 0)
2946                return err;
2947        return 0;
2948}
2949
2950/* create input playback/capture controls for the given pin */
2951static int new_analog_input(struct ad198x_spec *spec, hda_nid_t pin,
2952                            const char *ctlname, int ctlidx, int boost)
2953{
2954        char name[32];
2955        int err, idx;
2956
2957        sprintf(name, "%s Playback Volume", ctlname);
2958        idx = ad1988_pin_to_loopback_idx(pin);
2959        if ((err = add_control(spec, AD_CTL_WIDGET_VOL, name,
2960                               HDA_COMPOSE_AMP_VAL(0x20, 3, idx, HDA_INPUT))) < 0)
2961                return err;
2962        sprintf(name, "%s Playback Switch", ctlname);
2963        if ((err = add_control(spec, AD_CTL_WIDGET_MUTE, name,
2964                               HDA_COMPOSE_AMP_VAL(0x20, 3, idx, HDA_INPUT))) < 0)
2965                return err;
2966        if (boost) {
2967                hda_nid_t bnid;
2968                idx = ad1988_pin_idx(pin);
2969                bnid = ad1988_boost_nids[idx];
2970                if (bnid) {
2971                        sprintf(name, "%s Boost Volume", ctlname);
2972                        return add_control(spec, AD_CTL_WIDGET_VOL, name,
2973                                           HDA_COMPOSE_AMP_VAL(bnid, 3, idx, HDA_OUTPUT));
2974
2975                }
2976        }
2977        return 0;
2978}
2979
2980/* create playback/capture controls for input pins */
2981static int ad1988_auto_create_analog_input_ctls(struct hda_codec *codec,
2982                                                const struct auto_pin_cfg *cfg)
2983{
2984        struct ad198x_spec *spec = codec->spec;
2985        struct hda_input_mux *imux = &spec->private_imux;
2986        int i, err, type, type_idx;
2987
2988        for (i = 0; i < cfg->num_inputs; i++) {
2989                const char *label;
2990                type = cfg->inputs[i].type;
2991                label = hda_get_autocfg_input_label(codec, cfg, i);
2992                snd_hda_add_imux_item(imux, label,
2993                                      ad1988_pin_to_adc_idx(cfg->inputs[i].pin),
2994                                      &type_idx);
2995                err = new_analog_input(spec, cfg->inputs[i].pin,
2996                                       label, type_idx,
2997                                       type == AUTO_PIN_MIC);
2998                if (err < 0)
2999                        return err;
3000        }
3001        snd_hda_add_imux_item(imux, "Mix", 9, NULL);
3002
3003        if ((err = add_control(spec, AD_CTL_WIDGET_VOL,
3004                               "Analog Mix Playback Volume",
3005                               HDA_COMPOSE_AMP_VAL(0x21, 3, 0x0, HDA_OUTPUT))) < 0)
3006                return err;
3007        if ((err = add_control(spec, AD_CTL_WIDGET_MUTE,
3008                               "Analog Mix Playback Switch",
3009                               HDA_COMPOSE_AMP_VAL(0x21, 3, 0x0, HDA_OUTPUT))) < 0)
3010                return err;
3011
3012        return 0;
3013}
3014
3015static void ad1988_auto_set_output_and_unmute(struct hda_codec *codec,
3016                                              hda_nid_t nid, int pin_type,
3017                                              int dac_idx)
3018{
3019        /* set as output */
3020        snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
3021        snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
3022        switch (nid) {
3023        case 0x11: /* port-A - DAC 04 */
3024                snd_hda_codec_write(codec, 0x37, 0, AC_VERB_SET_CONNECT_SEL, 0x01);
3025                break;
3026        case 0x14: /* port-B - DAC 06 */
3027                snd_hda_codec_write(codec, 0x30, 0, AC_VERB_SET_CONNECT_SEL, 0x02);
3028                break;
3029        case 0x15: /* port-C - DAC 05 */
3030                snd_hda_codec_write(codec, 0x31, 0, AC_VERB_SET_CONNECT_SEL, 0x00);
3031                break;
3032        case 0x17: /* port-E - DAC 0a */
3033                snd_hda_codec_write(codec, 0x32, 0, AC_VERB_SET_CONNECT_SEL, 0x01);
3034                break;
3035        case 0x13: /* mono - DAC 04 */
3036                snd_hda_codec_write(codec, 0x36, 0, AC_VERB_SET_CONNECT_SEL, 0x01);
3037                break;
3038        }
3039}
3040
3041static void ad1988_auto_init_multi_out(struct hda_codec *codec)
3042{
3043        struct ad198x_spec *spec = codec->spec;
3044        int i;
3045
3046        for (i = 0; i < spec->autocfg.line_outs; i++) {
3047                hda_nid_t nid = spec->autocfg.line_out_pins[i];
3048                ad1988_auto_set_output_and_unmute(codec, nid, PIN_OUT, i);
3049        }
3050}
3051
3052static void ad1988_auto_init_extra_out(struct hda_codec *codec)
3053{
3054        struct ad198x_spec *spec = codec->spec;
3055        hda_nid_t pin;
3056
3057        pin = spec->autocfg.speaker_pins[0];
3058        if (pin) /* connect to front */
3059                ad1988_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
3060        pin = spec->autocfg.hp_pins[0];
3061        if (pin) /* connect to front */
3062                ad1988_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
3063}
3064
3065static void ad1988_auto_init_analog_input(struct hda_codec *codec)
3066{
3067        struct ad198x_spec *spec = codec->spec;
3068        const struct auto_pin_cfg *cfg = &spec->autocfg;
3069        int i, idx;
3070
3071        for (i = 0; i < cfg->num_inputs; i++) {
3072                hda_nid_t nid = cfg->inputs[i].pin;
3073                switch (nid) {
3074                case 0x15: /* port-C */
3075                        snd_hda_codec_write(codec, 0x33, 0, AC_VERB_SET_CONNECT_SEL, 0x0);
3076                        break;
3077                case 0x17: /* port-E */
3078                        snd_hda_codec_write(codec, 0x34, 0, AC_VERB_SET_CONNECT_SEL, 0x0);
3079                        break;
3080                }
3081                snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3082                                    i == AUTO_PIN_MIC ? PIN_VREF80 : PIN_IN);
3083                if (nid != AD1988_PIN_CD_NID)
3084                        snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
3085                                            AMP_OUT_MUTE);
3086                idx = ad1988_pin_idx(nid);
3087                if (ad1988_boost_nids[idx])
3088                        snd_hda_codec_write(codec, ad1988_boost_nids[idx], 0,
3089                                            AC_VERB_SET_AMP_GAIN_MUTE,
3090                                            AMP_OUT_ZERO);
3091        }
3092}
3093
3094/* parse the BIOS configuration and set up the alc_spec */
3095/* return 1 if successful, 0 if the proper config is not found, or a negative error code */
3096static int ad1988_parse_auto_config(struct hda_codec *codec)
3097{
3098        struct ad198x_spec *spec = codec->spec;
3099        int err;
3100
3101        if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL)) < 0)
3102                return err;
3103        if ((err = ad1988_auto_fill_dac_nids(codec, &spec->autocfg)) < 0)
3104                return err;
3105        if (! spec->autocfg.line_outs)
3106                return 0; /* can't find valid BIOS pin config */
3107        if ((err = ad1988_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0 ||
3108            (err = ad1988_auto_create_extra_out(codec,
3109                                                spec->autocfg.speaker_pins[0],
3110                                                "Speaker")) < 0 ||
3111            (err = ad1988_auto_create_extra_out(codec, spec->autocfg.hp_pins[0],
3112                                                "Headphone")) < 0 ||
3113            (err = ad1988_auto_create_analog_input_ctls(codec, &spec->autocfg)) < 0)
3114                return err;
3115
3116        spec->multiout.max_channels = spec->multiout.num_dacs * 2;
3117
3118        if (spec->autocfg.dig_outs)
3119                spec->multiout.dig_out_nid = AD1988_SPDIF_OUT;
3120        if (spec->autocfg.dig_in_pin)
3121                spec->dig_in_nid = AD1988_SPDIF_IN;
3122
3123        if (spec->kctls.list)
3124                spec->mixers[spec->num_mixers++] = spec->kctls.list;
3125
3126        spec->init_verbs[spec->num_init_verbs++] = ad1988_6stack_init_verbs;
3127
3128        spec->input_mux = &spec->private_imux;
3129
3130        return 1;
3131}
3132
3133/* init callback for auto-configuration model -- overriding the default init */
3134static int ad1988_auto_init(struct hda_codec *codec)
3135{
3136        ad198x_init(codec);
3137        ad1988_auto_init_multi_out(codec);
3138        ad1988_auto_init_extra_out(codec);
3139        ad1988_auto_init_analog_input(codec);
3140        return 0;
3141}
3142
3143/*
3144 */
3145
3146static const char * const ad1988_models[AD1988_MODEL_LAST] = {
3147        [AD1988_6STACK]         = "6stack",
3148        [AD1988_6STACK_DIG]     = "6stack-dig",
3149        [AD1988_6STACK_DIG_FP]  = "6stack-dig-fp",
3150        [AD1988_3STACK]         = "3stack",
3151        [AD1988_3STACK_DIG]     = "3stack-dig",
3152        [AD1988_LAPTOP]         = "laptop",
3153        [AD1988_LAPTOP_DIG]     = "laptop-dig",
3154        [AD1988_AUTO]           = "auto",
3155};
3156
3157static struct snd_pci_quirk ad1988_cfg_tbl[] = {
3158        SND_PCI_QUIRK(0x1043, 0x81ec, "Asus P5B-DLX", AD1988_6STACK_DIG),
3159        SND_PCI_QUIRK(0x1043, 0x81f6, "Asus M2N-SLI", AD1988_6STACK_DIG),
3160        SND_PCI_QUIRK(0x1043, 0x8277, "Asus P5K-E/WIFI-AP", AD1988_6STACK_DIG),
3161        SND_PCI_QUIRK(0x1043, 0x8311, "Asus P5Q-Premium/Pro", AD1988_6STACK_DIG),
3162        {}
3163};
3164
3165static int patch_ad1988(struct hda_codec *codec)
3166{
3167        struct ad198x_spec *spec;
3168        int err, board_config;
3169
3170        spec = kzalloc(sizeof(*spec), GFP_KERNEL);
3171        if (spec == NULL)
3172                return -ENOMEM;
3173
3174        codec->spec = spec;
3175
3176        if (is_rev2(codec))
3177                snd_printk(KERN_INFO "patch_analog: AD1988A rev.2 is detected, enable workarounds\n");
3178
3179        board_config = snd_hda_check_board_config(codec, AD1988_MODEL_LAST,
3180                                                  ad1988_models, ad1988_cfg_tbl);
3181        if (board_config < 0) {
3182                printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
3183                       codec->chip_name);
3184                board_config = AD1988_AUTO;
3185        }
3186
3187        if (board_config == AD1988_AUTO) {
3188                /* automatic parse from the BIOS config */
3189                err = ad1988_parse_auto_config(codec);
3190                if (err < 0) {
3191                        ad198x_free(codec);
3192                        return err;
3193                } else if (! err) {
3194                        printk(KERN_INFO "hda_codec: Cannot set up configuration from BIOS.  Using 6-stack mode...\n");
3195                        board_config = AD1988_6STACK;
3196                }
3197        }
3198
3199        err = snd_hda_attach_beep_device(codec, 0x10);
3200        if (err < 0) {
3201                ad198x_free(codec);
3202                return err;
3203        }
3204        set_beep_amp(spec, 0x10, 0, HDA_OUTPUT);
3205
3206        switch (board_config) {
3207        case AD1988_6STACK:
3208        case AD1988_6STACK_DIG:
3209        case AD1988_6STACK_DIG_FP:
3210                spec->multiout.max_channels = 8;
3211                spec->multiout.num_dacs = 4;
3212                if (is_rev2(codec))
3213                        spec->multiout.dac_nids = ad1988_6stack_dac_nids_rev2;
3214                else
3215                        spec->multiout.dac_nids = ad1988_6stack_dac_nids;
3216                spec->input_mux = &ad1988_6stack_capture_source;
3217                spec->num_mixers = 2;
3218                if (is_rev2(codec))
3219                        spec->mixers[0] = ad1988_6stack_mixers1_rev2;
3220                else
3221                        spec->mixers[0] = ad1988_6stack_mixers1;
3222                spec->mixers[1] = ad1988_6stack_mixers2;
3223                spec->num_init_verbs = 1;
3224                spec->init_verbs[0] = ad1988_6stack_init_verbs;
3225                if (board_config == AD1988_6STACK_DIG_FP) {
3226                        spec->num_mixers++;
3227                        spec->mixers[2] = ad1988_6stack_fp_mixers;
3228                        spec->num_init_verbs++;
3229                        spec->init_verbs[1] = ad1988_6stack_fp_init_verbs;
3230                        spec->slave_vols = ad1988_6stack_fp_slave_vols;
3231                        spec->slave_sws = ad1988_6stack_fp_slave_sws;
3232                        spec->alt_dac_nid = ad1988_alt_dac_nid;
3233                        spec->stream_analog_alt_playback =
3234                                &ad198x_pcm_analog_alt_playback;
3235                }
3236                if ((board_config == AD1988_6STACK_DIG) ||
3237                        (board_config == AD1988_6STACK_DIG_FP)) {
3238                        spec->multiout.dig_out_nid = AD1988_SPDIF_OUT;
3239                        spec->dig_in_nid = AD1988_SPDIF_IN;
3240                }
3241                break;
3242        case AD1988_3STACK:
3243        case AD1988_3STACK_DIG:
3244                spec->multiout.max_channels = 6;
3245                spec->multiout.num_dacs = 3;
3246                if (is_rev2(codec))
3247                        spec->multiout.dac_nids = ad1988_3stack_dac_nids_rev2;
3248                else
3249                        spec->multiout.dac_nids = ad1988_3stack_dac_nids;
3250                spec->input_mux = &ad1988_6stack_capture_source;
3251                spec->channel_mode = ad1988_3stack_modes;
3252                spec->num_channel_mode = ARRAY_SIZE(ad1988_3stack_modes);
3253                spec->num_mixers = 2;
3254                if (is_rev2(codec))
3255                        spec->mixers[0] = ad1988_3stack_mixers1_rev2;
3256                else
3257                        spec->mixers[0] = ad1988_3stack_mixers1;
3258                spec->mixers[1] = ad1988_3stack_mixers2;
3259                spec->num_init_verbs = 1;
3260                spec->init_verbs[0] = ad1988_3stack_init_verbs;
3261                if (board_config == AD1988_3STACK_DIG)
3262                        spec->multiout.dig_out_nid = AD1988_SPDIF_OUT;
3263                break;
3264        case AD1988_LAPTOP:
3265        case AD1988_LAPTOP_DIG:
3266                spec->multiout.max_channels = 2;
3267                spec->multiout.num_dacs = 1;
3268                spec->multiout.dac_nids = ad1988_3stack_dac_nids;
3269                spec->input_mux = &ad1988_laptop_capture_source;
3270                spec->num_mixers = 1;
3271                spec->mixers[0] = ad1988_laptop_mixers;
3272                spec->inv_eapd = 1; /* inverted EAPD */
3273                spec->num_init_verbs = 1;
3274                spec->init_verbs[0] = ad1988_laptop_init_verbs;
3275                if (board_config == AD1988_LAPTOP_DIG)
3276                        spec->multiout.dig_out_nid = AD1988_SPDIF_OUT;
3277                break;
3278        }
3279
3280        spec->num_adc_nids = ARRAY_SIZE(ad1988_adc_nids);
3281        spec->adc_nids = ad1988_adc_nids;
3282        spec->capsrc_nids = ad1988_capsrc_nids;
3283        spec->mixers[spec->num_mixers++] = ad1988_capture_mixers;
3284        spec->init_verbs[spec->num_init_verbs++] = ad1988_capture_init_verbs;
3285        if (spec->multiout.dig_out_nid) {
3286                if (codec->vendor_id >= 0x11d4989a) {
3287                        spec->mixers[spec->num_mixers++] =
3288                                ad1989_spdif_out_mixers;
3289                        spec->init_verbs[spec->num_init_verbs++] =
3290                                ad1989_spdif_init_verbs;
3291                        codec->slave_dig_outs = ad1989b_slave_dig_outs;
3292                } else {
3293                        spec->mixers[spec->num_mixers++] =
3294                                ad1988_spdif_out_mixers;
3295                        spec->init_verbs[spec->num_init_verbs++] =
3296                                ad1988_spdif_init_verbs;
3297                }
3298        }
3299        if (spec->dig_in_nid && codec->vendor_id < 0x11d4989a) {
3300                spec->mixers[spec->num_mixers++] = ad1988_spdif_in_mixers;
3301                spec->init_verbs[spec->num_init_verbs++] =
3302                        ad1988_spdif_in_init_verbs;
3303        }
3304
3305        codec->patch_ops = ad198x_patch_ops;
3306        switch (board_config) {
3307        case AD1988_AUTO:
3308                codec->patch_ops.init = ad1988_auto_init;
3309                break;
3310        case AD1988_LAPTOP:
3311        case AD1988_LAPTOP_DIG:
3312                codec->patch_ops.unsol_event = ad1988_laptop_unsol_event;
3313                break;
3314        }
3315#ifdef CONFIG_SND_HDA_POWER_SAVE
3316        spec->loopback.amplist = ad1988_loopbacks;
3317#endif
3318        spec->vmaster_nid = 0x04;
3319
3320        codec->no_trigger_sense = 1;
3321        codec->no_sticky_stream = 1;
3322
3323        return 0;
3324}
3325
3326
3327/*
3328 * AD1884 / AD1984
3329 *
3330 * port-B - front line/mic-in
3331 * port-E - aux in/out
3332 * port-F - aux in/out
3333 * port-C - rear line/mic-in
3334 * port-D - rear line/hp-out
3335 * port-A - front line/hp-out
3336 *
3337 * AD1984 = AD1884 + two digital mic-ins
3338 *
3339 * FIXME:
3340 * For simplicity, we share the single DAC for both HP and line-outs
3341 * right now.  The inidividual playbacks could be easily implemented,
3342 * but no build-up framework is given, so far.
3343 */
3344
3345static hda_nid_t ad1884_dac_nids[1] = {
3346        0x04,
3347};
3348
3349static hda_nid_t ad1884_adc_nids[2] = {
3350        0x08, 0x09,
3351};
3352
3353static hda_nid_t ad1884_capsrc_nids[2] = {
3354        0x0c, 0x0d,
3355};
3356
3357#define AD1884_SPDIF_OUT        0x02
3358
3359static struct hda_input_mux ad1884_capture_source = {
3360        .num_items = 4,
3361        .items = {
3362                { "Front Mic", 0x0 },
3363                { "Mic", 0x1 },
3364                { "CD", 0x2 },
3365                { "Mix", 0x3 },
3366        },
3367};
3368
3369static struct snd_kcontrol_new ad1884_base_mixers[] = {
3370        HDA_CODEC_VOLUME("PCM Playback Volume", 0x04, 0x0, HDA_OUTPUT),
3371        /* HDA_CODEC_VOLUME_IDX("PCM Playback Volume", 1, 0x03, 0x0, HDA_OUTPUT), */
3372        HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT),
3373        HDA_CODEC_MUTE("Front Playback Switch", 0x12, 0x0, HDA_OUTPUT),
3374        HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x13, 1, 0x0, HDA_OUTPUT),
3375        HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x13, 1, 0x0, HDA_OUTPUT),
3376        HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
3377        HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
3378        HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x01, HDA_INPUT),
3379        HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x01, HDA_INPUT),
3380        HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x02, HDA_INPUT),
3381        HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x02, HDA_INPUT),
3382        HDA_CODEC_VOLUME("Mic Boost Volume", 0x15, 0x0, HDA_INPUT),
3383        HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x14, 0x0, HDA_INPUT),
3384        HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
3385        HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
3386        HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT),
3387        HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x0d, 0x0, HDA_OUTPUT),
3388        {
3389                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3390                /* The multiple "Capture Source" controls confuse alsamixer
3391                 * So call somewhat different..
3392                 */
3393                /* .name = "Capture Source", */
3394                .name = "Input Source",
3395                .count = 2,
3396                .info = ad198x_mux_enum_info,
3397                .get = ad198x_mux_enum_get,
3398                .put = ad198x_mux_enum_put,
3399        },
3400        /* SPDIF controls */
3401        HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
3402        {
3403                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3404                .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
3405                /* identical with ad1983 */
3406                .info = ad1983_spdif_route_info,
3407                .get = ad1983_spdif_route_get,
3408                .put = ad1983_spdif_route_put,
3409        },
3410        { } /* end */
3411};
3412
3413static struct snd_kcontrol_new ad1984_dmic_mixers[] = {
3414        HDA_CODEC_VOLUME("Digital Mic Capture Volume", 0x05, 0x0, HDA_INPUT),
3415        HDA_CODEC_MUTE("Digital Mic Capture Switch", 0x05, 0x0, HDA_INPUT),
3416        HDA_CODEC_VOLUME_IDX("Digital Mic Capture Volume", 1, 0x06, 0x0,
3417                             HDA_INPUT),
3418        HDA_CODEC_MUTE_IDX("Digital Mic Capture Switch", 1, 0x06, 0x0,
3419                           HDA_INPUT),
3420        { } /* end */
3421};
3422
3423/*
3424 * initialization verbs
3425 */
3426static struct hda_verb ad1884_init_verbs[] = {
3427        /* DACs; mute as default */
3428        {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3429        {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3430        /* Port-A (HP) mixer */
3431        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3432        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3433        /* Port-A pin */
3434        {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3435        {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3436        /* HP selector - select DAC2 */
3437        {0x22, AC_VERB_SET_CONNECT_SEL, 0x1},
3438        /* Port-D (Line-out) mixer */
3439        {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3440        {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3441        /* Port-D pin */
3442        {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3443        {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3444        /* Mono-out mixer */
3445        {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3446        {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3447        /* Mono-out pin */
3448        {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3449        {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3450        /* Mono selector */
3451        {0x0e, AC_VERB_SET_CONNECT_SEL, 0x1},
3452        /* Port-B (front mic) pin */
3453        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3454        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3455        /* Port-C (rear mic) pin */
3456        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3457        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3458        /* Analog mixer; mute as default */
3459        {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3460        {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3461        {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3462        {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3463        /* Analog Mix output amp */
3464        {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x1f}, /* 0dB */
3465        /* SPDIF output selector */
3466        {0x02, AC_VERB_SET_CONNECT_SEL, 0x0}, /* PCM */
3467        {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */
3468        { } /* end */
3469};
3470
3471#ifdef CONFIG_SND_HDA_POWER_SAVE
3472static struct hda_amp_list ad1884_loopbacks[] = {
3473        { 0x20, HDA_INPUT, 0 }, /* Front Mic */
3474        { 0x20, HDA_INPUT, 1 }, /* Mic */
3475        { 0x20, HDA_INPUT, 2 }, /* CD */
3476        { 0x20, HDA_INPUT, 4 }, /* Docking */
3477        { } /* end */
3478};
3479#endif
3480
3481static const char * const ad1884_slave_vols[] = {
3482        "PCM Playback Volume",
3483        "Mic Playback Volume",
3484        "Mono Playback Volume",
3485        "Front Mic Playback Volume",
3486        "Mic Playback Volume",
3487        "CD Playback Volume",
3488        "Internal Mic Playback Volume",
3489        "Docking Mic Playback Volume",
3490        /* "Beep Playback Volume", */
3491        "IEC958 Playback Volume",
3492        NULL
3493};
3494
3495static int patch_ad1884(struct hda_codec *codec)
3496{
3497        struct ad198x_spec *spec;
3498        int err;
3499
3500        spec = kzalloc(sizeof(*spec), GFP_KERNEL);
3501        if (spec == NULL)
3502                return -ENOMEM;
3503
3504        codec->spec = spec;
3505
3506        err = snd_hda_attach_beep_device(codec, 0x10);
3507        if (err < 0) {
3508                ad198x_free(codec);
3509                return err;
3510        }
3511        set_beep_amp(spec, 0x10, 0, HDA_OUTPUT);
3512
3513        spec->multiout.max_channels = 2;
3514        spec->multiout.num_dacs = ARRAY_SIZE(ad1884_dac_nids);
3515        spec->multiout.dac_nids = ad1884_dac_nids;
3516        spec->multiout.dig_out_nid = AD1884_SPDIF_OUT;
3517        spec->num_adc_nids = ARRAY_SIZE(ad1884_adc_nids);
3518        spec->adc_nids = ad1884_adc_nids;
3519        spec->capsrc_nids = ad1884_capsrc_nids;
3520        spec->input_mux = &ad1884_capture_source;
3521        spec->num_mixers = 1;
3522        spec->mixers[0] = ad1884_base_mixers;
3523        spec->num_init_verbs = 1;
3524        spec->init_verbs[0] = ad1884_init_verbs;
3525        spec->spdif_route = 0;
3526#ifdef CONFIG_SND_HDA_POWER_SAVE
3527        spec->loopback.amplist = ad1884_loopbacks;
3528#endif
3529        spec->vmaster_nid = 0x04;
3530        /* we need to cover all playback volumes */
3531        spec->slave_vols = ad1884_slave_vols;
3532
3533        codec->patch_ops = ad198x_patch_ops;
3534
3535        codec->no_trigger_sense = 1;
3536        codec->no_sticky_stream = 1;
3537
3538        return 0;
3539}
3540
3541/*
3542 * Lenovo Thinkpad T61/X61
3543 */
3544static struct hda_input_mux ad1984_thinkpad_capture_source = {
3545        .num_items = 4,
3546        .items = {
3547                { "Mic", 0x0 },
3548                { "Internal Mic", 0x1 },
3549                { "Mix", 0x3 },
3550                { "Docking-Station", 0x4 },
3551        },
3552};
3553
3554
3555/*
3556 * Dell Precision T3400
3557 */
3558static struct hda_input_mux ad1984_dell_desktop_capture_source = {
3559        .num_items = 3,
3560        .items = {
3561                { "Front Mic", 0x0 },
3562                { "Line-In", 0x1 },
3563                { "Mix", 0x3 },
3564        },
3565};
3566
3567
3568static struct snd_kcontrol_new ad1984_thinkpad_mixers[] = {
3569        HDA_CODEC_VOLUME("PCM Playback Volume", 0x04, 0x0, HDA_OUTPUT),
3570        /* HDA_CODEC_VOLUME_IDX("PCM Playback Volume", 1, 0x03, 0x0, HDA_OUTPUT), */
3571        HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT),
3572        HDA_CODEC_MUTE("Speaker Playback Switch", 0x12, 0x0, HDA_OUTPUT),
3573        HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
3574        HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
3575        HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x20, 0x01, HDA_INPUT),
3576        HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x20, 0x01, HDA_INPUT),
3577        HDA_CODEC_VOLUME("Beep Playback Volume", 0x20, 0x03, HDA_INPUT),
3578        HDA_CODEC_MUTE("Beep Playback Switch", 0x20, 0x03, HDA_INPUT),
3579        HDA_CODEC_VOLUME("Docking Mic Playback Volume", 0x20, 0x04, HDA_INPUT),
3580        HDA_CODEC_MUTE("Docking Mic Playback Switch", 0x20, 0x04, HDA_INPUT),
3581        HDA_CODEC_VOLUME("Mic Boost Volume", 0x14, 0x0, HDA_INPUT),
3582        HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x15, 0x0, HDA_INPUT),
3583        HDA_CODEC_VOLUME("Dock Mic Boost Volume", 0x25, 0x0, HDA_OUTPUT),
3584        HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
3585        HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
3586        HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT),
3587        HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x0d, 0x0, HDA_OUTPUT),
3588        {
3589                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3590                /* The multiple "Capture Source" controls confuse alsamixer
3591                 * So call somewhat different..
3592                 */
3593                /* .name = "Capture Source", */
3594                .name = "Input Source",
3595                .count = 2,
3596                .info = ad198x_mux_enum_info,
3597                .get = ad198x_mux_enum_get,
3598                .put = ad198x_mux_enum_put,
3599        },
3600        /* SPDIF controls */
3601        HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
3602        {
3603                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3604                .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
3605                /* identical with ad1983 */
3606                .info = ad1983_spdif_route_info,
3607                .get = ad1983_spdif_route_get,
3608                .put = ad1983_spdif_route_put,
3609        },
3610        { } /* end */
3611};
3612
3613/* additional verbs */
3614static struct hda_verb ad1984_thinkpad_init_verbs[] = {
3615        /* Port-E (docking station mic) pin */
3616        {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3617        {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3618        /* docking mic boost */
3619        {0x25, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3620        /* Analog PC Beeper - allow firmware/ACPI beeps */
3621        {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3) | 0x1a},
3622        /* Analog mixer - docking mic; mute as default */
3623        {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3624        /* enable EAPD bit */
3625        {0x12, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
3626        { } /* end */
3627};
3628
3629/*
3630 * Dell Precision T3400
3631 */
3632static struct snd_kcontrol_new ad1984_dell_desktop_mixers[] = {
3633        HDA_CODEC_VOLUME("PCM Playback Volume", 0x04, 0x0, HDA_OUTPUT),
3634        HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT),
3635        HDA_CODEC_MUTE("Speaker Playback Switch", 0x12, 0x0, HDA_OUTPUT),
3636        HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x13, 1, 0x0, HDA_OUTPUT),
3637        HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x13, 1, 0x0, HDA_OUTPUT),
3638        HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
3639        HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
3640        HDA_CODEC_VOLUME("Line-In Playback Volume", 0x20, 0x01, HDA_INPUT),
3641        HDA_CODEC_MUTE("Line-In Playback Switch", 0x20, 0x01, HDA_INPUT),
3642        HDA_CODEC_VOLUME("Line-In Boost Volume", 0x15, 0x0, HDA_INPUT),
3643        HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x14, 0x0, HDA_INPUT),
3644        HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
3645        HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
3646        HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT),
3647        HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x0d, 0x0, HDA_OUTPUT),
3648        {
3649                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3650                /* The multiple "Capture Source" controls confuse alsamixer
3651                 * So call somewhat different..
3652                 */
3653                /* .name = "Capture Source", */
3654                .name = "Input Source",
3655                .count = 2,
3656                .info = ad198x_mux_enum_info,
3657                .get = ad198x_mux_enum_get,
3658                .put = ad198x_mux_enum_put,
3659        },
3660        { } /* end */
3661};
3662
3663/* Digial MIC ADC NID 0x05 + 0x06 */
3664static int ad1984_pcm_dmic_prepare(struct hda_pcm_stream *hinfo,
3665                                   struct hda_codec *codec,
3666                                   unsigned int stream_tag,
3667                                   unsigned int format,
3668                                   struct snd_pcm_substream *substream)
3669{
3670        snd_hda_codec_setup_stream(codec, 0x05 + substream->number,
3671                                   stream_tag, 0, format);
3672        return 0;
3673}
3674
3675static int ad1984_pcm_dmic_cleanup(struct hda_pcm_stream *hinfo,
3676                                   struct hda_codec *codec,
3677                                   struct snd_pcm_substream *substream)
3678{
3679        snd_hda_codec_cleanup_stream(codec, 0x05 + substream->number);
3680        return 0;
3681}
3682
3683static struct hda_pcm_stream ad1984_pcm_dmic_capture = {
3684        .substreams = 2,
3685        .channels_min = 2,
3686        .channels_max = 2,
3687        .nid = 0x05,
3688        .ops = {
3689                .prepare = ad1984_pcm_dmic_prepare,
3690                .cleanup = ad1984_pcm_dmic_cleanup
3691        },
3692};
3693
3694static int ad1984_build_pcms(struct hda_codec *codec)
3695{
3696        struct ad198x_spec *spec = codec->spec;
3697        struct hda_pcm *info;
3698        int err;
3699
3700        err = ad198x_build_pcms(codec);
3701        if (err < 0)
3702                return err;
3703
3704        info = spec->pcm_rec + codec->num_pcms;
3705        codec->num_pcms++;
3706        info->name = "AD1984 Digital Mic";
3707        info->stream[SNDRV_PCM_STREAM_CAPTURE] = ad1984_pcm_dmic_capture;
3708        return 0;
3709}
3710
3711/* models */
3712enum {
3713        AD1984_BASIC,
3714        AD1984_THINKPAD,
3715        AD1984_DELL_DESKTOP,
3716        AD1984_MODELS
3717};
3718
3719static const char * const ad1984_models[AD1984_MODELS] = {
3720        [AD1984_BASIC]          = "basic",
3721        [AD1984_THINKPAD]       = "thinkpad",
3722        [AD1984_DELL_DESKTOP]   = "dell_desktop",
3723};
3724
3725static struct snd_pci_quirk ad1984_cfg_tbl[] = {
3726        /* Lenovo Thinkpad T61/X61 */
3727        SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo Thinkpad", AD1984_THINKPAD),
3728        SND_PCI_QUIRK(0x1028, 0x0214, "Dell T3400", AD1984_DELL_DESKTOP),
3729        SND_PCI_QUIRK(0x1028, 0x0233, "Dell Latitude E6400", AD1984_DELL_DESKTOP),
3730        {}
3731};
3732
3733static int patch_ad1984(struct hda_codec *codec)
3734{
3735        struct ad198x_spec *spec;
3736        int board_config, err;
3737
3738        err = patch_ad1884(codec);
3739        if (err < 0)
3740                return err;
3741        spec = codec->spec;
3742        board_config = snd_hda_check_board_config(codec, AD1984_MODELS,
3743                                                  ad1984_models, ad1984_cfg_tbl);
3744        switch (board_config) {
3745        case AD1984_BASIC:
3746                /* additional digital mics */
3747                spec->mixers[spec->num_mixers++] = ad1984_dmic_mixers;
3748                codec->patch_ops.build_pcms = ad1984_build_pcms;
3749                break;
3750        case AD1984_THINKPAD:
3751                if (codec->subsystem_id == 0x17aa20fb) {
3752                        /* Thinpad X300 does not have the ability to do SPDIF,
3753                           or attach to docking station to use SPDIF */
3754                        spec->multiout.dig_out_nid = 0;
3755                } else
3756                        spec->multiout.dig_out_nid = AD1884_SPDIF_OUT;
3757                spec->input_mux = &ad1984_thinkpad_capture_source;
3758                spec->mixers[0] = ad1984_thinkpad_mixers;
3759                spec->init_verbs[spec->num_init_verbs++] = ad1984_thinkpad_init_verbs;
3760                spec->analog_beep = 1;
3761                break;
3762        case AD1984_DELL_DESKTOP:
3763                spec->multiout.dig_out_nid = 0;
3764                spec->input_mux = &ad1984_dell_desktop_capture_source;
3765                spec->mixers[0] = ad1984_dell_desktop_mixers;
3766                break;
3767        }
3768        return 0;
3769}
3770
3771
3772/*
3773 * AD1883 / AD1884A / AD1984A / AD1984B
3774 *
3775 * port-B (0x14) - front mic-in
3776 * port-E (0x1c) - rear mic-in
3777 * port-F (0x16) - CD / ext out
3778 * port-C (0x15) - rear line-in
3779 * port-D (0x12) - rear line-out
3780 * port-A (0x11) - front hp-out
3781 *
3782 * AD1984A = AD1884A + digital-mic
3783 * AD1883 = equivalent with AD1984A
3784 * AD1984B = AD1984A + extra SPDIF-out
3785 *
3786 * FIXME:
3787 * We share the single DAC for both HP and line-outs (see AD1884/1984).
3788 */
3789
3790static hda_nid_t ad1884a_dac_nids[1] = {
3791        0x03,
3792};
3793
3794#define ad1884a_adc_nids        ad1884_adc_nids
3795#define ad1884a_capsrc_nids     ad1884_capsrc_nids
3796
3797#define AD1884A_SPDIF_OUT       0x02
3798
3799static struct hda_input_mux ad1884a_capture_source = {
3800        .num_items = 5,
3801        .items = {
3802                { "Front Mic", 0x0 },
3803                { "Mic", 0x4 },
3804                { "Line", 0x1 },
3805                { "CD", 0x2 },
3806                { "Mix", 0x3 },
3807        },
3808};
3809
3810static struct snd_kcontrol_new ad1884a_base_mixers[] = {
3811        HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT),
3812        HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT),
3813        HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT),
3814        HDA_CODEC_MUTE("Front Playback Switch", 0x12, 0x0, HDA_OUTPUT),
3815        HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x13, 1, 0x0, HDA_OUTPUT),
3816        HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x13, 1, 0x0, HDA_OUTPUT),
3817        HDA_CODEC_VOLUME("PCM Playback Volume", 0x20, 0x5, HDA_INPUT),
3818        HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT),
3819        HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
3820        HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
3821        HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x01, HDA_INPUT),
3822        HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x01, HDA_INPUT),
3823        HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x04, HDA_INPUT),
3824        HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x04, HDA_INPUT),
3825        HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x02, HDA_INPUT),
3826        HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x02, HDA_INPUT),
3827        HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x14, 0x0, HDA_INPUT),
3828        HDA_CODEC_VOLUME("Line Boost Volume", 0x15, 0x0, HDA_INPUT),
3829        HDA_CODEC_VOLUME("Mic Boost Volume", 0x25, 0x0, HDA_OUTPUT),
3830        HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
3831        HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
3832        HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT),
3833        HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x0d, 0x0, HDA_OUTPUT),
3834        {
3835                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3836                /* The multiple "Capture Source" controls confuse alsamixer
3837                 * So call somewhat different..
3838                 */
3839                /* .name = "Capture Source", */
3840                .name = "Input Source",
3841                .count = 2,
3842                .info = ad198x_mux_enum_info,
3843                .get = ad198x_mux_enum_get,
3844                .put = ad198x_mux_enum_put,
3845        },
3846        /* SPDIF controls */
3847        HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
3848        {
3849                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3850                .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
3851                /* identical with ad1983 */
3852                .info = ad1983_spdif_route_info,
3853                .get = ad1983_spdif_route_get,
3854                .put = ad1983_spdif_route_put,
3855        },
3856        { } /* end */
3857};
3858
3859/*
3860 * initialization verbs
3861 */
3862static struct hda_verb ad1884a_init_verbs[] = {
3863        /* DACs; unmute as default */
3864        {0x03, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */
3865        {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */
3866        /* Port-A (HP) mixer - route only from analog mixer */
3867        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3868        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3869        /* Port-A pin */
3870        {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3871        {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3872        /* Port-D (Line-out) mixer - route only from analog mixer */
3873        {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3874        {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3875        /* Port-D pin */
3876        {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3877        {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3878        /* Mono-out mixer - route only from analog mixer */
3879        {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3880        {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3881        /* Mono-out pin */
3882        {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3883        {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3884        /* Port-B (front mic) pin */
3885        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3886        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3887        /* Port-C (rear line-in) pin */
3888        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3889        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3890        /* Port-E (rear mic) pin */
3891        {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3892        {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3893        {0x25, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, /* no boost */
3894        /* Port-F (CD) pin */
3895        {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3896        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3897        /* Analog mixer; mute as default */
3898        {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3899        {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3900        {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3901        {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3902        {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, /* aux */
3903        {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
3904        /* Analog Mix output amp */
3905        {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3906        /* capture sources */
3907        {0x0c, AC_VERB_SET_CONNECT_SEL, 0x0},
3908        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3909        {0x0d, AC_VERB_SET_CONNECT_SEL, 0x0},
3910        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3911        /* SPDIF output amp */
3912        {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */
3913        { } /* end */
3914};
3915
3916#ifdef CONFIG_SND_HDA_POWER_SAVE
3917static struct hda_amp_list ad1884a_loopbacks[] = {
3918        { 0x20, HDA_INPUT, 0 }, /* Front Mic */
3919        { 0x20, HDA_INPUT, 1 }, /* Mic */
3920        { 0x20, HDA_INPUT, 2 }, /* CD */
3921        { 0x20, HDA_INPUT, 4 }, /* Docking */
3922        { } /* end */
3923};
3924#endif
3925
3926/*
3927 * Laptop model
3928 *
3929 * Port A: Headphone jack
3930 * Port B: MIC jack
3931 * Port C: Internal MIC
3932 * Port D: Dock Line Out (if enabled)
3933 * Port E: Dock Line In (if enabled)
3934 * Port F: Internal speakers
3935 */
3936
3937static int ad1884a_mobile_master_sw_put(struct snd_kcontrol *kcontrol,
3938                                        struct snd_ctl_elem_value *ucontrol)
3939{
3940        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3941        int ret = snd_hda_mixer_amp_switch_put(kcontrol, ucontrol);
3942        int mute = (!ucontrol->value.integer.value[0] &&
3943                    !ucontrol->value.integer.value[1]);
3944        /* toggle GPIO1 according to the mute state */
3945        snd_hda_codec_write_cache(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA,
3946                            mute ? 0x02 : 0x0);
3947        return ret;
3948}
3949
3950static struct snd_kcontrol_new ad1884a_laptop_mixers[] = {
3951        HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT),
3952        {
3953                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3954                .name = "Master Playback Switch",
3955                .subdevice = HDA_SUBDEV_AMP_FLAG,
3956                .info = snd_hda_mixer_amp_switch_info,
3957                .get = snd_hda_mixer_amp_switch_get,
3958                .put = ad1884a_mobile_master_sw_put,
3959                .private_value = HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
3960        },
3961        HDA_CODEC_MUTE("Dock Playback Switch", 0x12, 0x0, HDA_OUTPUT),
3962        HDA_CODEC_VOLUME("PCM Playback Volume", 0x20, 0x5, HDA_INPUT),
3963        HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT),
3964        HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
3965        HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
3966        HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x20, 0x01, HDA_INPUT),
3967        HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x20, 0x01, HDA_INPUT),
3968        HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x20, 0x04, HDA_INPUT),
3969        HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x20, 0x04, HDA_INPUT),
3970        HDA_CODEC_VOLUME("Mic Boost Volume", 0x14, 0x0, HDA_INPUT),
3971        HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x15, 0x0, HDA_INPUT),
3972        HDA_CODEC_VOLUME("Dock Mic Boost Volume", 0x25, 0x0, HDA_OUTPUT),
3973        HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
3974        HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
3975        { } /* end */
3976};
3977
3978static struct snd_kcontrol_new ad1884a_mobile_mixers[] = {
3979        HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT),
3980        /*HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT),*/
3981        {
3982                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3983                .name = "Master Playback Switch",
3984                .subdevice = HDA_SUBDEV_AMP_FLAG,
3985                .info = snd_hda_mixer_amp_switch_info,
3986                .get = snd_hda_mixer_amp_switch_get,
3987                .put = ad1884a_mobile_master_sw_put,
3988                .private_value = HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
3989        },
3990        HDA_CODEC_VOLUME("PCM Playback Volume", 0x20, 0x5, HDA_INPUT),
3991        HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT),
3992        HDA_CODEC_VOLUME("Mic Capture Volume", 0x14, 0x0, HDA_INPUT),
3993        HDA_CODEC_VOLUME("Internal Mic Capture Volume", 0x15, 0x0, HDA_INPUT),
3994        HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
3995        HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
3996        { } /* end */
3997};
3998
3999/* mute internal speaker if HP is plugged */
4000static void ad1884a_hp_automute(struct hda_codec *codec)
4001{
4002        unsigned int present;
4003
4004        present = snd_hda_jack_detect(codec, 0x11);
4005        snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
4006                                 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
4007        snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_EAPD_BTLENABLE,
4008                            present ? 0x00 : 0x02);
4009}
4010
4011/* switch to external mic if plugged */
4012static void ad1884a_hp_automic(struct hda_codec *codec)
4013{
4014        unsigned int present;
4015
4016        present = snd_hda_jack_detect(codec, 0x14);
4017        snd_hda_codec_write(codec, 0x0c, 0, AC_VERB_SET_CONNECT_SEL,
4018                            present ? 0 : 1);
4019}
4020
4021#define AD1884A_HP_EVENT                0x37
4022#define AD1884A_MIC_EVENT               0x36
4023
4024/* unsolicited event for HP jack sensing */
4025static void ad1884a_hp_unsol_event(struct hda_codec *codec, unsigned int res)
4026{
4027        switch (res >> 26) {
4028        case AD1884A_HP_EVENT:
4029                ad1884a_hp_automute(codec);
4030                break;
4031        case AD1884A_MIC_EVENT:
4032                ad1884a_hp_automic(codec);
4033                break;
4034        }
4035}
4036
4037/* initialize jack-sensing, too */
4038static int ad1884a_hp_init(struct hda_codec *codec)
4039{
4040        ad198x_init(codec);
4041        ad1884a_hp_automute(codec);
4042        ad1884a_hp_automic(codec);
4043        return 0;
4044}
4045
4046/* mute internal speaker if HP or docking HP is plugged */
4047static void ad1884a_laptop_automute(struct hda_codec *codec)
4048{
4049        unsigned int present;
4050
4051        present = snd_hda_jack_detect(codec, 0x11);
4052        if (!present)
4053                present = snd_hda_jack_detect(codec, 0x12);
4054        snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
4055                                 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
4056        snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_EAPD_BTLENABLE,
4057                            present ? 0x00 : 0x02);
4058}
4059
4060/* switch to external mic if plugged */
4061static void ad1884a_laptop_automic(struct hda_codec *codec)
4062{
4063        unsigned int idx;
4064
4065        if (snd_hda_jack_detect(codec, 0x14))
4066                idx = 0;
4067        else if (snd_hda_jack_detect(codec, 0x1c))
4068                idx = 4;
4069        else
4070                idx = 1;
4071        snd_hda_codec_write(codec, 0x0c, 0, AC_VERB_SET_CONNECT_SEL, idx);
4072}
4073
4074/* unsolicited event for HP jack sensing */
4075static void ad1884a_laptop_unsol_event(struct hda_codec *codec,
4076                                       unsigned int res)
4077{
4078        switch (res >> 26) {
4079        case AD1884A_HP_EVENT:
4080                ad1884a_laptop_automute(codec);
4081                break;
4082        case AD1884A_MIC_EVENT:
4083                ad1884a_laptop_automic(codec);
4084                break;
4085        }
4086}
4087
4088/* initialize jack-sensing, too */
4089static int ad1884a_laptop_init(struct hda_codec *codec)
4090{
4091        ad198x_init(codec);
4092        ad1884a_laptop_automute(codec);
4093        ad1884a_laptop_automic(codec);
4094        return 0;
4095}
4096
4097/* additional verbs for laptop model */
4098static struct hda_verb ad1884a_laptop_verbs[] = {
4099        /* Port-A (HP) pin - always unmuted */
4100        {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4101        /* Port-F (int speaker) mixer - route only from analog mixer */
4102        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4103        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4104        /* Port-F (int speaker) pin */
4105        {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4106        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4107        /* required for compaq 6530s/6531s speaker output */
4108        {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4109        /* Port-C pin - internal mic-in */
4110        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4111        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7002}, /* raise mic as default */
4112        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x7002}, /* raise mic as default */
4113        /* Port-D (docking line-out) pin - default unmuted */
4114        {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4115        /* analog mix */
4116        {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4117        /* unsolicited event for pin-sense */
4118        {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_HP_EVENT},
4119        {0x12, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_HP_EVENT},
4120        {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_MIC_EVENT},
4121        {0x1c, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_MIC_EVENT},
4122        /* allow to touch GPIO1 (for mute control) */
4123        {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
4124        {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
4125        {0x01, AC_VERB_SET_GPIO_DATA, 0x02}, /* first muted */
4126        { } /* end */
4127};
4128
4129static struct hda_verb ad1884a_mobile_verbs[] = {
4130        /* DACs; unmute as default */
4131        {0x03, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */
4132        {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */
4133        /* Port-A (HP) mixer - route only from analog mixer */
4134        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4135        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4136        /* Port-A pin */
4137        {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4138        /* Port-A (HP) pin - always unmuted */
4139        {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4140        /* Port-B (mic jack) pin */
4141        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4142        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7002}, /* raise mic as default */
4143        /* Port-C (int mic) pin */
4144        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4145        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x7002}, /* raise mic as default */
4146        /* Port-F (int speaker) mixer - route only from analog mixer */
4147        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4148        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4149        /* Port-F pin */
4150        {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4151        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4152        /* Analog mixer; mute as default */
4153        {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4154        {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4155        {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4156        {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4157        {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4158        {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
4159        /* Analog Mix output amp */
4160        {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4161        /* capture sources */
4162        /* {0x0c, AC_VERB_SET_CONNECT_SEL, 0x0}, */ /* set via unsol */
4163        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4164        {0x0d, AC_VERB_SET_CONNECT_SEL, 0x0},
4165        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4166        /* unsolicited event for pin-sense */
4167        {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_HP_EVENT},
4168        {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_MIC_EVENT},
4169        /* allow to touch GPIO1 (for mute control) */
4170        {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
4171        {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
4172        {0x01, AC_VERB_SET_GPIO_DATA, 0x02}, /* first muted */
4173        { } /* end */
4174};
4175
4176/*
4177 * Thinkpad X300
4178 * 0x11 - HP
4179 * 0x12 - speaker
4180 * 0x14 - mic-in
4181 * 0x17 - built-in mic
4182 */
4183
4184static struct hda_verb ad1984a_thinkpad_verbs[] = {
4185        /* HP unmute */
4186        {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4187        /* analog mix */
4188        {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4189        /* turn on EAPD */
4190        {0x12, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
4191        /* unsolicited event for pin-sense */
4192        {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_HP_EVENT},
4193        /* internal mic - dmic */
4194        {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4195        /* set magic COEFs for dmic */
4196        {0x01, AC_VERB_SET_COEF_INDEX, 0x13f7},
4197        {0x01, AC_VERB_SET_PROC_COEF, 0x08},
4198        { } /* end */
4199};
4200
4201static struct snd_kcontrol_new ad1984a_thinkpad_mixers[] = {
4202        HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT),
4203        HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT),
4204        HDA_CODEC_VOLUME("PCM Playback Volume", 0x20, 0x5, HDA_INPUT),
4205        HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT),
4206        HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
4207        HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
4208        HDA_CODEC_VOLUME("Mic Boost Volume", 0x14, 0x0, HDA_INPUT),
4209        HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x17, 0x0, HDA_INPUT),
4210        HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
4211        HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
4212        {
4213                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4214                .name = "Capture Source",
4215                .info = ad198x_mux_enum_info,
4216                .get = ad198x_mux_enum_get,
4217                .put = ad198x_mux_enum_put,
4218        },
4219        { } /* end */
4220};
4221
4222static struct hda_input_mux ad1984a_thinkpad_capture_source = {
4223        .num_items = 3,
4224        .items = {
4225                { "Mic", 0x0 },
4226                { "Internal Mic", 0x5 },
4227                { "Mix", 0x3 },
4228        },
4229};
4230
4231/* mute internal speaker if HP is plugged */
4232static void ad1984a_thinkpad_automute(struct hda_codec *codec)
4233{
4234        unsigned int present;
4235
4236        present = snd_hda_jack_detect(codec, 0x11);
4237        snd_hda_codec_amp_stereo(codec, 0x12, HDA_OUTPUT, 0,
4238                                 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
4239}
4240
4241/* unsolicited event for HP jack sensing */
4242static void ad1984a_thinkpad_unsol_event(struct hda_codec