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