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