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                int type = cfg->inputs[i].type;
3074                switch (nid) {
3075                case 0x15: /* port-C */
3076                        snd_hda_codec_write(codec, 0x33, 0, AC_VERB_SET_CONNECT_SEL, 0x0);
3077                        break;
3078                case 0x17: /* port-E */
3079                        snd_hda_codec_write(codec, 0x34, 0, AC_VERB_SET_CONNECT_SEL, 0x0);
3080                        break;
3081                }
3082                snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3083                                    type == AUTO_PIN_MIC ? PIN_VREF80 : PIN_IN);
3084                if (nid != AD1988_PIN_CD_NID)
3085                        snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
3086                                            AMP_OUT_MUTE);
3087                idx = ad1988_pin_idx(nid);
3088                if (ad1988_boost_nids[idx])
3089                        snd_hda_codec_write(codec, ad1988_boost_nids[idx], 0,
3090                                            AC_VERB_SET_AMP_GAIN_MUTE,
3091                                            AMP_OUT_ZERO);
3092        }
3093}
3094
3095/* parse the BIOS configuration and set up the alc_spec */
3096/* return 1 if successful, 0 if the proper config is not found, or a negative error code */
3097static int ad1988_parse_auto_config(struct hda_codec *codec)
3098{
3099        struct ad198x_spec *spec = codec->spec;
3100        int err;
3101
3102        if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL)) < 0)
3103                return err;
3104        if ((err = ad1988_auto_fill_dac_nids(codec, &spec->autocfg)) < 0)
3105                return err;
3106        if (! spec->autocfg.line_outs)
3107                return 0; /* can't find valid BIOS pin config */
3108        if ((err = ad1988_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0 ||
3109            (err = ad1988_auto_create_extra_out(codec,
3110                                                spec->autocfg.speaker_pins[0],
3111                                                "Speaker")) < 0 ||
3112            (err = ad1988_auto_create_extra_out(codec, spec->autocfg.hp_pins[0],
3113                                                "Headphone")) < 0 ||
3114            (err = ad1988_auto_create_analog_input_ctls(codec, &spec->autocfg)) < 0)
3115                return err;
3116
3117        spec->multiout.max_channels = spec->multiout.num_dacs * 2;
3118
3119        if (spec->autocfg.dig_outs)
3120                spec->multiout.dig_out_nid = AD1988_SPDIF_OUT;
3121        if (spec->autocfg.dig_in_pin)
3122                spec->dig_in_nid = AD1988_SPDIF_IN;
3123
3124        if (spec->kctls.list)
3125                spec->mixers[spec->num_mixers++] = spec->kctls.list;
3126
3127        spec->init_verbs[spec->num_init_verbs++] = ad1988_6stack_init_verbs;
3128
3129        spec->input_mux = &spec->private_imux;
3130
3131        return 1;
3132}
3133
3134/* init callback for auto-configuration model -- overriding the default init */
3135static int ad1988_auto_init(struct hda_codec *codec)
3136{
3137        ad198x_init(codec);
3138        ad1988_auto_init_multi_out(codec);
3139        ad1988_auto_init_extra_out(codec);
3140        ad1988_auto_init_analog_input(codec);
3141        return 0;
3142}
3143
3144/*
3145 */
3146
3147static const char * const ad1988_models[AD1988_MODEL_LAST] = {
3148        [AD1988_6STACK]         = "6stack",
3149        [AD1988_6STACK_DIG]     = "6stack-dig",
3150        [AD1988_6STACK_DIG_FP]  = "6stack-dig-fp",
3151        [AD1988_3STACK]         = "3stack",
3152        [AD1988_3STACK_DIG]     = "3stack-dig",
3153        [AD1988_LAPTOP]         = "laptop",
3154        [AD1988_LAPTOP_DIG]     = "laptop-dig",
3155        [AD1988_AUTO]           = "auto",
3156};
3157
3158static struct snd_pci_quirk ad1988_cfg_tbl[] = {
3159        SND_PCI_QUIRK(0x1043, 0x81ec, "Asus P5B-DLX", AD1988_6STACK_DIG),
3160        SND_PCI_QUIRK(0x1043, 0x81f6, "Asus M2N-SLI", AD1988_6STACK_DIG),
3161        SND_PCI_QUIRK(0x1043, 0x8277, "Asus P5K-E/WIFI-AP", AD1988_6STACK_DIG),
3162        SND_PCI_QUIRK(0x1043, 0x8311, "Asus P5Q-Premium/Pro", AD1988_6STACK_DIG),
3163        {}
3164};
3165
3166static int patch_ad1988(struct hda_codec *codec)
3167{
3168        struct ad198x_spec *spec;
3169        int err, board_config;
3170
3171        spec = kzalloc(sizeof(*spec), GFP_KERNEL);
3172        if (spec == NULL)
3173                return -ENOMEM;
3174
3175        codec->spec = spec;
3176
3177        if (is_rev2(codec))
3178                snd_printk(KERN_INFO "patch_analog: AD1988A rev.2 is detected, enable workarounds\n");
3179
3180        board_config = snd_hda_check_board_config(codec, AD1988_MODEL_LAST,
3181                                                  ad1988_models, ad1988_cfg_tbl);
3182        if (board_config < 0) {
3183                printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
3184                       codec->chip_name);
3185                board_config = AD1988_AUTO;
3186        }
3187
3188        if (board_config == AD1988_AUTO) {
3189                /* automatic parse from the BIOS config */
3190                err = ad1988_parse_auto_config(codec);
3191                if (err < 0) {
3192                        ad198x_free(codec);
3193                        return err;
3194                } else if (! err) {
3195                        printk(KERN_INFO "hda_codec: Cannot set up configuration from BIOS.  Using 6-stack mode...\n");
3196                        board_config = AD1988_6STACK;
3197                }
3198        }
3199
3200        err = snd_hda_attach_beep_device(codec, 0x10);
3201        if (err < 0) {
3202                ad198x_free(codec);
3203                return err;
3204        }
3205        set_beep_amp(spec, 0x10, 0, HDA_OUTPUT);
3206
3207        switch (board_config) {
3208        case AD1988_6STACK:
3209        case AD1988_6STACK_DIG:
3210        case AD1988_6STACK_DIG_FP:
3211                spec->multiout.max_channels = 8;
3212                spec->multiout.num_dacs = 4;
3213                if (is_rev2(codec))
3214                        spec->multiout.dac_nids = ad1988_6stack_dac_nids_rev2;
3215                else
3216                        spec->multiout.dac_nids = ad1988_6stack_dac_nids;
3217                spec->input_mux = &ad1988_6stack_capture_source;
3218                spec->num_mixers = 2;
3219                if (is_rev2(codec))
3220                        spec->mixers[0] = ad1988_6stack_mixers1_rev2;
3221                else
3222                        spec->mixers[0] = ad1988_6stack_mixers1;
3223                spec->mixers[1] = ad1988_6stack_mixers2;
3224                spec->num_init_verbs = 1;
3225                spec->init_verbs[0] = ad1988_6stack_init_verbs;
3226                if (board_config == AD1988_6STACK_DIG_FP) {
3227                        spec->num_mixers++;
3228                        spec->mixers[2] = ad1988_6stack_fp_mixers;
3229                        spec->num_init_verbs++;
3230                        spec->init_verbs[1] = ad1988_6stack_fp_init_verbs;
3231                        spec->slave_vols = ad1988_6stack_fp_slave_vols;
3232                        spec->slave_sws = ad1988_6stack_fp_slave_sws;
3233                        spec->alt_dac_nid = ad1988_alt_dac_nid;
3234                        spec->stream_analog_alt_playback =
3235                                &ad198x_pcm_analog_alt_playback;
3236                }
3237                if ((board_config == AD1988_6STACK_DIG) ||
3238                        (board_config == AD1988_6STACK_DIG_FP)) {
3239                        spec->multiout.dig_out_nid = AD1988_SPDIF_OUT;
3240                        spec->dig_in_nid = AD1988_SPDIF_IN;
3241                }
3242                break;
3243        case AD1988_3STACK:
3244        case AD1988_3STACK_DIG:
3245                spec->multiout.max_channels = 6;
3246                spec->multiout.num_dacs = 3;
3247                if (is_rev2(codec))
3248                        spec->multiout.dac_nids = ad1988_3stack_dac_nids_rev2;
3249                else
3250                        spec->multiout.dac_nids = ad1988_3stack_dac_nids;
3251                spec->input_mux = &ad1988_6stack_capture_source;
3252                spec->channel_mode = ad1988_3stack_modes;
3253                spec->num_channel_mode = ARRAY_SIZE(ad1988_3stack_modes);
3254                spec->num_mixers = 2;
3255                if (is_rev2(codec))
3256                        spec->mixers[0] = ad1988_3stack_mixers1_rev2;
3257                else
3258                        spec->mixers[0] = ad1988_3stack_mixers1;
3259                spec->mixers[1] = ad1988_3stack_mixers2;
3260                spec->num_init_verbs = 1;
3261                spec->init_verbs[0] = ad1988_3stack_init_verbs;
3262                if (board_config == AD1988_3STACK_DIG)
3263                        spec->multiout.dig_out_nid = AD1988_SPDIF_OUT;
3264                break;
3265        case AD1988_LAPTOP:
3266        case AD1988_LAPTOP_DIG:
3267                spec->multiout.max_channels = 2;
3268                spec->multiout.num_dacs = 1;
3269                spec->multiout.dac_nids = ad1988_3stack_dac_nids;
3270                spec->input_mux = &ad1988_laptop_capture_source;
3271                spec->num_mixers = 1;
3272                spec->mixers[0] = ad1988_laptop_mixers;
3273                spec->inv_eapd = 1; /* inverted EAPD */
3274                spec->num_init_verbs = 1;
3275                spec->init_verbs[0] = ad1988_laptop_init_verbs;
3276                if (board_config == AD1988_LAPTOP_DIG)
3277                        spec->multiout.dig_out_nid = AD1988_SPDIF_OUT;
3278                break;
3279        }
3280
3281        spec->num_adc_nids = ARRAY_SIZE(ad1988_adc_nids);
3282        spec->adc_nids = ad1988_adc_nids;
3283        spec->capsrc_nids = ad1988_capsrc_nids;
3284        spec->mixers[spec->num_mixers++] = ad1988_capture_mixers;
3285        spec->init_verbs[spec->num_init_verbs++] = ad1988_capture_init_verbs;
3286        if (spec->multiout.dig_out_nid) {
3287                if (codec->vendor_id >= 0x11d4989a) {
3288                        spec->mixers[spec->num_mixers++] =
3289                                ad1989_spdif_out_mixers;
3290                        spec->init_verbs[spec->num_init_verbs++] =
3291                                ad1989_spdif_init_verbs;
3292                        codec->slave_dig_outs = ad1989b_slave_dig_outs;
3293                } else {
3294                        spec->mixers[spec->num_mixers++] =
3295                                ad1988_spdif_out_mixers;
3296                        spec->init_verbs[spec->num_init_verbs++] =
3297                                ad1988_spdif_init_verbs;
3298                }
3299        }
3300        if (spec->dig_in_nid && codec->vendor_id < 0x11d4989a) {
3301                spec->mixers[spec->num_mixers++] = ad1988_spdif_in_mixers;
3302                spec->init_verbs[spec->num_init_verbs++] =
3303                        ad1988_spdif_in_init_verbs;
3304        }
3305
3306        codec->patch_ops = ad198x_patch_ops;
3307        switch (board_config) {
3308        case AD1988_AUTO:
3309                codec->patch_ops.init = ad1988_auto_init;
3310                break;
3311        case AD1988_LAPTOP:
3312        case AD1988_LAPTOP_DIG:
3313                codec->patch_ops.unsol_event = ad1988_laptop_unsol_event;
3314                break;
3315        }
3316#ifdef CONFIG_SND_HDA_POWER_SAVE
3317        spec->loopback.amplist = ad1988_loopbacks;
3318#endif
3319        spec->vmaster_nid = 0x04;
3320
3321        codec->no_trigger_sense = 1;
3322        codec->no_sticky_stream = 1;
3323
3324        return 0;
3325}
3326
3327
3328/*
3329 * AD1884 / AD1984
3330 *
3331 * port-B - front line/mic-in
3332 * port-E - aux in/out
3333 * port-F - aux in/out
3334 * port-C - rear line/mic-in
3335 * port-D - rear line/hp-out
3336 * port-A - front line/hp-out
3337 *
3338 * AD1984 = AD1884 + two digital mic-ins
3339 *
3340 * FIXME:
3341 * For simplicity, we share the single DAC for both HP and line-outs
3342 * right now.  The inidividual playbacks could be easily implemented,
3343 * but no build-up framework is given, so far.
3344 */
3345
3346static hda_nid_t ad1884_dac_nids[1] = {
3347        0x04,
3348};
3349
3350static hda_nid_t ad1884_adc_nids[2] = {
3351        0x08, 0x09,
3352};
3353
3354static hda_nid_t ad1884_capsrc_nids[2] = {
3355        0x0c, 0x0d,
3356};
3357
3358#define AD1884_SPDIF_OUT        0x02
3359
3360static struct hda_input_mux ad1884_capture_source = {
3361        .num_items = 4,
3362        .items = {
3363                { "Front Mic", 0x0 },
3364                { "Mic", 0x1 },
3365                { "CD", 0x2 },
3366                { "Mix", 0x3 },
3367        },
3368};
3369
3370static struct snd_kcontrol_new ad1884_base_mixers[] = {
3371        HDA_CODEC_VOLUME("PCM Playback Volume", 0x04, 0x0, HDA_OUTPUT),
3372        /* HDA_CODEC_VOLUME_IDX("PCM Playback Volume", 1, 0x03, 0x0, HDA_OUTPUT), */
3373        HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT),
3374        HDA_CODEC_MUTE("Front Playback Switch", 0x12, 0x0, HDA_OUTPUT),
3375        HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x13, 1, 0x0, HDA_OUTPUT),
3376        HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x13, 1, 0x0, HDA_OUTPUT),
3377        HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
3378        HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
3379        HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x01, HDA_INPUT),
3380        HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x01, HDA_INPUT),
3381        HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x02, HDA_INPUT),
3382        HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x02, HDA_INPUT),
3383        HDA_CODEC_VOLUME("Mic Boost Volume", 0x15, 0x0, HDA_INPUT),
3384        HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x14, 0x0, HDA_INPUT),
3385        HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
3386        HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
3387        HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT),
3388        HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x0d, 0x0, HDA_OUTPUT),
3389        {
3390                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3391                /* The multiple "Capture Source" controls confuse alsamixer
3392                 * So call somewhat different..
3393                 */
3394                /* .name = "Capture Source", */
3395                .name = "Input Source",
3396                .count = 2,
3397                .info = ad198x_mux_enum_info,
3398                .get = ad198x_mux_enum_get,
3399                .put = ad198x_mux_enum_put,
3400        },
3401        /* SPDIF controls */
3402        HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
3403        {
3404                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3405                .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
3406                /* identical with ad1983 */
3407                .info = ad1983_spdif_route_info,
3408                .get = ad1983_spdif_route_get,
3409                .put = ad1983_spdif_route_put,
3410        },
3411        { } /* end */
3412};
3413
3414static struct snd_kcontrol_new ad1984_dmic_mixers[] = {
3415        HDA_CODEC_VOLUME("Digital Mic Capture Volume", 0x05, 0x0, HDA_INPUT),
3416        HDA_CODEC_MUTE("Digital Mic Capture Switch", 0x05, 0x0, HDA_INPUT),
3417        HDA_CODEC_VOLUME_IDX("Digital Mic Capture Volume", 1, 0x06, 0x0,
3418                             HDA_INPUT),
3419        HDA_CODEC_MUTE_IDX("Digital Mic Capture Switch", 1, 0x06, 0x0,
3420                           HDA_INPUT),
3421        { } /* end */
3422};
3423
3424/*
3425 * initialization verbs
3426 */
3427static struct hda_verb ad1884_init_verbs[] = {
3428        /* DACs; mute as default */
3429        {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3430        {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3431        /* Port-A (HP) mixer */
3432        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3433        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3434        /* Port-A pin */
3435        {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3436        {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3437        /* HP selector - select DAC2 */
3438        {0x22, AC_VERB_SET_CONNECT_SEL, 0x1},
3439        /* Port-D (Line-out) mixer */
3440        {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3441        {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3442        /* Port-D pin */
3443        {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3444        {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3445        /* Mono-out mixer */
3446        {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3447        {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3448        /* Mono-out pin */
3449        {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3450        {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3451        /* Mono selector */
3452        {0x0e, AC_VERB_SET_CONNECT_SEL, 0x1},
3453        /* Port-B (front mic) pin */
3454        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3455        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3456        /* Port-C (rear mic) pin */
3457        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3458        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3459        /* Analog mixer; mute as default */
3460        {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3461        {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3462        {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3463        {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3464        /* Analog Mix output amp */
3465        {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x1f}, /* 0dB */
3466        /* SPDIF output selector */
3467        {0x02, AC_VERB_SET_CONNECT_SEL, 0x0}, /* PCM */
3468        {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */
3469        { } /* end */
3470};
3471
3472#ifdef CONFIG_SND_HDA_POWER_SAVE
3473static struct hda_amp_list ad1884_loopbacks[] = {
3474        { 0x20, HDA_INPUT, 0 }, /* Front Mic */
3475        { 0x20, HDA_INPUT, 1 }, /* Mic */
3476        { 0x20, HDA_INPUT, 2 }, /* CD */
3477        { 0x20, HDA_INPUT, 4 }, /* Docking */
3478        { } /* end */
3479};
3480#endif
3481
3482static const char * const ad1884_slave_vols[] = {
3483        "PCM Playback Volume",
3484        "Mic Playback Volume",
3485        "Mono Playback Volume",
3486        "Front Mic Playback Volume",
3487        "Mic Playback Volume",
3488        "CD Playback Volume",
3489        "Internal Mic Playback Volume",
3490        "Docking Mic Playback Volume",
3491        /* "Beep Playback Volume", */
3492        "IEC958 Playback Volume",
3493        NULL
3494};
3495
3496static int patch_ad1884(struct hda_codec *codec)
3497{
3498        struct ad198x_spec *spec;
3499        int err;
3500
3501        spec = kzalloc(sizeof(*spec), GFP_KERNEL);
3502        if (spec == NULL)
3503                return -ENOMEM;
3504
3505        codec->spec = spec;
3506
3507        err = snd_hda_attach_beep_device(codec, 0x10);
3508        if (err < 0) {
3509                ad198x_free(codec);
3510                return err;
3511        }
3512        set_beep_amp(spec, 0x10, 0, HDA_OUTPUT);
3513
3514        spec->multiout.max_channels = 2;
3515        spec->multiout.num_dacs = ARRAY_SIZE(ad1884_dac_nids);
3516        spec->multiout.dac_nids = ad1884_dac_nids;
3517        spec->multiout.dig_out_nid = AD1884_SPDIF_OUT;
3518        spec->num_adc_nids = ARRAY_SIZE(ad1884_adc_nids);
3519        spec->adc_nids = ad1884_adc_nids;
3520        spec->capsrc_nids = ad1884_capsrc_nids;
3521        spec->input_mux = &ad1884_capture_source;
3522        spec->num_mixers = 1;
3523        spec->mixers[0] = ad1884_base_mixers;
3524        spec->num_init_verbs = 1;
3525        spec->init_verbs[0] = ad1884_init_verbs;
3526        spec->spdif_route = 0;
3527#ifdef CONFIG_SND_HDA_POWER_SAVE
3528        spec->loopback.amplist = ad1884_loopbacks;
3529#endif
3530        spec->vmaster_nid = 0x04;
3531        /* we need to cover all playback volumes */
3532        spec->slave_vols = ad1884_slave_vols;
3533
3534        codec->patch_ops = ad198x_patch_ops;
3535
3536        codec->no_trigger_sense = 1;
3537        codec->no_sticky_stream = 1;
3538
3539        return 0;
3540}
3541
3542/*
3543 * Lenovo Thinkpad T61/X61
3544 */
3545static struct hda_input_mux ad1984_thinkpad_capture_source = {
3546        .num_items = 4,
3547        .items = {
3548                { "Mic", 0x0 },
3549                { "Internal Mic", 0x1 },
3550                { "Mix", 0x3 },
3551                { "Docking-Station", 0x4 },
3552        },
3553};
3554
3555
3556/*
3557 * Dell Precision T3400
3558 */
3559static struct hda_input_mux ad1984_dell_desktop_capture_source = {
3560        .num_items = 3,
3561        .items = {
3562                { "Front Mic", 0x0 },
3563                { "Line-In", 0x1 },
3564                { "Mix", 0x3 },
3565        },
3566};
3567
3568
3569static struct snd_kcontrol_new ad1984_thinkpad_mixers[] = {
3570        HDA_CODEC_VOLUME("PCM Playback Volume", 0x04, 0x0, HDA_OUTPUT),
3571        /* HDA_CODEC_VOLUME_IDX("PCM Playback Volume", 1, 0x03, 0x0, HDA_OUTPUT), */
3572        HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT),
3573        HDA_CODEC_MUTE("Speaker Playback Switch", 0x12, 0x0, HDA_OUTPUT),
3574        HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
3575        HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
3576        HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x20, 0x01, HDA_INPUT),
3577        HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x20, 0x01, HDA_INPUT),
3578        HDA_CODEC_VOLUME("Beep Playback Volume", 0x20, 0x03, HDA_INPUT),
3579        HDA_CODEC_MUTE("Beep Playback Switch", 0x20, 0x03, HDA_INPUT),
3580        HDA_CODEC_VOLUME("Docking Mic Playback Volume", 0x20, 0x04, HDA_INPUT),
3581        HDA_CODEC_MUTE("Docking Mic Playback Switch", 0x20, 0x04, HDA_INPUT),
3582        HDA_CODEC_VOLUME("Mic Boost Volume", 0x14, 0x0, HDA_INPUT),
3583        HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x15, 0x0, HDA_INPUT),
3584        HDA_CODEC_VOLUME("Dock Mic Boost Volume", 0x25, 0x0, HDA_OUTPUT),
3585        HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
3586        HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
3587        HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT),
3588        HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x0d, 0x0, HDA_OUTPUT),
3589        {
3590                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3591                /* The multiple "Capture Source" controls confuse alsamixer
3592                 * So call somewhat different..
3593                 */
3594                /* .name = "Capture Source", */
3595                .name = "Input Source",
3596                .count = 2,
3597                .info = ad198x_mux_enum_info,
3598                .get = ad198x_mux_enum_get,
3599                .put = ad198x_mux_enum_put,
3600        },
3601        /* SPDIF controls */
3602        HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
3603        {
3604                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3605                .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
3606                /* identical with ad1983 */
3607                .info = ad1983_spdif_route_info,
3608                .get = ad1983_spdif_route_get,
3609                .put = ad1983_spdif_route_put,
3610        },
3611        { } /* end */
3612};
3613
3614/* additional verbs */
3615static struct hda_verb ad1984_thinkpad_init_verbs[] = {
3616        /* Port-E (docking station mic) pin */
3617        {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3618        {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3619        /* docking mic boost */
3620        {0x25, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3621        /* Analog PC Beeper - allow firmware/ACPI beeps */
3622        {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3) | 0x1a},
3623        /* Analog mixer - docking mic; mute as default */
3624        {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3625        /* enable EAPD bit */
3626        {0x12, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
3627        { } /* end */
3628};
3629
3630/*
3631 * Dell Precision T3400
3632 */
3633static struct snd_kcontrol_new ad1984_dell_desktop_mixers[] = {
3634        HDA_CODEC_VOLUME("PCM Playback Volume", 0x04, 0x0, HDA_OUTPUT),
3635        HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT),
3636        HDA_CODEC_MUTE("Speaker Playback Switch", 0x12, 0x0, HDA_OUTPUT),
3637        HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x13, 1, 0x0, HDA_OUTPUT),
3638        HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x13, 1, 0x0, HDA_OUTPUT),
3639        HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
3640        HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
3641        HDA_CODEC_VOLUME("Line-In Playback Volume", 0x20, 0x01, HDA_INPUT),
3642        HDA_CODEC_MUTE("Line-In Playback Switch", 0x20, 0x01, HDA_INPUT),
3643        HDA_CODEC_VOLUME("Line-In Boost Volume", 0x15, 0x0, HDA_INPUT),
3644        HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x14, 0x0, HDA_INPUT),
3645        HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
3646        HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
3647        HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT),
3648        HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x0d, 0x0, HDA_OUTPUT),
3649        {
3650                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3651                /* The multiple "Capture Source" controls confuse alsamixer
3652                 * So call somewhat different..
3653                 */
3654                /* .name = "Capture Source", */
3655                .name = "Input Source",
3656                .count = 2,
3657                .info = ad198x_mux_enum_info,
3658                .get = ad198x_mux_enum_get,
3659                .put = ad198x_mux_enum_put,
3660        },
3661        { } /* end */
3662};
3663
3664/* Digial MIC ADC NID 0x05 + 0x06 */
3665static int ad1984_pcm_dmic_prepare(struct hda_pcm_stream *hinfo,
3666                                   struct hda_codec *codec,
3667                                   unsigned int stream_tag,
3668                                   unsigned int format,
3669                                   struct snd_pcm_substream *substream)
3670{
3671        snd_hda_codec_setup_stream(codec, 0x05 + substream->number,
3672                                   stream_tag, 0, format);
3673        return 0;
3674}
3675
3676static int ad1984_pcm_dmic_cleanup(struct hda_pcm_stream *hinfo,
3677                                   struct hda_codec *codec,
3678                                   struct snd_pcm_substream *substream)
3679{
3680        snd_hda_codec_cleanup_stream(codec, 0x05 + substream->number);
3681        return 0;
3682}
3683
3684static struct hda_pcm_stream ad1984_pcm_dmic_capture = {
3685        .substreams = 2,
3686        .channels_min = 2,
3687        .channels_max = 2,
3688        .nid = 0x05,
3689        .ops = {
3690                .prepare = ad1984_pcm_dmic_prepare,
3691                .cleanup = ad1984_pcm_dmic_cleanup
3692        },
3693};
3694
3695static int ad1984_build_pcms(struct hda_codec *codec)
3696{
3697        struct ad198x_spec *spec = codec->spec;
3698        struct hda_pcm *info;
3699        int err;
3700
3701        err = ad198x_build_pcms(codec);
3702        if (err < 0)
3703                return err;
3704
3705        info = spec->pcm_rec + codec->num_pcms;
3706        codec->num_pcms++;
3707        info->name = "AD1984 Digital Mic";
3708        info->stream[SNDRV_PCM_STREAM_CAPTURE] = ad1984_pcm_dmic_capture;
3709        return 0;
3710}
3711
3712/* models */
3713enum {
3714        AD1984_BASIC,
3715        AD1984_THINKPAD,
3716        AD1984_DELL_DESKTOP,
3717        AD1984_MODELS
3718};
3719
3720static const char * const ad1984_models[AD1984_MODELS] = {
3721        [AD1984_BASIC]          = "basic",
3722        [AD1984_THINKPAD]       = "thinkpad",
3723        [AD1984_DELL_DESKTOP]   = "dell_desktop",
3724};
3725
3726static struct snd_pci_quirk ad1984_cfg_tbl[] = {
3727        /* Lenovo Thinkpad T61/X61 */
3728        SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo Thinkpad", AD1984_THINKPAD),
3729        SND_PCI_QUIRK(0x1028, 0x0214, "Dell T3400", AD1984_DELL_DESKTOP),
3730        SND_PCI_QUIRK(0x1028, 0x0233, "Dell Latitude E6400", AD1984_DELL_DESKTOP),
3731        {}
3732};
3733
3734static int patch_ad1984(struct hda_codec *codec)
3735{
3736        struct ad198x_spec *spec;
3737        int board_config, err;
3738
3739        err = patch_ad1884(codec);
3740        if (err < 0)
3741                return err;
3742        spec = codec->spec;
3743        board_config = snd_hda_check_board_config(codec, AD1984_MODELS,
3744                                                  ad1984_models, ad1984_cfg_tbl);
3745        switch (board_config) {
3746        case AD1984_BASIC:
3747                /* additional digital mics */
3748                spec->mixers[spec->num_mixers++] = ad1984_dmic_mixers;
3749                codec->patch_ops.build_pcms = ad1984_build_pcms;
3750                break;
3751        case AD1984_THINKPAD:
3752                if (codec->subsystem_id == 0x17aa20fb) {
3753                        /* Thinpad X300 does not have the ability to do SPDIF,
3754                           or attach to docking station to use SPDIF */
3755                        spec->multiout.dig_out_nid = 0;
3756                } else
3757                        spec->multiout.dig_out_nid = AD1884_SPDIF_OUT;
3758                spec->input_mux = &ad1984_thinkpad_capture_source;
3759                spec->mixers[0] = ad1984_thinkpad_mixers;
3760                spec->init_verbs[spec->num_init_verbs++] = ad1984_thinkpad_init_verbs;
3761                spec->analog_beep = 1;
3762                break;
3763        case AD1984_DELL_DESKTOP:
3764                spec->multiout.dig_out_nid = 0;
3765                spec->input_mux = &ad1984_dell_desktop_capture_source;
3766                spec->mixers[0] = ad1984_dell_desktop_mixers;
3767                break;
3768        }
3769        return 0;
3770}
3771
3772
3773/*
3774 * AD1883 / AD1884A / AD1984A / AD1984B
3775 *
3776 * port-B (0x14) - front mic-in
3777 * port-E (0x1c) - rear mic-in
3778 * port-F (0x16) - CD / ext out
3779 * port-C (0x15) - rear line-in
3780 * port-D (0x12) - rear line-out
3781 * port-A (0x11) - front hp-out
3782 *
3783 * AD1984A = AD1884A + digital-mic
3784 * AD1883 = equivalent with AD1984A
3785 * AD1984B = AD1984A + extra SPDIF-out
3786 *
3787 * FIXME:
3788 * We share the single DAC for both HP and line-outs (see AD1884/1984).
3789 */
3790
3791static hda_nid_t ad1884a_dac_nids[1] = {
3792        0x03,
3793};
3794
3795#define ad1884a_adc_nids        ad1884_adc_nids
3796#define ad1884a_capsrc_nids     ad1884_capsrc_nids
3797
3798#define AD1884A_SPDIF_OUT       0x02
3799
3800static struct hda_input_mux ad1884a_capture_source = {
3801        .num_items = 5,
3802        .items = {
3803                { "Front Mic", 0x0 },
3804                { "Mic", 0x4 },
3805                { "Line", 0x1 },
3806                { "CD", 0x2 },
3807                { "Mix", 0x3 },
3808        },
3809};
3810
3811static struct snd_kcontrol_new ad1884a_base_mixers[] = {
3812        HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT),
3813        HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT),
3814        HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT),
3815        HDA_CODEC_MUTE("Front Playback Switch", 0x12, 0x0, HDA_OUTPUT),
3816        HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x13, 1, 0x0, HDA_OUTPUT),
3817        HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x13, 1, 0x0, HDA_OUTPUT),
3818        HDA_CODEC_VOLUME("PCM Playback Volume", 0x20, 0x5, HDA_INPUT),
3819        HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT),
3820        HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
3821        HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
3822        HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x01, HDA_INPUT),
3823        HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x01, HDA_INPUT),
3824        HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x04, HDA_INPUT),
3825        HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x04, HDA_INPUT),
3826        HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x02, HDA_INPUT),
3827        HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x02, HDA_INPUT),
3828        HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x14, 0x0, HDA_INPUT),
3829        HDA_CODEC_VOLUME("Line Boost Volume", 0x15, 0x0, HDA_INPUT),
3830        HDA_CODEC_VOLUME("Mic Boost Volume", 0x25, 0x0, HDA_OUTPUT),
3831        HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
3832        HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
3833        HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT),
3834        HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x0d, 0x0, HDA_OUTPUT),
3835        {
3836                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3837                /* The multiple "Capture Source" controls confuse alsamixer
3838                 * So call somewhat different..
3839                 */
3840                /* .name = "Capture Source", */
3841                .name = "Input Source",
3842                .count = 2,
3843                .info = ad198x_mux_enum_info,
3844                .get = ad198x_mux_enum_get,
3845                .put = ad198x_mux_enum_put,
3846        },
3847        /* SPDIF controls */
3848        HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
3849        {
3850                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3851                .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
3852                /* identical with ad1983 */
3853                .info = ad1983_spdif_route_info,
3854                .get = ad1983_spdif_route_get,
3855                .put = ad1983_spdif_route_put,
3856        },
3857        { } /* end */
3858};
3859
3860/*
3861 * initialization verbs
3862 */
3863static struct hda_verb ad1884a_init_verbs[] = {
3864        /* DACs; unmute as default */
3865        {0x03, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */
3866        {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */
3867        /* Port-A (HP) mixer - route only from analog mixer */
3868        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3869        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3870        /* Port-A pin */
3871        {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3872        {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3873        /* Port-D (Line-out) mixer - route only from analog mixer */
3874        {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3875        {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3876        /* Port-D pin */
3877        {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3878        {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3879        /* Mono-out mixer - route only from analog mixer */
3880        {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3881        {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3882        /* Mono-out pin */
3883        {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3884        {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3885        /* Port-B (front mic) pin */
3886        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3887        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3888        /* Port-C (rear line-in) pin */
3889        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3890        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3891        /* Port-E (rear mic) pin */
3892        {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3893        {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3894        {0x25, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, /* no boost */
3895        /* Port-F (CD) pin */
3896        {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3897        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3898        /* Analog mixer; mute as default */
3899        {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3900        {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3901        {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3902        {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3903        {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, /* aux */
3904        {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
3905        /* Analog Mix output amp */
3906        {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3907        /* capture sources */
3908        {0x0c, AC_VERB_SET_CONNECT_SEL, 0x0},
3909        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3910        {0x0d, AC_VERB_SET_CONNECT_SEL, 0x0},
3911        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3912        /* SPDIF output amp */
3913        {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */
3914        { } /* end */
3915};
3916
3917#ifdef CONFIG_SND_HDA_POWER_SAVE
3918static struct hda_amp_list ad1884a_loopbacks[] = {
3919        { 0x20, HDA_INPUT, 0 }, /* Front Mic */
3920        { 0x20, HDA_INPUT, 1 }, /* Mic */
3921        { 0x20, HDA_INPUT, 2 }, /* CD */
3922        { 0x20, HDA_INPUT, 4 }, /* Docking */
3923        { } /* end */
3924};
3925#endif
3926
3927/*
3928 * Laptop model
3929 *
3930 * Port A: Headphone jack
3931 * Port B: MIC jack
3932 * Port C: Internal MIC
3933 * Port D: Dock Line Out (if enabled)
3934 * Port E: Dock Line In (if enabled)
3935 * Port F: Internal speakers
3936 */
3937
3938static int ad1884a_mobile_master_sw_put(struct snd_kcontrol *kcontrol,
3939                                        struct snd_ctl_elem_value *ucontrol)
3940{
3941        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3942        int ret = snd_hda_mixer_amp_switch_put(kcontrol, ucontrol);
3943        int mute = (!ucontrol->value.integer.value[0] &&
3944                    !ucontrol->value.integer.value[1]);
3945        /* toggle GPIO1 according to the mute state */
3946        snd_hda_codec_write_cache(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA,
3947                            mute ? 0x02 : 0x0);
3948        return ret;
3949}
3950
3951static struct snd_kcontrol_new ad1884a_laptop_mixers[] = {
3952        HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT),
3953        {
3954                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3955                .name = "Master Playback Switch",
3956                .subdevice = HDA_SUBDEV_AMP_FLAG,
3957                .info = snd_hda_mixer_amp_switch_info,
3958                .get = snd_hda_mixer_amp_switch_get,
3959                .put = ad1884a_mobile_master_sw_put,
3960                .private_value = HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
3961        },
3962        HDA_CODEC_MUTE("Dock Playback Switch", 0x12, 0x0, HDA_OUTPUT),
3963        HDA_CODEC_VOLUME("PCM Playback Volume", 0x20, 0x5, HDA_INPUT),
3964        HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT),
3965        HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
3966        HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
3967        HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x20, 0x01, HDA_INPUT),
3968        HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x20, 0x01, HDA_INPUT),
3969        HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x20, 0x04, HDA_INPUT),
3970        HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x20, 0x04, HDA_INPUT),
3971        HDA_CODEC_VOLUME("Mic Boost Volume", 0x14, 0x0, HDA_INPUT),
3972        HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x15, 0x0, HDA_INPUT),
3973        HDA_CODEC_VOLUME("Dock Mic Boost Volume", 0x25, 0x0, HDA_OUTPUT),
3974        HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
3975        HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
3976        { } /* end */
3977};
3978
3979static struct snd_kcontrol_new ad1884a_mobile_mixers[] = {
3980        HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT),
3981        /*HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT),*/
3982        {
3983                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3984                .name = "Master Playback Switch",
3985                .subdevice = HDA_SUBDEV_AMP_FLAG,
3986                .info = snd_hda_mixer_amp_switch_info,
3987                .get = snd_hda_mixer_amp_switch_get,
3988                .put = ad1884a_mobile_master_sw_put,
3989                .private_value = HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
3990        },
3991        HDA_CODEC_VOLUME("PCM Playback Volume", 0x20, 0x5, HDA_INPUT),
3992        HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT),
3993        HDA_CODEC_VOLUME("Mic Capture Volume", 0x14, 0x0, HDA_INPUT),
3994        HDA_CODEC_VOLUME("Internal Mic Capture Volume", 0x15, 0x0, HDA_INPUT),
3995        HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
3996        HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
3997        { } /* end */
3998};
3999
4000/* mute internal speaker if HP is plugged */
4001static void ad1884a_hp_automute(struct hda_codec *codec)
4002{
4003        unsigned int present;
4004
4005        present = snd_hda_jack_detect(codec, 0x11);
4006        snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
4007                                 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
4008        snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_EAPD_BTLENABLE,
4009                            present ? 0x00 : 0x02);
4010}
4011
4012/* switch to external mic if plugged */
4013static void ad1884a_hp_automic(struct hda_codec *codec)
4014{
4015        unsigned int present;
4016
4017        present = snd_hda_jack_detect(codec, 0x14);
4018        snd_hda_codec_write(codec, 0x0c, 0, AC_VERB_SET_CONNECT_SEL,
4019                            present ? 0 : 1);
4020}
4021
4022#define AD1884A_HP_EVENT                0x37
4023#define AD1884A_MIC_EVENT               0x36
4024
4025/* unsolicited event for HP jack sensing */
4026static void ad1884a_hp_unsol_event(struct hda_codec *codec, unsigned int res)
4027{
4028        switch (res >> 26) {
4029        case AD1884A_HP_EVENT:
4030                ad1884a_hp_automute(codec);
4031                break;
4032        case AD1884A_MIC_EVENT:
4033                ad1884a_hp_automic(codec);
4034                break;
4035        }
4036}
4037
4038/* initialize jack-sensing, too */
4039static int ad1884a_hp_init(struct hda_codec *codec)
4040{
4041        ad198x_init(codec);
4042        ad1884a_hp_automute(codec);
4043        ad1884a_hp_automic(codec);
4044        return 0;
4045}
4046
4047/* mute internal speaker if HP or docking HP is plugged */
4048static void ad1884a_laptop_automute(struct hda_codec *codec)
4049{
4050        unsigned int present;
4051
4052        present = snd_hda_jack_detect(codec, 0x11);
4053        if (!present)
4054                present = snd_hda_jack_detect(codec, 0x12);
4055        snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
4056                                 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
4057        snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_EAPD_BTLENABLE,
4058                            present ? 0x00 : 0x02);
4059}
4060
4061/* switch to external mic if plugged */
4062static void ad1884a_laptop_automic(struct hda_codec *codec)
4063{
4064        unsigned int idx;
4065
4066        if (snd_hda_jack_detect(codec, 0x14))
4067                idx = 0;
4068        else if (snd_hda_jack_detect(codec, 0x1c))
4069                idx = 4;
4070        else
4071                idx = 1;
4072        snd_hda_codec_write(codec, 0x0c, 0, AC_VERB_SET_CONNECT_SEL, idx);
4073}
4074
4075/* unsolicited event for HP jack sensing */
4076static void ad1884a_laptop_unsol_event(struct hda_codec *codec,
4077                                       unsigned int res)
4078{
4079        switch (res >> 26) {
4080        case AD1884A_HP_EVENT:
4081                ad1884a_laptop_automute(codec);
4082                break;
4083        case AD1884A_MIC_EVENT:
4084                ad1884a_laptop_automic(codec);
4085                break;
4086        }
4087}
4088
4089/* initialize jack-sensing, too */
4090static int ad1884a_laptop_init(struct hda_codec *codec)
4091{
4092        ad198x_init(codec);
4093        ad1884a_laptop_automute(codec);
4094        ad1884a_laptop_automic(codec);
4095        return 0;
4096}
4097
4098/* additional verbs for laptop model */
4099static struct hda_verb ad1884a_laptop_verbs[] = {
4100        /* Port-A (HP) pin - always unmuted */
4101        {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4102        /* Port-F (int speaker) mixer - route only from analog mixer */
4103        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4104        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4105        /* Port-F (int speaker) pin */
4106        {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4107        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4108        /* required for compaq 6530s/6531s speaker output */
4109        {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4110        /* Port-C pin - internal mic-in */
4111        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4112        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7002}, /* raise mic as default */
4113        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x7002}, /* raise mic as default */
4114        /* Port-D (docking line-out) pin - default unmuted */
4115        {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4116        /* analog mix */
4117        {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4118        /* unsolicited event for pin-sense */
4119        {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_HP_EVENT},
4120        {0x12, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_HP_EVENT},
4121        {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_MIC_EVENT},
4122        {0x1c, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_MIC_EVENT},
4123        /* allow to touch GPIO1 (for mute control) */
4124        {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
4125        {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
4126        {0x01, AC_VERB_SET_GPIO_DATA, 0x02}, /* first muted */
4127        { } /* end */
4128};
4129
4130static struct hda_verb ad1884a_mobile_verbs[] = {
4131        /* DACs; unmute as default */
4132        {0x03, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */
4133        {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */
4134        /* Port-A (HP) mixer - route only from analog mixer */
4135        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4136        {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4137        /* Port-A pin */
4138        {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4139        /* Port-A (HP) pin - always unmuted */
4140        {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4141        /* Port-B (mic jack) pin */
4142        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4143        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7002}, /* raise mic as default */
4144        /* Port-C (int mic) pin */
4145        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4146        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x7002}, /* raise mic as default */
4147        /* Port-F (int speaker) mixer - route only from analog mixer */
4148        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4149        {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4150        /* Port-F pin */
4151        {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4152        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4153        /* Analog mixer; mute as default */
4154        {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4155        {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4156        {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4157        {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4158        {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4159        {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
4160        /* Analog Mix output amp */
4161        {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4162        /* capture sources */
4163        /* {0x0c, AC_VERB_SET_CONNECT_SEL, 0x0}, */ /* set via unsol */
4164        {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4165        {0x0d, AC_VERB_SET_CONNECT_SEL, 0x0},
4166        {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4167        /* unsolicited event for pin-sense */
4168        {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_HP_EVENT},
4169        {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_MIC_EVENT},
4170        /* allow to touch GPIO1 (for mute control) */
4171        {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
4172        {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
4173        {0x01, AC_VERB_SET_GPIO_DATA, 0x02}, /* first muted */
4174        { } /* end */
4175};
4176
4177/*
4178 * Thinkpad X300
4179 * 0x11 - HP
4180 * 0x12 - speaker
4181 * 0x14 - mic-in
4182 * 0x17 - built-in mic
4183 */
4184
4185static struct hda_verb ad1984a_thinkpad_verbs[] = {
4186        /* HP unmute */
4187        {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4188        /* analog mix */
4189        {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4190        /* turn on EAPD */
4191        {0x12, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
4192        /* unsolicited event for pin-sense */
4193        {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_HP_EVENT},
4194        /* internal mic - dmic */
4195        {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4196        /* set magic COEFs for dmic */
4197        {0x01, AC_VERB_SET_COEF_INDEX, 0x13f7},
4198        {0x01, AC_VERB_SET_PROC_COEF, 0x08},
4199        { } /* end */
4200};
4201
4202static struct snd_kcontrol_new ad1984a_thinkpad_mixers[] = {
4203        HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT),
4204        HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT),
4205        HDA_CODEC_VOLUME("PCM Playback Volume", 0x20, 0x5, HDA_INPUT),
4206        HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT),
4207        HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
4208        HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
4209        HDA_CODEC_VOLUME("Mic Boost Volume", 0x14, 0x0, HDA_INPUT),
4210        HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x17, 0x0, HDA_INPUT),
4211        HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
4212        HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
4213        {
4214                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4215                .name = "Capture Source",
4216                .info = ad198x_mux_enum_info,
4217                .get = ad198x_mux_enum_get,
4218                .put = ad198x_mux_enum_put,
4219        },
4220        { } /* end */
4221};
4222
4223static struct hda_input_mux ad1984a_thinkpad_capture_source = {
4224        .num_items = 3,
4225        .items = {
4226                { "Mic", 0x0 },
4227                { "Internal Mic", 0x5 },
4228                { "Mix", 0x3 },
4229        },
4230};
4231
4232/* mute internal speaker if HP is plugged */
4233static void ad1984a_thinkpad_automute(struct hda_codec *codec)
4234{
4235        unsigned int present;
4236
4237        present = snd_hda_jack_detect(codec, 0x11);
4238        snd_hda_codec_amp_stereo(codec, 0x12, HDA_OUTPUT, 0,
4239                                 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
4240}
4241