linux/sound/pci/hda/patch_conexant.c
<<
>>
Prefs
   1/*
   2 * HD audio interface patch for Conexant HDA audio codec
   3 *
   4 * Copyright (c) 2006 Pototskiy Akex <alex.pototskiy@gmail.com>
   5 *                    Takashi Iwai <tiwai@suse.de>
   6 *                    Tobin Davis  <tdavis@dsl-only.net>
   7 *
   8 *  This driver is free software; you can redistribute it and/or modify
   9 *  it under the terms of the GNU General Public License as published by
  10 *  the Free Software Foundation; either version 2 of the License, or
  11 *  (at your option) any later version.
  12 *
  13 *  This driver is distributed in the hope that it will be useful,
  14 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  15 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16 *  GNU General Public License for more details.
  17 *
  18 *  You should have received a copy of the GNU General Public License
  19 *  along with this program; if not, write to the Free Software
  20 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  21 */
  22
  23#include <linux/init.h>
  24#include <linux/delay.h>
  25#include <linux/slab.h>
  26#include <linux/pci.h>
  27#include <sound/core.h>
  28#include <sound/jack.h>
  29
  30#include "hda_codec.h"
  31#include "hda_local.h"
  32
  33#define CXT_PIN_DIR_IN              0x00
  34#define CXT_PIN_DIR_OUT             0x01
  35#define CXT_PIN_DIR_INOUT           0x02
  36#define CXT_PIN_DIR_IN_NOMICBIAS    0x03
  37#define CXT_PIN_DIR_INOUT_NOMICBIAS 0x04
  38
  39#define CONEXANT_HP_EVENT       0x37
  40#define CONEXANT_MIC_EVENT      0x38
  41
  42/* Conexant 5051 specific */
  43
  44#define CXT5051_SPDIF_OUT       0x1C
  45#define CXT5051_PORTB_EVENT     0x38
  46#define CXT5051_PORTC_EVENT     0x39
  47
  48
  49struct conexant_jack {
  50
  51        hda_nid_t nid;
  52        int type;
  53        struct snd_jack *jack;
  54
  55};
  56
  57struct conexant_spec {
  58
  59        struct snd_kcontrol_new *mixers[5];
  60        int num_mixers;
  61        hda_nid_t vmaster_nid;
  62
  63        const struct hda_verb *init_verbs[5];   /* initialization verbs
  64                                                 * don't forget NULL
  65                                                 * termination!
  66                                                 */
  67        unsigned int num_init_verbs;
  68
  69        /* playback */
  70        struct hda_multi_out multiout;  /* playback set-up
  71                                         * max_channels, dacs must be set
  72                                         * dig_out_nid and hp_nid are optional
  73                                         */
  74        unsigned int cur_eapd;
  75        unsigned int hp_present;
  76        unsigned int no_auto_mic;
  77        unsigned int need_dac_fix;
  78
  79        /* capture */
  80        unsigned int num_adc_nids;
  81        hda_nid_t *adc_nids;
  82        hda_nid_t dig_in_nid;           /* digital-in NID; optional */
  83
  84        unsigned int cur_adc_idx;
  85        hda_nid_t cur_adc;
  86        unsigned int cur_adc_stream_tag;
  87        unsigned int cur_adc_format;
  88
  89        /* capture source */
  90        const struct hda_input_mux *input_mux;
  91        hda_nid_t *capsrc_nids;
  92        unsigned int cur_mux[3];
  93
  94        /* channel model */
  95        const struct hda_channel_mode *channel_mode;
  96        int num_channel_mode;
  97
  98        /* PCM information */
  99        struct hda_pcm pcm_rec[2];      /* used in build_pcms() */
 100
 101        unsigned int spdif_route;
 102
 103        /* jack detection */
 104        struct snd_array jacks;
 105
 106        /* dynamic controls, init_verbs and input_mux */
 107        struct auto_pin_cfg autocfg;
 108        struct hda_input_mux private_imux;
 109        hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
 110
 111        unsigned int dell_automute;
 112        unsigned int port_d_mode;
 113        unsigned char ext_mic_bias;
 114};
 115
 116static int conexant_playback_pcm_open(struct hda_pcm_stream *hinfo,
 117                                      struct hda_codec *codec,
 118                                      struct snd_pcm_substream *substream)
 119{
 120        struct conexant_spec *spec = codec->spec;
 121        return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
 122                                             hinfo);
 123}
 124
 125static int conexant_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
 126                                         struct hda_codec *codec,
 127                                         unsigned int stream_tag,
 128                                         unsigned int format,
 129                                         struct snd_pcm_substream *substream)
 130{
 131        struct conexant_spec *spec = codec->spec;
 132        return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
 133                                                stream_tag,
 134                                                format, substream);
 135}
 136
 137static int conexant_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
 138                                         struct hda_codec *codec,
 139                                         struct snd_pcm_substream *substream)
 140{
 141        struct conexant_spec *spec = codec->spec;
 142        return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
 143}
 144
 145/*
 146 * Digital out
 147 */
 148static int conexant_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
 149                                          struct hda_codec *codec,
 150                                          struct snd_pcm_substream *substream)
 151{
 152        struct conexant_spec *spec = codec->spec;
 153        return snd_hda_multi_out_dig_open(codec, &spec->multiout);
 154}
 155
 156static int conexant_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
 157                                         struct hda_codec *codec,
 158                                         struct snd_pcm_substream *substream)
 159{
 160        struct conexant_spec *spec = codec->spec;
 161        return snd_hda_multi_out_dig_close(codec, &spec->multiout);
 162}
 163
 164static int conexant_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
 165                                         struct hda_codec *codec,
 166                                         unsigned int stream_tag,
 167                                         unsigned int format,
 168                                         struct snd_pcm_substream *substream)
 169{
 170        struct conexant_spec *spec = codec->spec;
 171        return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
 172                                             stream_tag,
 173                                             format, substream);
 174}
 175
 176/*
 177 * Analog capture
 178 */
 179static int conexant_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
 180                                      struct hda_codec *codec,
 181                                      unsigned int stream_tag,
 182                                      unsigned int format,
 183                                      struct snd_pcm_substream *substream)
 184{
 185        struct conexant_spec *spec = codec->spec;
 186        snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
 187                                   stream_tag, 0, format);
 188        return 0;
 189}
 190
 191static int conexant_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
 192                                      struct hda_codec *codec,
 193                                      struct snd_pcm_substream *substream)
 194{
 195        struct conexant_spec *spec = codec->spec;
 196        snd_hda_codec_cleanup_stream(codec, spec->adc_nids[substream->number]);
 197        return 0;
 198}
 199
 200
 201
 202static struct hda_pcm_stream conexant_pcm_analog_playback = {
 203        .substreams = 1,
 204        .channels_min = 2,
 205        .channels_max = 2,
 206        .nid = 0, /* fill later */
 207        .ops = {
 208                .open = conexant_playback_pcm_open,
 209                .prepare = conexant_playback_pcm_prepare,
 210                .cleanup = conexant_playback_pcm_cleanup
 211        },
 212};
 213
 214static struct hda_pcm_stream conexant_pcm_analog_capture = {
 215        .substreams = 1,
 216        .channels_min = 2,
 217        .channels_max = 2,
 218        .nid = 0, /* fill later */
 219        .ops = {
 220                .prepare = conexant_capture_pcm_prepare,
 221                .cleanup = conexant_capture_pcm_cleanup
 222        },
 223};
 224
 225
 226static struct hda_pcm_stream conexant_pcm_digital_playback = {
 227        .substreams = 1,
 228        .channels_min = 2,
 229        .channels_max = 2,
 230        .nid = 0, /* fill later */
 231        .ops = {
 232                .open = conexant_dig_playback_pcm_open,
 233                .close = conexant_dig_playback_pcm_close,
 234                .prepare = conexant_dig_playback_pcm_prepare
 235        },
 236};
 237
 238static struct hda_pcm_stream conexant_pcm_digital_capture = {
 239        .substreams = 1,
 240        .channels_min = 2,
 241        .channels_max = 2,
 242        /* NID is set in alc_build_pcms */
 243};
 244
 245static int cx5051_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
 246                                      struct hda_codec *codec,
 247                                      unsigned int stream_tag,
 248                                      unsigned int format,
 249                                      struct snd_pcm_substream *substream)
 250{
 251        struct conexant_spec *spec = codec->spec;
 252        spec->cur_adc = spec->adc_nids[spec->cur_adc_idx];
 253        spec->cur_adc_stream_tag = stream_tag;
 254        spec->cur_adc_format = format;
 255        snd_hda_codec_setup_stream(codec, spec->cur_adc, stream_tag, 0, format);
 256        return 0;
 257}
 258
 259static int cx5051_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
 260                                      struct hda_codec *codec,
 261                                      struct snd_pcm_substream *substream)
 262{
 263        struct conexant_spec *spec = codec->spec;
 264        snd_hda_codec_cleanup_stream(codec, spec->cur_adc);
 265        spec->cur_adc = 0;
 266        return 0;
 267}
 268
 269static struct hda_pcm_stream cx5051_pcm_analog_capture = {
 270        .substreams = 1,
 271        .channels_min = 2,
 272        .channels_max = 2,
 273        .nid = 0, /* fill later */
 274        .ops = {
 275                .prepare = cx5051_capture_pcm_prepare,
 276                .cleanup = cx5051_capture_pcm_cleanup
 277        },
 278};
 279
 280static int conexant_build_pcms(struct hda_codec *codec)
 281{
 282        struct conexant_spec *spec = codec->spec;
 283        struct hda_pcm *info = spec->pcm_rec;
 284
 285        codec->num_pcms = 1;
 286        codec->pcm_info = info;
 287
 288        info->name = "CONEXANT Analog";
 289        info->stream[SNDRV_PCM_STREAM_PLAYBACK] = conexant_pcm_analog_playback;
 290        info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max =
 291                spec->multiout.max_channels;
 292        info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
 293                spec->multiout.dac_nids[0];
 294        if (codec->vendor_id == 0x14f15051)
 295                info->stream[SNDRV_PCM_STREAM_CAPTURE] =
 296                        cx5051_pcm_analog_capture;
 297        else
 298                info->stream[SNDRV_PCM_STREAM_CAPTURE] =
 299                        conexant_pcm_analog_capture;
 300        info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = spec->num_adc_nids;
 301        info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
 302
 303        if (spec->multiout.dig_out_nid) {
 304                info++;
 305                codec->num_pcms++;
 306                info->name = "Conexant Digital";
 307                info->pcm_type = HDA_PCM_TYPE_SPDIF;
 308                info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
 309                        conexant_pcm_digital_playback;
 310                info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
 311                        spec->multiout.dig_out_nid;
 312                if (spec->dig_in_nid) {
 313                        info->stream[SNDRV_PCM_STREAM_CAPTURE] =
 314                                conexant_pcm_digital_capture;
 315                        info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
 316                                spec->dig_in_nid;
 317                }
 318        }
 319
 320        return 0;
 321}
 322
 323static int conexant_mux_enum_info(struct snd_kcontrol *kcontrol,
 324                                  struct snd_ctl_elem_info *uinfo)
 325{
 326        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 327        struct conexant_spec *spec = codec->spec;
 328
 329        return snd_hda_input_mux_info(spec->input_mux, uinfo);
 330}
 331
 332static int conexant_mux_enum_get(struct snd_kcontrol *kcontrol,
 333                                 struct snd_ctl_elem_value *ucontrol)
 334{
 335        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 336        struct conexant_spec *spec = codec->spec;
 337        unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
 338
 339        ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
 340        return 0;
 341}
 342
 343static int conexant_mux_enum_put(struct snd_kcontrol *kcontrol,
 344                                 struct snd_ctl_elem_value *ucontrol)
 345{
 346        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 347        struct conexant_spec *spec = codec->spec;
 348        unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
 349
 350        return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol,
 351                                     spec->capsrc_nids[adc_idx],
 352                                     &spec->cur_mux[adc_idx]);
 353}
 354
 355#ifdef CONFIG_SND_HDA_INPUT_JACK
 356static void conexant_free_jack_priv(struct snd_jack *jack)
 357{
 358        struct conexant_jack *jacks = jack->private_data;
 359        jacks->nid = 0;
 360        jacks->jack = NULL;
 361}
 362
 363static int conexant_add_jack(struct hda_codec *codec,
 364                hda_nid_t nid, int type)
 365{
 366        struct conexant_spec *spec;
 367        struct conexant_jack *jack;
 368        const char *name;
 369        int err;
 370
 371        spec = codec->spec;
 372        snd_array_init(&spec->jacks, sizeof(*jack), 32);
 373        jack = snd_array_new(&spec->jacks);
 374        name = (type == SND_JACK_HEADPHONE) ? "Headphone" : "Mic" ;
 375
 376        if (!jack)
 377                return -ENOMEM;
 378
 379        jack->nid = nid;
 380        jack->type = type;
 381
 382        err = snd_jack_new(codec->bus->card, name, type, &jack->jack);
 383        if (err < 0)
 384                return err;
 385        jack->jack->private_data = jack;
 386        jack->jack->private_free = conexant_free_jack_priv;
 387        return 0;
 388}
 389
 390static void conexant_report_jack(struct hda_codec *codec, hda_nid_t nid)
 391{
 392        struct conexant_spec *spec = codec->spec;
 393        struct conexant_jack *jacks = spec->jacks.list;
 394
 395        if (jacks) {
 396                int i;
 397                for (i = 0; i < spec->jacks.used; i++) {
 398                        if (jacks->nid == nid) {
 399                                unsigned int present;
 400                                present = snd_hda_codec_read(codec, nid, 0,
 401                                                AC_VERB_GET_PIN_SENSE, 0) &
 402                                        AC_PINSENSE_PRESENCE;
 403
 404                                present = (present) ? jacks->type : 0 ;
 405
 406                                snd_jack_report(jacks->jack,
 407                                                present);
 408                        }
 409                        jacks++;
 410                }
 411        }
 412}
 413
 414static int conexant_init_jacks(struct hda_codec *codec)
 415{
 416        struct conexant_spec *spec = codec->spec;
 417        int i;
 418
 419        for (i = 0; i < spec->num_init_verbs; i++) {
 420                const struct hda_verb *hv;
 421
 422                hv = spec->init_verbs[i];
 423                while (hv->nid) {
 424                        int err = 0;
 425                        switch (hv->param ^ AC_USRSP_EN) {
 426                        case CONEXANT_HP_EVENT:
 427                                err = conexant_add_jack(codec, hv->nid,
 428                                                SND_JACK_HEADPHONE);
 429                                conexant_report_jack(codec, hv->nid);
 430                                break;
 431                        case CXT5051_PORTC_EVENT:
 432                        case CONEXANT_MIC_EVENT:
 433                                err = conexant_add_jack(codec, hv->nid,
 434                                                SND_JACK_MICROPHONE);
 435                                conexant_report_jack(codec, hv->nid);
 436                                break;
 437                        }
 438                        if (err < 0)
 439                                return err;
 440                        ++hv;
 441                }
 442        }
 443        return 0;
 444
 445}
 446#else
 447static inline void conexant_report_jack(struct hda_codec *codec, hda_nid_t nid)
 448{
 449}
 450
 451static inline int conexant_init_jacks(struct hda_codec *codec)
 452{
 453        return 0;
 454}
 455#endif
 456
 457static int conexant_init(struct hda_codec *codec)
 458{
 459        struct conexant_spec *spec = codec->spec;
 460        int i;
 461
 462        for (i = 0; i < spec->num_init_verbs; i++)
 463                snd_hda_sequence_write(codec, spec->init_verbs[i]);
 464        return 0;
 465}
 466
 467static void conexant_free(struct hda_codec *codec)
 468{
 469#ifdef CONFIG_SND_HDA_INPUT_JACK
 470        struct conexant_spec *spec = codec->spec;
 471        if (spec->jacks.list) {
 472                struct conexant_jack *jacks = spec->jacks.list;
 473                int i;
 474                for (i = 0; i < spec->jacks.used; i++, jacks++) {
 475                        if (jacks->jack)
 476                                snd_device_free(codec->bus->card, jacks->jack);
 477                }
 478                snd_array_free(&spec->jacks);
 479        }
 480#endif
 481        kfree(codec->spec);
 482}
 483
 484static struct snd_kcontrol_new cxt_capture_mixers[] = {
 485        {
 486                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 487                .name = "Capture Source",
 488                .info = conexant_mux_enum_info,
 489                .get = conexant_mux_enum_get,
 490                .put = conexant_mux_enum_put
 491        },
 492        {}
 493};
 494
 495static const char *slave_vols[] = {
 496        "Headphone Playback Volume",
 497        "Speaker Playback Volume",
 498        NULL
 499};
 500
 501static const char *slave_sws[] = {
 502        "Headphone Playback Switch",
 503        "Speaker Playback Switch",
 504        NULL
 505};
 506
 507static int conexant_build_controls(struct hda_codec *codec)
 508{
 509        struct conexant_spec *spec = codec->spec;
 510        unsigned int i;
 511        int err;
 512
 513        for (i = 0; i < spec->num_mixers; i++) {
 514                err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
 515                if (err < 0)
 516                        return err;
 517        }
 518        if (spec->multiout.dig_out_nid) {
 519                err = snd_hda_create_spdif_out_ctls(codec,
 520                                                    spec->multiout.dig_out_nid);
 521                if (err < 0)
 522                        return err;
 523                err = snd_hda_create_spdif_share_sw(codec,
 524                                                    &spec->multiout);
 525                if (err < 0)
 526                        return err;
 527                spec->multiout.share_spdif = 1;
 528        } 
 529        if (spec->dig_in_nid) {
 530                err = snd_hda_create_spdif_in_ctls(codec,spec->dig_in_nid);
 531                if (err < 0)
 532                        return err;
 533        }
 534
 535        /* if we have no master control, let's create it */
 536        if (spec->vmaster_nid &&
 537            !snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
 538                unsigned int vmaster_tlv[4];
 539                snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
 540                                        HDA_OUTPUT, vmaster_tlv);
 541                err = snd_hda_add_vmaster(codec, "Master Playback Volume",
 542                                          vmaster_tlv, slave_vols);
 543                if (err < 0)
 544                        return err;
 545        }
 546        if (spec->vmaster_nid &&
 547            !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
 548                err = snd_hda_add_vmaster(codec, "Master Playback Switch",
 549                                          NULL, slave_sws);
 550                if (err < 0)
 551                        return err;
 552        }
 553
 554        if (spec->input_mux) {
 555                err = snd_hda_add_new_ctls(codec, cxt_capture_mixers);
 556                if (err < 0)
 557                        return err;
 558        }
 559
 560        return 0;
 561}
 562
 563static struct hda_codec_ops conexant_patch_ops = {
 564        .build_controls = conexant_build_controls,
 565        .build_pcms = conexant_build_pcms,
 566        .init = conexant_init,
 567        .free = conexant_free,
 568};
 569
 570/*
 571 * EAPD control
 572 * the private value = nid | (invert << 8)
 573 */
 574
 575#define cxt_eapd_info           snd_ctl_boolean_mono_info
 576
 577static int cxt_eapd_get(struct snd_kcontrol *kcontrol,
 578                             struct snd_ctl_elem_value *ucontrol)
 579{
 580        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 581        struct conexant_spec *spec = codec->spec;
 582        int invert = (kcontrol->private_value >> 8) & 1;
 583        if (invert)
 584                ucontrol->value.integer.value[0] = !spec->cur_eapd;
 585        else
 586                ucontrol->value.integer.value[0] = spec->cur_eapd;
 587        return 0;
 588
 589}
 590
 591static int cxt_eapd_put(struct snd_kcontrol *kcontrol,
 592                             struct snd_ctl_elem_value *ucontrol)
 593{
 594        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 595        struct conexant_spec *spec = codec->spec;
 596        int invert = (kcontrol->private_value >> 8) & 1;
 597        hda_nid_t nid = kcontrol->private_value & 0xff;
 598        unsigned int eapd;
 599
 600        eapd = !!ucontrol->value.integer.value[0];
 601        if (invert)
 602                eapd = !eapd;
 603        if (eapd == spec->cur_eapd)
 604                return 0;
 605        
 606        spec->cur_eapd = eapd;
 607        snd_hda_codec_write_cache(codec, nid,
 608                                  0, AC_VERB_SET_EAPD_BTLENABLE,
 609                                  eapd ? 0x02 : 0x00);
 610        return 1;
 611}
 612
 613/* controls for test mode */
 614#ifdef CONFIG_SND_DEBUG
 615
 616#define CXT_EAPD_SWITCH(xname, nid, mask) \
 617        { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
 618          .info = cxt_eapd_info, \
 619          .get = cxt_eapd_get, \
 620          .put = cxt_eapd_put, \
 621          .private_value = nid | (mask<<16) }
 622
 623
 624
 625static int conexant_ch_mode_info(struct snd_kcontrol *kcontrol,
 626                                 struct snd_ctl_elem_info *uinfo)
 627{
 628        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 629        struct conexant_spec *spec = codec->spec;
 630        return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
 631                                    spec->num_channel_mode);
 632}
 633
 634static int conexant_ch_mode_get(struct snd_kcontrol *kcontrol,
 635                                struct snd_ctl_elem_value *ucontrol)
 636{
 637        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 638        struct conexant_spec *spec = codec->spec;
 639        return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
 640                                   spec->num_channel_mode,
 641                                   spec->multiout.max_channels);
 642}
 643
 644static int conexant_ch_mode_put(struct snd_kcontrol *kcontrol,
 645                                struct snd_ctl_elem_value *ucontrol)
 646{
 647        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 648        struct conexant_spec *spec = codec->spec;
 649        int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
 650                                      spec->num_channel_mode,
 651                                      &spec->multiout.max_channels);
 652        if (err >= 0 && spec->need_dac_fix)
 653                spec->multiout.num_dacs = spec->multiout.max_channels / 2;
 654        return err;
 655}
 656
 657#define CXT_PIN_MODE(xname, nid, dir) \
 658        { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0,  \
 659          .info = conexant_ch_mode_info, \
 660          .get = conexant_ch_mode_get, \
 661          .put = conexant_ch_mode_put, \
 662          .private_value = nid | (dir<<16) }
 663
 664#endif /* CONFIG_SND_DEBUG */
 665
 666/* Conexant 5045 specific */
 667
 668static hda_nid_t cxt5045_dac_nids[1] = { 0x19 };
 669static hda_nid_t cxt5045_adc_nids[1] = { 0x1a };
 670static hda_nid_t cxt5045_capsrc_nids[1] = { 0x1a };
 671#define CXT5045_SPDIF_OUT       0x18
 672
 673static struct hda_channel_mode cxt5045_modes[1] = {
 674        { 2, NULL },
 675};
 676
 677static struct hda_input_mux cxt5045_capture_source = {
 678        .num_items = 2,
 679        .items = {
 680                { "IntMic", 0x1 },
 681                { "ExtMic", 0x2 },
 682        }
 683};
 684
 685static struct hda_input_mux cxt5045_capture_source_benq = {
 686        .num_items = 5,
 687        .items = {
 688                { "IntMic", 0x1 },
 689                { "ExtMic", 0x2 },
 690                { "LineIn", 0x3 },
 691                { "CD",     0x4 },
 692                { "Mixer",  0x0 },
 693        }
 694};
 695
 696static struct hda_input_mux cxt5045_capture_source_hp530 = {
 697        .num_items = 2,
 698        .items = {
 699                { "ExtMic", 0x1 },
 700                { "IntMic", 0x2 },
 701        }
 702};
 703
 704/* turn on/off EAPD (+ mute HP) as a master switch */
 705static int cxt5045_hp_master_sw_put(struct snd_kcontrol *kcontrol,
 706                                    struct snd_ctl_elem_value *ucontrol)
 707{
 708        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 709        struct conexant_spec *spec = codec->spec;
 710        unsigned int bits;
 711
 712        if (!cxt_eapd_put(kcontrol, ucontrol))
 713                return 0;
 714
 715        /* toggle internal speakers mute depending of presence of
 716         * the headphone jack
 717         */
 718        bits = (!spec->hp_present && spec->cur_eapd) ? 0 : HDA_AMP_MUTE;
 719        snd_hda_codec_amp_stereo(codec, 0x10, HDA_OUTPUT, 0,
 720                                 HDA_AMP_MUTE, bits);
 721
 722        bits = spec->cur_eapd ? 0 : HDA_AMP_MUTE;
 723        snd_hda_codec_amp_stereo(codec, 0x11, HDA_OUTPUT, 0,
 724                                 HDA_AMP_MUTE, bits);
 725        return 1;
 726}
 727
 728/* bind volumes of both NID 0x10 and 0x11 */
 729static struct hda_bind_ctls cxt5045_hp_bind_master_vol = {
 730        .ops = &snd_hda_bind_vol,
 731        .values = {
 732                HDA_COMPOSE_AMP_VAL(0x10, 3, 0, HDA_OUTPUT),
 733                HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT),
 734                0
 735        },
 736};
 737
 738/* toggle input of built-in and mic jack appropriately */
 739static void cxt5045_hp_automic(struct hda_codec *codec)
 740{
 741        static struct hda_verb mic_jack_on[] = {
 742                {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
 743                {0x12, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
 744                {}
 745        };
 746        static struct hda_verb mic_jack_off[] = {
 747                {0x12, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
 748                {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
 749                {}
 750        };
 751        unsigned int present;
 752
 753        present = snd_hda_codec_read(codec, 0x12, 0,
 754                                     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
 755        if (present)
 756                snd_hda_sequence_write(codec, mic_jack_on);
 757        else
 758                snd_hda_sequence_write(codec, mic_jack_off);
 759}
 760
 761
 762/* mute internal speaker if HP is plugged */
 763static void cxt5045_hp_automute(struct hda_codec *codec)
 764{
 765        struct conexant_spec *spec = codec->spec;
 766        unsigned int bits;
 767
 768        spec->hp_present = snd_hda_codec_read(codec, 0x11, 0,
 769                                     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
 770
 771        bits = (spec->hp_present || !spec->cur_eapd) ? HDA_AMP_MUTE : 0; 
 772        snd_hda_codec_amp_stereo(codec, 0x10, HDA_OUTPUT, 0,
 773                                 HDA_AMP_MUTE, bits);
 774}
 775
 776/* unsolicited event for HP jack sensing */
 777static void cxt5045_hp_unsol_event(struct hda_codec *codec,
 778                                   unsigned int res)
 779{
 780        res >>= 26;
 781        switch (res) {
 782        case CONEXANT_HP_EVENT:
 783                cxt5045_hp_automute(codec);
 784                break;
 785        case CONEXANT_MIC_EVENT:
 786                cxt5045_hp_automic(codec);
 787                break;
 788
 789        }
 790}
 791
 792static struct snd_kcontrol_new cxt5045_mixers[] = {
 793        HDA_CODEC_VOLUME("Int Mic Capture Volume", 0x1a, 0x01, HDA_INPUT),
 794        HDA_CODEC_MUTE("Int Mic Capture Switch", 0x1a, 0x01, HDA_INPUT),
 795        HDA_CODEC_VOLUME("Ext Mic Capture Volume", 0x1a, 0x02, HDA_INPUT),
 796        HDA_CODEC_MUTE("Ext Mic Capture Switch", 0x1a, 0x02, HDA_INPUT),
 797        HDA_CODEC_VOLUME("PCM Playback Volume", 0x17, 0x0, HDA_INPUT),
 798        HDA_CODEC_MUTE("PCM Playback Switch", 0x17, 0x0, HDA_INPUT),
 799        HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x17, 0x1, HDA_INPUT),
 800        HDA_CODEC_MUTE("Int Mic Playback Switch", 0x17, 0x1, HDA_INPUT),
 801        HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x17, 0x2, HDA_INPUT),
 802        HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x17, 0x2, HDA_INPUT),
 803        HDA_BIND_VOL("Master Playback Volume", &cxt5045_hp_bind_master_vol),
 804        {
 805                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 806                .name = "Master Playback Switch",
 807                .info = cxt_eapd_info,
 808                .get = cxt_eapd_get,
 809                .put = cxt5045_hp_master_sw_put,
 810                .private_value = 0x10,
 811        },
 812
 813        {}
 814};
 815
 816static struct snd_kcontrol_new cxt5045_benq_mixers[] = {
 817        HDA_CODEC_VOLUME("CD Capture Volume", 0x1a, 0x04, HDA_INPUT),
 818        HDA_CODEC_MUTE("CD Capture Switch", 0x1a, 0x04, HDA_INPUT),
 819        HDA_CODEC_VOLUME("CD Playback Volume", 0x17, 0x4, HDA_INPUT),
 820        HDA_CODEC_MUTE("CD Playback Switch", 0x17, 0x4, HDA_INPUT),
 821
 822        HDA_CODEC_VOLUME("Line In Capture Volume", 0x1a, 0x03, HDA_INPUT),
 823        HDA_CODEC_MUTE("Line In Capture Switch", 0x1a, 0x03, HDA_INPUT),
 824        HDA_CODEC_VOLUME("Line In Playback Volume", 0x17, 0x3, HDA_INPUT),
 825        HDA_CODEC_MUTE("Line In Playback Switch", 0x17, 0x3, HDA_INPUT),
 826
 827        HDA_CODEC_VOLUME("Mixer Capture Volume", 0x1a, 0x0, HDA_INPUT),
 828        HDA_CODEC_MUTE("Mixer Capture Switch", 0x1a, 0x0, HDA_INPUT),
 829
 830        {}
 831};
 832
 833static struct snd_kcontrol_new cxt5045_mixers_hp530[] = {
 834        HDA_CODEC_VOLUME("Int Mic Capture Volume", 0x1a, 0x02, HDA_INPUT),
 835        HDA_CODEC_MUTE("Int Mic Capture Switch", 0x1a, 0x02, HDA_INPUT),
 836        HDA_CODEC_VOLUME("Ext Mic Capture Volume", 0x1a, 0x01, HDA_INPUT),
 837        HDA_CODEC_MUTE("Ext Mic Capture Switch", 0x1a, 0x01, HDA_INPUT),
 838        HDA_CODEC_VOLUME("PCM Playback Volume", 0x17, 0x0, HDA_INPUT),
 839        HDA_CODEC_MUTE("PCM Playback Switch", 0x17, 0x0, HDA_INPUT),
 840        HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x17, 0x2, HDA_INPUT),
 841        HDA_CODEC_MUTE("Int Mic Playback Switch", 0x17, 0x2, HDA_INPUT),
 842        HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x17, 0x1, HDA_INPUT),
 843        HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x17, 0x1, HDA_INPUT),
 844        HDA_BIND_VOL("Master Playback Volume", &cxt5045_hp_bind_master_vol),
 845        {
 846                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 847                .name = "Master Playback Switch",
 848                .info = cxt_eapd_info,
 849                .get = cxt_eapd_get,
 850                .put = cxt5045_hp_master_sw_put,
 851                .private_value = 0x10,
 852        },
 853
 854        {}
 855};
 856
 857static struct hda_verb cxt5045_init_verbs[] = {
 858        /* Line in, Mic */
 859        {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_80 },
 860        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_80 },
 861        /* HP, Amp  */
 862        {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
 863        {0x10, AC_VERB_SET_CONNECT_SEL, 0x1},
 864        {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
 865        {0x11, AC_VERB_SET_CONNECT_SEL, 0x1},
 866        {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
 867        {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
 868        {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
 869        {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
 870        {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
 871        /* Record selector: Int mic */
 872        {0x1a, AC_VERB_SET_CONNECT_SEL,0x1},
 873        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE,
 874         AC_AMP_SET_INPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x17},
 875        /* SPDIF route: PCM */
 876        {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
 877        { 0x13, AC_VERB_SET_CONNECT_SEL, 0x0 },
 878        /* EAPD */
 879        {0x10, AC_VERB_SET_EAPD_BTLENABLE, 0x2 }, /* default on */ 
 880        { } /* end */
 881};
 882
 883static struct hda_verb cxt5045_benq_init_verbs[] = {
 884        /* Int Mic, Mic */
 885        {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_80 },
 886        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_80 },
 887        /* Line In,HP, Amp  */
 888        {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
 889        {0x10, AC_VERB_SET_CONNECT_SEL, 0x1},
 890        {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
 891        {0x11, AC_VERB_SET_CONNECT_SEL, 0x1},
 892        {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
 893        {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
 894        {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
 895        {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
 896        {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
 897        /* Record selector: Int mic */
 898        {0x1a, AC_VERB_SET_CONNECT_SEL, 0x1},
 899        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE,
 900         AC_AMP_SET_INPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x17},
 901        /* SPDIF route: PCM */
 902        {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
 903        {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
 904        /* EAPD */
 905        {0x10, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
 906        { } /* end */
 907};
 908
 909static struct hda_verb cxt5045_hp_sense_init_verbs[] = {
 910        /* pin sensing on HP jack */
 911        {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT},
 912        { } /* end */
 913};
 914
 915static struct hda_verb cxt5045_mic_sense_init_verbs[] = {
 916        /* pin sensing on HP jack */
 917        {0x12, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT},
 918        { } /* end */
 919};
 920
 921#ifdef CONFIG_SND_DEBUG
 922/* Test configuration for debugging, modelled after the ALC260 test
 923 * configuration.
 924 */
 925static struct hda_input_mux cxt5045_test_capture_source = {
 926        .num_items = 5,
 927        .items = {
 928                { "MIXER", 0x0 },
 929                { "MIC1 pin", 0x1 },
 930                { "LINE1 pin", 0x2 },
 931                { "HP-OUT pin", 0x3 },
 932                { "CD pin", 0x4 },
 933        },
 934};
 935
 936static struct snd_kcontrol_new cxt5045_test_mixer[] = {
 937
 938        /* Output controls */
 939        HDA_CODEC_VOLUME("Speaker Playback Volume", 0x10, 0x0, HDA_OUTPUT),
 940        HDA_CODEC_MUTE("Speaker Playback Switch", 0x10, 0x0, HDA_OUTPUT),
 941        HDA_CODEC_VOLUME("Node 11 Playback Volume", 0x11, 0x0, HDA_OUTPUT),
 942        HDA_CODEC_MUTE("Node 11 Playback Switch", 0x11, 0x0, HDA_OUTPUT),
 943        HDA_CODEC_VOLUME("Node 12 Playback Volume", 0x12, 0x0, HDA_OUTPUT),
 944        HDA_CODEC_MUTE("Node 12 Playback Switch", 0x12, 0x0, HDA_OUTPUT),
 945        
 946        /* Modes for retasking pin widgets */
 947        CXT_PIN_MODE("HP-OUT pin mode", 0x11, CXT_PIN_DIR_INOUT),
 948        CXT_PIN_MODE("LINE1 pin mode", 0x12, CXT_PIN_DIR_INOUT),
 949
 950        /* EAPD Switch Control */
 951        CXT_EAPD_SWITCH("External Amplifier", 0x10, 0x0),
 952
 953        /* Loopback mixer controls */
 954
 955        HDA_CODEC_VOLUME("Mixer-1 Volume", 0x17, 0x0, HDA_INPUT),
 956        HDA_CODEC_MUTE("Mixer-1 Switch", 0x17, 0x0, HDA_INPUT),
 957        HDA_CODEC_VOLUME("Mixer-2 Volume", 0x17, 0x1, HDA_INPUT),
 958        HDA_CODEC_MUTE("Mixer-2 Switch", 0x17, 0x1, HDA_INPUT),
 959        HDA_CODEC_VOLUME("Mixer-3 Volume", 0x17, 0x2, HDA_INPUT),
 960        HDA_CODEC_MUTE("Mixer-3 Switch", 0x17, 0x2, HDA_INPUT),
 961        HDA_CODEC_VOLUME("Mixer-4 Volume", 0x17, 0x3, HDA_INPUT),
 962        HDA_CODEC_MUTE("Mixer-4 Switch", 0x17, 0x3, HDA_INPUT),
 963        HDA_CODEC_VOLUME("Mixer-5 Volume", 0x17, 0x4, HDA_INPUT),
 964        HDA_CODEC_MUTE("Mixer-5 Switch", 0x17, 0x4, HDA_INPUT),
 965        {
 966                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 967                .name = "Input Source",
 968                .info = conexant_mux_enum_info,
 969                .get = conexant_mux_enum_get,
 970                .put = conexant_mux_enum_put,
 971        },
 972        /* Audio input controls */
 973        HDA_CODEC_VOLUME("Input-1 Volume", 0x1a, 0x0, HDA_INPUT),
 974        HDA_CODEC_MUTE("Input-1 Switch", 0x1a, 0x0, HDA_INPUT),
 975        HDA_CODEC_VOLUME("Input-2 Volume", 0x1a, 0x1, HDA_INPUT),
 976        HDA_CODEC_MUTE("Input-2 Switch", 0x1a, 0x1, HDA_INPUT),
 977        HDA_CODEC_VOLUME("Input-3 Volume", 0x1a, 0x2, HDA_INPUT),
 978        HDA_CODEC_MUTE("Input-3 Switch", 0x1a, 0x2, HDA_INPUT),
 979        HDA_CODEC_VOLUME("Input-4 Volume", 0x1a, 0x3, HDA_INPUT),
 980        HDA_CODEC_MUTE("Input-4 Switch", 0x1a, 0x3, HDA_INPUT),
 981        HDA_CODEC_VOLUME("Input-5 Volume", 0x1a, 0x4, HDA_INPUT),
 982        HDA_CODEC_MUTE("Input-5 Switch", 0x1a, 0x4, HDA_INPUT),
 983        { } /* end */
 984};
 985
 986static struct hda_verb cxt5045_test_init_verbs[] = {
 987        /* Set connections */
 988        { 0x10, AC_VERB_SET_CONNECT_SEL, 0x0 },
 989        { 0x11, AC_VERB_SET_CONNECT_SEL, 0x0 },
 990        { 0x12, AC_VERB_SET_CONNECT_SEL, 0x0 },
 991        /* Enable retasking pins as output, initially without power amp */
 992        {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
 993        {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
 994
 995        /* Disable digital (SPDIF) pins initially, but users can enable
 996         * them via a mixer switch.  In the case of SPDIF-out, this initverb
 997         * payload also sets the generation to 0, output to be in "consumer"
 998         * PCM format, copyright asserted, no pre-emphasis and no validity
 999         * control.
1000         */
1001        {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1002        {0x18, AC_VERB_SET_DIGI_CONVERT_1, 0},
1003
1004        /* Start with output sum widgets muted and their output gains at min */
1005        {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1006        {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1007
1008        /* Unmute retasking pin widget output buffers since the default
1009         * state appears to be output.  As the pin mode is changed by the
1010         * user the pin mode control will take care of enabling the pin's
1011         * input/output buffers as needed.
1012         */
1013        {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1014        {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1015
1016        /* Mute capture amp left and right */
1017        {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1018
1019        /* Set ADC connection select to match default mixer setting (mic1
1020         * pin)
1021         */
1022        {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
1023        {0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
1024
1025        /* Mute all inputs to mixer widget (even unconnected ones) */
1026        {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* Mixer pin */
1027        {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* Mic1 pin */
1028        {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* Line pin */
1029        {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* HP pin */
1030        {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
1031
1032        { }
1033};
1034#endif
1035
1036
1037/* initialize jack-sensing, too */
1038static int cxt5045_init(struct hda_codec *codec)
1039{
1040        conexant_init(codec);
1041        cxt5045_hp_automute(codec);
1042        return 0;
1043}
1044
1045
1046enum {
1047        CXT5045_LAPTOP_HPSENSE,
1048        CXT5045_LAPTOP_MICSENSE,
1049        CXT5045_LAPTOP_HPMICSENSE,
1050        CXT5045_BENQ,
1051        CXT5045_LAPTOP_HP530,
1052#ifdef CONFIG_SND_DEBUG
1053        CXT5045_TEST,
1054#endif
1055        CXT5045_MODELS
1056};
1057
1058static const char *cxt5045_models[CXT5045_MODELS] = {
1059        [CXT5045_LAPTOP_HPSENSE]        = "laptop-hpsense",
1060        [CXT5045_LAPTOP_MICSENSE]       = "laptop-micsense",
1061        [CXT5045_LAPTOP_HPMICSENSE]     = "laptop-hpmicsense",
1062        [CXT5045_BENQ]                  = "benq",
1063        [CXT5045_LAPTOP_HP530]          = "laptop-hp530",
1064#ifdef CONFIG_SND_DEBUG
1065        [CXT5045_TEST]          = "test",
1066#endif
1067};
1068
1069static struct snd_pci_quirk cxt5045_cfg_tbl[] = {
1070        SND_PCI_QUIRK(0x103c, 0x30d5, "HP 530", CXT5045_LAPTOP_HP530),
1071        SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3000, "HP DV Series",
1072                           CXT5045_LAPTOP_HPSENSE),
1073        SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba P105", CXT5045_LAPTOP_MICSENSE),
1074        SND_PCI_QUIRK(0x152d, 0x0753, "Benq R55E", CXT5045_BENQ),
1075        SND_PCI_QUIRK(0x1734, 0x10ad, "Fujitsu Si1520", CXT5045_LAPTOP_MICSENSE),
1076        SND_PCI_QUIRK(0x1734, 0x10cb, "Fujitsu Si3515", CXT5045_LAPTOP_HPMICSENSE),
1077        SND_PCI_QUIRK(0x1734, 0x110e, "Fujitsu V5505",
1078                      CXT5045_LAPTOP_HPMICSENSE),
1079        SND_PCI_QUIRK(0x1509, 0x1e40, "FIC", CXT5045_LAPTOP_HPMICSENSE),
1080        SND_PCI_QUIRK(0x1509, 0x2f05, "FIC", CXT5045_LAPTOP_HPMICSENSE),
1081        SND_PCI_QUIRK(0x1509, 0x2f06, "FIC", CXT5045_LAPTOP_HPMICSENSE),
1082        SND_PCI_QUIRK_MASK(0x1631, 0xff00, 0xc100, "Packard Bell",
1083                           CXT5045_LAPTOP_HPMICSENSE),
1084        SND_PCI_QUIRK(0x8086, 0x2111, "Conexant Reference board", CXT5045_LAPTOP_HPSENSE),
1085        {}
1086};
1087
1088static int patch_cxt5045(struct hda_codec *codec)
1089{
1090        struct conexant_spec *spec;
1091        int board_config;
1092
1093        spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1094        if (!spec)
1095                return -ENOMEM;
1096        codec->spec = spec;
1097        codec->pin_amp_workaround = 1;
1098
1099        spec->multiout.max_channels = 2;
1100        spec->multiout.num_dacs = ARRAY_SIZE(cxt5045_dac_nids);
1101        spec->multiout.dac_nids = cxt5045_dac_nids;
1102        spec->multiout.dig_out_nid = CXT5045_SPDIF_OUT;
1103        spec->num_adc_nids = 1;
1104        spec->adc_nids = cxt5045_adc_nids;
1105        spec->capsrc_nids = cxt5045_capsrc_nids;
1106        spec->input_mux = &cxt5045_capture_source;
1107        spec->num_mixers = 1;
1108        spec->mixers[0] = cxt5045_mixers;
1109        spec->num_init_verbs = 1;
1110        spec->init_verbs[0] = cxt5045_init_verbs;
1111        spec->spdif_route = 0;
1112        spec->num_channel_mode = ARRAY_SIZE(cxt5045_modes),
1113        spec->channel_mode = cxt5045_modes,
1114
1115
1116        codec->patch_ops = conexant_patch_ops;
1117
1118        board_config = snd_hda_check_board_config(codec, CXT5045_MODELS,
1119                                                  cxt5045_models,
1120                                                  cxt5045_cfg_tbl);
1121        switch (board_config) {
1122        case CXT5045_LAPTOP_HPSENSE:
1123                codec->patch_ops.unsol_event = cxt5045_hp_unsol_event;
1124                spec->input_mux = &cxt5045_capture_source;
1125                spec->num_init_verbs = 2;
1126                spec->init_verbs[1] = cxt5045_hp_sense_init_verbs;
1127                spec->mixers[0] = cxt5045_mixers;
1128                codec->patch_ops.init = cxt5045_init;
1129                break;
1130        case CXT5045_LAPTOP_MICSENSE:
1131                codec->patch_ops.unsol_event = cxt5045_hp_unsol_event;
1132                spec->input_mux = &cxt5045_capture_source;
1133                spec->num_init_verbs = 2;
1134                spec->init_verbs[1] = cxt5045_mic_sense_init_verbs;
1135                spec->mixers[0] = cxt5045_mixers;
1136                codec->patch_ops.init = cxt5045_init;
1137                break;
1138        default:
1139        case CXT5045_LAPTOP_HPMICSENSE:
1140                codec->patch_ops.unsol_event = cxt5045_hp_unsol_event;
1141                spec->input_mux = &cxt5045_capture_source;
1142                spec->num_init_verbs = 3;
1143                spec->init_verbs[1] = cxt5045_hp_sense_init_verbs;
1144                spec->init_verbs[2] = cxt5045_mic_sense_init_verbs;
1145                spec->mixers[0] = cxt5045_mixers;
1146                codec->patch_ops.init = cxt5045_init;
1147                break;
1148        case CXT5045_BENQ:
1149                codec->patch_ops.unsol_event = cxt5045_hp_unsol_event;
1150                spec->input_mux = &cxt5045_capture_source_benq;
1151                spec->num_init_verbs = 1;
1152                spec->init_verbs[0] = cxt5045_benq_init_verbs;
1153                spec->mixers[0] = cxt5045_mixers;
1154                spec->mixers[1] = cxt5045_benq_mixers;
1155                spec->num_mixers = 2;
1156                codec->patch_ops.init = cxt5045_init;
1157                break;
1158        case CXT5045_LAPTOP_HP530:
1159                codec->patch_ops.unsol_event = cxt5045_hp_unsol_event;
1160                spec->input_mux = &cxt5045_capture_source_hp530;
1161                spec->num_init_verbs = 2;
1162                spec->init_verbs[1] = cxt5045_hp_sense_init_verbs;
1163                spec->mixers[0] = cxt5045_mixers_hp530;
1164                codec->patch_ops.init = cxt5045_init;
1165                break;
1166#ifdef CONFIG_SND_DEBUG
1167        case CXT5045_TEST:
1168                spec->input_mux = &cxt5045_test_capture_source;
1169                spec->mixers[0] = cxt5045_test_mixer;
1170                spec->init_verbs[0] = cxt5045_test_init_verbs;
1171                break;
1172                
1173#endif  
1174        }
1175
1176        switch (codec->subsystem_id >> 16) {
1177        case 0x103c:
1178                /* HP laptop has a really bad sound over 0dB on NID 0x17.
1179                 * Fix max PCM level to 0 dB
1180                 * (originall it has 0x2b steps with 0dB offset 0x14)
1181                 */
1182                snd_hda_override_amp_caps(codec, 0x17, HDA_INPUT,
1183                                          (0x14 << AC_AMPCAP_OFFSET_SHIFT) |
1184                                          (0x14 << AC_AMPCAP_NUM_STEPS_SHIFT) |
1185                                          (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) |
1186                                          (1 << AC_AMPCAP_MUTE_SHIFT));
1187                break;
1188        }
1189
1190        return 0;
1191}
1192
1193
1194/* Conexant 5047 specific */
1195#define CXT5047_SPDIF_OUT       0x11
1196
1197static hda_nid_t cxt5047_dac_nids[1] = { 0x10 }; /* 0x1c */
1198static hda_nid_t cxt5047_adc_nids[1] = { 0x12 };
1199static hda_nid_t cxt5047_capsrc_nids[1] = { 0x1a };
1200
1201static struct hda_channel_mode cxt5047_modes[1] = {
1202        { 2, NULL },
1203};
1204
1205static struct hda_input_mux cxt5047_toshiba_capture_source = {
1206        .num_items = 2,
1207        .items = {
1208                { "ExtMic", 0x2 },
1209                { "Line-In", 0x1 },
1210        }
1211};
1212
1213/* turn on/off EAPD (+ mute HP) as a master switch */
1214static int cxt5047_hp_master_sw_put(struct snd_kcontrol *kcontrol,
1215                                    struct snd_ctl_elem_value *ucontrol)
1216{
1217        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1218        struct conexant_spec *spec = codec->spec;
1219        unsigned int bits;
1220
1221        if (!cxt_eapd_put(kcontrol, ucontrol))
1222                return 0;
1223
1224        /* toggle internal speakers mute depending of presence of
1225         * the headphone jack
1226         */
1227        bits = (!spec->hp_present && spec->cur_eapd) ? 0 : HDA_AMP_MUTE;
1228        /* NOTE: Conexat codec needs the index for *OUTPUT* amp of
1229         * pin widgets unlike other codecs.  In this case, we need to
1230         * set index 0x01 for the volume from the mixer amp 0x19.
1231         */
1232        snd_hda_codec_amp_stereo(codec, 0x1d, HDA_OUTPUT, 0x01,
1233                                 HDA_AMP_MUTE, bits);
1234        bits = spec->cur_eapd ? 0 : HDA_AMP_MUTE;
1235        snd_hda_codec_amp_stereo(codec, 0x13, HDA_OUTPUT, 0,
1236                                 HDA_AMP_MUTE, bits);
1237        return 1;
1238}
1239
1240/* mute internal speaker if HP is plugged */
1241static void cxt5047_hp_automute(struct hda_codec *codec)
1242{
1243        struct conexant_spec *spec = codec->spec;
1244        unsigned int bits;
1245
1246        spec->hp_present = snd_hda_codec_read(codec, 0x13, 0,
1247                                     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1248
1249        bits = (spec->hp_present || !spec->cur_eapd) ? HDA_AMP_MUTE : 0;
1250        /* See the note in cxt5047_hp_master_sw_put */
1251        snd_hda_codec_amp_stereo(codec, 0x1d, HDA_OUTPUT, 0x01,
1252                                 HDA_AMP_MUTE, bits);
1253}
1254
1255/* toggle input of built-in and mic jack appropriately */
1256static void cxt5047_hp_automic(struct hda_codec *codec)
1257{
1258        static struct hda_verb mic_jack_on[] = {
1259                {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1260                {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1261                {}
1262        };
1263        static struct hda_verb mic_jack_off[] = {
1264                {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1265                {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1266                {}
1267        };
1268        unsigned int present;
1269
1270        present = snd_hda_codec_read(codec, 0x15, 0,
1271                                     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1272        if (present)
1273                snd_hda_sequence_write(codec, mic_jack_on);
1274        else
1275                snd_hda_sequence_write(codec, mic_jack_off);
1276}
1277
1278/* unsolicited event for HP jack sensing */
1279static void cxt5047_hp_unsol_event(struct hda_codec *codec,
1280                                  unsigned int res)
1281{
1282        switch (res >> 26) {
1283        case CONEXANT_HP_EVENT:
1284                cxt5047_hp_automute(codec);
1285                break;
1286        case CONEXANT_MIC_EVENT:
1287                cxt5047_hp_automic(codec);
1288                break;
1289        }
1290}
1291
1292static struct snd_kcontrol_new cxt5047_base_mixers[] = {
1293        HDA_CODEC_VOLUME("Mic Playback Volume", 0x19, 0x02, HDA_INPUT),
1294        HDA_CODEC_MUTE("Mic Playback Switch", 0x19, 0x02, HDA_INPUT),
1295        HDA_CODEC_VOLUME("Mic Boost", 0x1a, 0x0, HDA_OUTPUT),
1296        HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x03, HDA_INPUT),
1297        HDA_CODEC_MUTE("Capture Switch", 0x12, 0x03, HDA_INPUT),
1298        HDA_CODEC_VOLUME("PCM Volume", 0x10, 0x00, HDA_OUTPUT),
1299        HDA_CODEC_MUTE("PCM Switch", 0x10, 0x00, HDA_OUTPUT),
1300        {
1301                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1302                .name = "Master Playback Switch",
1303                .info = cxt_eapd_info,
1304                .get = cxt_eapd_get,
1305                .put = cxt5047_hp_master_sw_put,
1306                .private_value = 0x13,
1307        },
1308
1309        {}
1310};
1311
1312static struct snd_kcontrol_new cxt5047_hp_spk_mixers[] = {
1313        /* See the note in cxt5047_hp_master_sw_put */
1314        HDA_CODEC_VOLUME("Speaker Playback Volume", 0x1d, 0x01, HDA_OUTPUT),
1315        HDA_CODEC_VOLUME("Headphone Playback Volume", 0x13, 0x00, HDA_OUTPUT),
1316        {}
1317};
1318
1319static struct snd_kcontrol_new cxt5047_hp_only_mixers[] = {
1320        HDA_CODEC_VOLUME("Master Playback Volume", 0x13, 0x00, HDA_OUTPUT),
1321        { } /* end */
1322};
1323
1324static struct hda_verb cxt5047_init_verbs[] = {
1325        /* Line in, Mic, Built-in Mic */
1326        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1327        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_50 },
1328        {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_50 },
1329        /* HP, Speaker  */
1330        {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
1331        {0x13, AC_VERB_SET_CONNECT_SEL, 0x0}, /* mixer(0x19) */
1332        {0x1d, AC_VERB_SET_CONNECT_SEL, 0x1}, /* mixer(0x19) */
1333        /* Record selector: Mic */
1334        {0x12, AC_VERB_SET_CONNECT_SEL,0x03},
1335        {0x19, AC_VERB_SET_AMP_GAIN_MUTE,
1336         AC_AMP_SET_INPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x17},
1337        {0x1A, AC_VERB_SET_CONNECT_SEL,0x02},
1338        {0x1A, AC_VERB_SET_AMP_GAIN_MUTE,
1339         AC_AMP_SET_OUTPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x00},
1340        {0x1A, AC_VERB_SET_AMP_GAIN_MUTE,
1341         AC_AMP_SET_OUTPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x03},
1342        /* SPDIF route: PCM */
1343        { 0x18, AC_VERB_SET_CONNECT_SEL, 0x0 },
1344        /* Enable unsolicited events */
1345        {0x13, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT},
1346        {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT},
1347        { } /* end */
1348};
1349
1350/* configuration for Toshiba Laptops */
1351static struct hda_verb cxt5047_toshiba_init_verbs[] = {
1352        {0x13, AC_VERB_SET_EAPD_BTLENABLE, 0x0}, /* default off */
1353        {}
1354};
1355
1356/* Test configuration for debugging, modelled after the ALC260 test
1357 * configuration.
1358 */
1359#ifdef CONFIG_SND_DEBUG
1360static struct hda_input_mux cxt5047_test_capture_source = {
1361        .num_items = 4,
1362        .items = {
1363                { "LINE1 pin", 0x0 },
1364                { "MIC1 pin", 0x1 },
1365                { "MIC2 pin", 0x2 },
1366                { "CD pin", 0x3 },
1367        },
1368};
1369
1370static struct snd_kcontrol_new cxt5047_test_mixer[] = {
1371
1372        /* Output only controls */
1373        HDA_CODEC_VOLUME("OutAmp-1 Volume", 0x10, 0x0, HDA_OUTPUT),
1374        HDA_CODEC_MUTE("OutAmp-1 Switch", 0x10,0x0, HDA_OUTPUT),
1375        HDA_CODEC_VOLUME("OutAmp-2 Volume", 0x1c, 0x0, HDA_OUTPUT),
1376        HDA_CODEC_MUTE("OutAmp-2 Switch", 0x1c, 0x0, HDA_OUTPUT),
1377        HDA_CODEC_VOLUME("Speaker Playback Volume", 0x1d, 0x0, HDA_OUTPUT),
1378        HDA_CODEC_MUTE("Speaker Playback Switch", 0x1d, 0x0, HDA_OUTPUT),
1379        HDA_CODEC_VOLUME("HeadPhone Playback Volume", 0x13, 0x0, HDA_OUTPUT),
1380        HDA_CODEC_MUTE("HeadPhone Playback Switch", 0x13, 0x0, HDA_OUTPUT),
1381        HDA_CODEC_VOLUME("Line1-Out Playback Volume", 0x14, 0x0, HDA_OUTPUT),
1382        HDA_CODEC_MUTE("Line1-Out Playback Switch", 0x14, 0x0, HDA_OUTPUT),
1383        HDA_CODEC_VOLUME("Line2-Out Playback Volume", 0x15, 0x0, HDA_OUTPUT),
1384        HDA_CODEC_MUTE("Line2-Out Playback Switch", 0x15, 0x0, HDA_OUTPUT),
1385
1386        /* Modes for retasking pin widgets */
1387        CXT_PIN_MODE("LINE1 pin mode", 0x14, CXT_PIN_DIR_INOUT),
1388        CXT_PIN_MODE("MIC1 pin mode", 0x15, CXT_PIN_DIR_INOUT),
1389
1390        /* EAPD Switch Control */
1391        CXT_EAPD_SWITCH("External Amplifier", 0x13, 0x0),
1392
1393        /* Loopback mixer controls */
1394        HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x12, 0x01, HDA_INPUT),
1395        HDA_CODEC_MUTE("MIC1 Playback Switch", 0x12, 0x01, HDA_INPUT),
1396        HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x12, 0x02, HDA_INPUT),
1397        HDA_CODEC_MUTE("MIC2 Playback Switch", 0x12, 0x02, HDA_INPUT),
1398        HDA_CODEC_VOLUME("LINE Playback Volume", 0x12, 0x0, HDA_INPUT),
1399        HDA_CODEC_MUTE("LINE Playback Switch", 0x12, 0x0, HDA_INPUT),
1400        HDA_CODEC_VOLUME("CD Playback Volume", 0x12, 0x04, HDA_INPUT),
1401        HDA_CODEC_MUTE("CD Playback Switch", 0x12, 0x04, HDA_INPUT),
1402
1403        HDA_CODEC_VOLUME("Capture-1 Volume", 0x19, 0x0, HDA_INPUT),
1404        HDA_CODEC_MUTE("Capture-1 Switch", 0x19, 0x0, HDA_INPUT),
1405        HDA_CODEC_VOLUME("Capture-2 Volume", 0x19, 0x1, HDA_INPUT),
1406        HDA_CODEC_MUTE("Capture-2 Switch", 0x19, 0x1, HDA_INPUT),
1407        HDA_CODEC_VOLUME("Capture-3 Volume", 0x19, 0x2, HDA_INPUT),
1408        HDA_CODEC_MUTE("Capture-3 Switch", 0x19, 0x2, HDA_INPUT),
1409        HDA_CODEC_VOLUME("Capture-4 Volume", 0x19, 0x3, HDA_INPUT),
1410        HDA_CODEC_MUTE("Capture-4 Switch", 0x19, 0x3, HDA_INPUT),
1411        {
1412                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1413                .name = "Input Source",
1414                .info = conexant_mux_enum_info,
1415                .get = conexant_mux_enum_get,
1416                .put = conexant_mux_enum_put,
1417        },
1418        HDA_CODEC_VOLUME("Input-1 Volume", 0x1a, 0x0, HDA_INPUT),
1419        HDA_CODEC_MUTE("Input-1 Switch", 0x1a, 0x0, HDA_INPUT),
1420        HDA_CODEC_VOLUME("Input-2 Volume", 0x1a, 0x1, HDA_INPUT),
1421        HDA_CODEC_MUTE("Input-2 Switch", 0x1a, 0x1, HDA_INPUT),
1422        HDA_CODEC_VOLUME("Input-3 Volume", 0x1a, 0x2, HDA_INPUT),
1423        HDA_CODEC_MUTE("Input-3 Switch", 0x1a, 0x2, HDA_INPUT),
1424        HDA_CODEC_VOLUME("Input-4 Volume", 0x1a, 0x3, HDA_INPUT),
1425        HDA_CODEC_MUTE("Input-4 Switch", 0x1a, 0x3, HDA_INPUT),
1426        HDA_CODEC_VOLUME("Input-5 Volume", 0x1a, 0x4, HDA_INPUT),
1427        HDA_CODEC_MUTE("Input-5 Switch", 0x1a, 0x4, HDA_INPUT),
1428
1429        { } /* end */
1430};
1431
1432static struct hda_verb cxt5047_test_init_verbs[] = {
1433        /* Enable retasking pins as output, initially without power amp */
1434        {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1435        {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1436        {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1437
1438        /* Disable digital (SPDIF) pins initially, but users can enable
1439         * them via a mixer switch.  In the case of SPDIF-out, this initverb
1440         * payload also sets the generation to 0, output to be in "consumer"
1441         * PCM format, copyright asserted, no pre-emphasis and no validity
1442         * control.
1443         */
1444        {0x18, AC_VERB_SET_DIGI_CONVERT_1, 0},
1445
1446        /* Ensure mic1, mic2, line1 pin widgets take input from the 
1447         * OUT1 sum bus when acting as an output.
1448         */
1449        {0x1a, AC_VERB_SET_CONNECT_SEL, 0},
1450        {0x1b, AC_VERB_SET_CONNECT_SEL, 0},
1451
1452        /* Start with output sum widgets muted and their output gains at min */
1453        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1454        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1455
1456        /* Unmute retasking pin widget output buffers since the default
1457         * state appears to be output.  As the pin mode is changed by the
1458         * user the pin mode control will take care of enabling the pin's
1459         * input/output buffers as needed.
1460         */
1461        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1462        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1463        {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1464
1465        /* Mute capture amp left and right */
1466        {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1467
1468        /* Set ADC connection select to match default mixer setting (mic1
1469         * pin)
1470         */
1471        {0x12, AC_VERB_SET_CONNECT_SEL, 0x00},
1472
1473        /* Mute all inputs to mixer widget (even unconnected ones) */
1474        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
1475        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
1476        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
1477        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
1478        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
1479        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
1480        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
1481        {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
1482
1483        { }
1484};
1485#endif
1486
1487
1488/* initialize jack-sensing, too */
1489static int cxt5047_hp_init(struct hda_codec *codec)
1490{
1491        conexant_init(codec);
1492        cxt5047_hp_automute(codec);
1493        return 0;
1494}
1495
1496
1497enum {
1498        CXT5047_LAPTOP,         /* Laptops w/o EAPD support */
1499        CXT5047_LAPTOP_HP,      /* Some HP laptops */
1500        CXT5047_LAPTOP_EAPD,    /* Laptops with EAPD support */
1501#ifdef CONFIG_SND_DEBUG
1502        CXT5047_TEST,
1503#endif
1504        CXT5047_MODELS
1505};
1506
1507static const char *cxt5047_models[CXT5047_MODELS] = {
1508        [CXT5047_LAPTOP]        = "laptop",
1509        [CXT5047_LAPTOP_HP]     = "laptop-hp",
1510        [CXT5047_LAPTOP_EAPD]   = "laptop-eapd",
1511#ifdef CONFIG_SND_DEBUG
1512        [CXT5047_TEST]          = "test",
1513#endif
1514};
1515
1516static struct snd_pci_quirk cxt5047_cfg_tbl[] = {
1517        SND_PCI_QUIRK(0x103c, 0x30a5, "HP DV5200T/DV8000T", CXT5047_LAPTOP_HP),
1518        SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3000, "HP DV Series",
1519                           CXT5047_LAPTOP),
1520        SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba P100", CXT5047_LAPTOP_EAPD),
1521        {}
1522};
1523
1524static int patch_cxt5047(struct hda_codec *codec)
1525{
1526        struct conexant_spec *spec;
1527        int board_config;
1528
1529        spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1530        if (!spec)
1531                return -ENOMEM;
1532        codec->spec = spec;
1533        codec->pin_amp_workaround = 1;
1534
1535        spec->multiout.max_channels = 2;
1536        spec->multiout.num_dacs = ARRAY_SIZE(cxt5047_dac_nids);
1537        spec->multiout.dac_nids = cxt5047_dac_nids;
1538        spec->multiout.dig_out_nid = CXT5047_SPDIF_OUT;
1539        spec->num_adc_nids = 1;
1540        spec->adc_nids = cxt5047_adc_nids;
1541        spec->capsrc_nids = cxt5047_capsrc_nids;
1542        spec->num_mixers = 1;
1543        spec->mixers[0] = cxt5047_base_mixers;
1544        spec->num_init_verbs = 1;
1545        spec->init_verbs[0] = cxt5047_init_verbs;
1546        spec->spdif_route = 0;
1547        spec->num_channel_mode = ARRAY_SIZE(cxt5047_modes),
1548        spec->channel_mode = cxt5047_modes,
1549
1550        codec->patch_ops = conexant_patch_ops;
1551
1552        board_config = snd_hda_check_board_config(codec, CXT5047_MODELS,
1553                                                  cxt5047_models,
1554                                                  cxt5047_cfg_tbl);
1555        switch (board_config) {
1556        case CXT5047_LAPTOP:
1557                spec->num_mixers = 2;
1558                spec->mixers[1] = cxt5047_hp_spk_mixers;
1559                codec->patch_ops.unsol_event = cxt5047_hp_unsol_event;
1560                break;
1561        case CXT5047_LAPTOP_HP:
1562                spec->num_mixers = 2;
1563                spec->mixers[1] = cxt5047_hp_only_mixers;
1564                codec->patch_ops.unsol_event = cxt5047_hp_unsol_event;
1565                codec->patch_ops.init = cxt5047_hp_init;
1566                break;
1567        case CXT5047_LAPTOP_EAPD:
1568                spec->input_mux = &cxt5047_toshiba_capture_source;
1569                spec->num_mixers = 2;
1570                spec->mixers[1] = cxt5047_hp_spk_mixers;
1571                spec->num_init_verbs = 2;
1572                spec->init_verbs[1] = cxt5047_toshiba_init_verbs;
1573                codec->patch_ops.unsol_event = cxt5047_hp_unsol_event;
1574                break;
1575#ifdef CONFIG_SND_DEBUG
1576        case CXT5047_TEST:
1577                spec->input_mux = &cxt5047_test_capture_source;
1578                spec->mixers[0] = cxt5047_test_mixer;
1579                spec->init_verbs[0] = cxt5047_test_init_verbs;
1580                codec->patch_ops.unsol_event = cxt5047_hp_unsol_event;
1581#endif  
1582        }
1583        spec->vmaster_nid = 0x13;
1584        return 0;
1585}
1586
1587/* Conexant 5051 specific */
1588static hda_nid_t cxt5051_dac_nids[1] = { 0x10 };
1589static hda_nid_t cxt5051_adc_nids[2] = { 0x14, 0x15 };
1590
1591static struct hda_channel_mode cxt5051_modes[1] = {
1592        { 2, NULL },
1593};
1594
1595static void cxt5051_update_speaker(struct hda_codec *codec)
1596{
1597        struct conexant_spec *spec = codec->spec;
1598        unsigned int pinctl;
1599        pinctl = (!spec->hp_present && spec->cur_eapd) ? PIN_OUT : 0;
1600        snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
1601                            pinctl);
1602}
1603
1604/* turn on/off EAPD (+ mute HP) as a master switch */
1605static int cxt5051_hp_master_sw_put(struct snd_kcontrol *kcontrol,
1606                                    struct snd_ctl_elem_value *ucontrol)
1607{
1608        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1609
1610        if (!cxt_eapd_put(kcontrol, ucontrol))
1611                return 0;
1612        cxt5051_update_speaker(codec);
1613        return 1;
1614}
1615
1616/* toggle input of built-in and mic jack appropriately */
1617static void cxt5051_portb_automic(struct hda_codec *codec)
1618{
1619        struct conexant_spec *spec = codec->spec;
1620        unsigned int present;
1621
1622        if (spec->no_auto_mic)
1623                return;
1624        present = snd_hda_codec_read(codec, 0x17, 0,
1625                                     AC_VERB_GET_PIN_SENSE, 0) &
1626                AC_PINSENSE_PRESENCE;
1627        snd_hda_codec_write(codec, 0x14, 0,
1628                            AC_VERB_SET_CONNECT_SEL,
1629                            present ? 0x01 : 0x00);
1630}
1631
1632/* switch the current ADC according to the jack state */
1633static void cxt5051_portc_automic(struct hda_codec *codec)
1634{
1635        struct conexant_spec *spec = codec->spec;
1636        unsigned int present;
1637        hda_nid_t new_adc;
1638
1639        if (spec->no_auto_mic)
1640                return;
1641        present = snd_hda_codec_read(codec, 0x18, 0,
1642                                     AC_VERB_GET_PIN_SENSE, 0) &
1643                AC_PINSENSE_PRESENCE;
1644        if (present)
1645                spec->cur_adc_idx = 1;
1646        else
1647                spec->cur_adc_idx = 0;
1648        new_adc = spec->adc_nids[spec->cur_adc_idx];
1649        if (spec->cur_adc && spec->cur_adc != new_adc) {
1650                /* stream is running, let's swap the current ADC */
1651                snd_hda_codec_cleanup_stream(codec, spec->cur_adc);
1652                spec->cur_adc = new_adc;
1653                snd_hda_codec_setup_stream(codec, new_adc,
1654                                           spec->cur_adc_stream_tag, 0,
1655                                           spec->cur_adc_format);
1656        }
1657}
1658
1659/* mute internal speaker if HP is plugged */
1660static void cxt5051_hp_automute(struct hda_codec *codec)
1661{
1662        struct conexant_spec *spec = codec->spec;
1663
1664        spec->hp_present = snd_hda_codec_read(codec, 0x16, 0,
1665                                     AC_VERB_GET_PIN_SENSE, 0) &
1666                AC_PINSENSE_PRESENCE;
1667        cxt5051_update_speaker(codec);
1668}
1669
1670/* unsolicited event for HP jack sensing */
1671static void cxt5051_hp_unsol_event(struct hda_codec *codec,
1672                                   unsigned int res)
1673{
1674        int nid = (res & AC_UNSOL_RES_SUBTAG) >> 20;
1675        switch (res >> 26) {
1676        case CONEXANT_HP_EVENT:
1677                cxt5051_hp_automute(codec);
1678                break;
1679        case CXT5051_PORTB_EVENT:
1680                cxt5051_portb_automic(codec);
1681                break;
1682        case CXT5051_PORTC_EVENT:
1683                cxt5051_portc_automic(codec);
1684                break;
1685        }
1686        conexant_report_jack(codec, nid);
1687}
1688
1689static struct snd_kcontrol_new cxt5051_mixers[] = {
1690        HDA_CODEC_VOLUME("Internal Mic Volume", 0x14, 0x00, HDA_INPUT),
1691        HDA_CODEC_MUTE("Internal Mic Switch", 0x14, 0x00, HDA_INPUT),
1692        HDA_CODEC_VOLUME("External Mic Volume", 0x14, 0x01, HDA_INPUT),
1693        HDA_CODEC_MUTE("External Mic Switch", 0x14, 0x01, HDA_INPUT),
1694        HDA_CODEC_VOLUME("Docking Mic Volume", 0x15, 0x00, HDA_INPUT),
1695        HDA_CODEC_MUTE("Docking Mic Switch", 0x15, 0x00, HDA_INPUT),
1696        HDA_CODEC_VOLUME("Master Playback Volume", 0x10, 0x00, HDA_OUTPUT),
1697        {
1698                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1699                .name = "Master Playback Switch",
1700                .info = cxt_eapd_info,
1701                .get = cxt_eapd_get,
1702                .put = cxt5051_hp_master_sw_put,
1703                .private_value = 0x1a,
1704        },
1705
1706        {}
1707};
1708
1709static struct snd_kcontrol_new cxt5051_hp_mixers[] = {
1710        HDA_CODEC_VOLUME("Internal Mic Volume", 0x14, 0x00, HDA_INPUT),
1711        HDA_CODEC_MUTE("Internal Mic Switch", 0x14, 0x00, HDA_INPUT),
1712        HDA_CODEC_VOLUME("External Mic Volume", 0x15, 0x00, HDA_INPUT),
1713        HDA_CODEC_MUTE("External Mic Switch", 0x15, 0x00, HDA_INPUT),
1714        HDA_CODEC_VOLUME("Master Playback Volume", 0x10, 0x00, HDA_OUTPUT),
1715        {
1716                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1717                .name = "Master Playback Switch",
1718                .info = cxt_eapd_info,
1719                .get = cxt_eapd_get,
1720                .put = cxt5051_hp_master_sw_put,
1721                .private_value = 0x1a,
1722        },
1723
1724        {}
1725};
1726
1727static struct snd_kcontrol_new cxt5051_hp_dv6736_mixers[] = {
1728        HDA_CODEC_VOLUME("Mic Volume", 0x14, 0x00, HDA_INPUT),
1729        HDA_CODEC_MUTE("Mic Switch", 0x14, 0x00, HDA_INPUT),
1730        HDA_CODEC_VOLUME("Master Playback Volume", 0x10, 0x00, HDA_OUTPUT),
1731        {
1732                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1733                .name = "Master Playback Switch",
1734                .info = cxt_eapd_info,
1735                .get = cxt_eapd_get,
1736                .put = cxt5051_hp_master_sw_put,
1737                .private_value = 0x1a,
1738        },
1739
1740        {}
1741};
1742
1743static struct hda_verb cxt5051_init_verbs[] = {
1744        /* Line in, Mic */
1745        {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03},
1746        {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1747        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03},
1748        {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1749        {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1750        {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03},
1751        /* SPK  */
1752        {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1753        {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
1754        /* HP, Amp  */
1755        {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1756        {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
1757        /* DAC1 */      
1758        {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1759        /* Record selector: Int mic */
1760        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x44},
1761        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1) | 0x44},
1762        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x44},
1763        /* SPDIF route: PCM */
1764        {0x1c, AC_VERB_SET_CONNECT_SEL, 0x0},
1765        /* EAPD */
1766        {0x1a, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */ 
1767        {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CONEXANT_HP_EVENT},
1768        {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CXT5051_PORTB_EVENT},
1769        {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CXT5051_PORTC_EVENT},
1770        { } /* end */
1771};
1772
1773static struct hda_verb cxt5051_hp_dv6736_init_verbs[] = {
1774        /* Line in, Mic */
1775        {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03},
1776        {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1777        {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0},
1778        {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0},
1779        /* SPK  */
1780        {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1781        {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
1782        /* HP, Amp  */
1783        {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1784        {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
1785        /* DAC1 */
1786        {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1787        /* Record selector: Int mic */
1788        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1) | 0x44},
1789        {0x14, AC_VERB_SET_CONNECT_SEL, 0x1},
1790        /* SPDIF route: PCM */
1791        {0x1c, AC_VERB_SET_CONNECT_SEL, 0x0},
1792        /* EAPD */
1793        {0x1a, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
1794        {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CONEXANT_HP_EVENT},
1795        {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CXT5051_PORTB_EVENT},
1796        { } /* end */
1797};
1798
1799static struct hda_verb cxt5051_lenovo_x200_init_verbs[] = {
1800        /* Line in, Mic */
1801        {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03},
1802        {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1803        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03},
1804        {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1805        {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1806        {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03},
1807        /* SPK  */
1808        {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1809        {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
1810        /* HP, Amp  */
1811        {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1812        {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
1813        /* Docking HP */
1814        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1815        {0x19, AC_VERB_SET_CONNECT_SEL, 0x00},
1816        /* DAC1 */
1817        {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1818        /* Record selector: Int mic */
1819        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x44},
1820        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1) | 0x44},
1821        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x44},
1822        /* SPDIF route: PCM */
1823        {0x1c, AC_VERB_SET_CONNECT_SEL, 0x0},
1824        /* EAPD */
1825        {0x1a, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
1826        {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CONEXANT_HP_EVENT},
1827        {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CXT5051_PORTB_EVENT},
1828        {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CXT5051_PORTC_EVENT},
1829        {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CONEXANT_HP_EVENT},
1830        { } /* end */
1831};
1832
1833/* initialize jack-sensing, too */
1834static int cxt5051_init(struct hda_codec *codec)
1835{
1836        conexant_init(codec);
1837        conexant_init_jacks(codec);
1838        if (codec->patch_ops.unsol_event) {
1839                cxt5051_hp_automute(codec);
1840                cxt5051_portb_automic(codec);
1841                cxt5051_portc_automic(codec);
1842        }
1843        return 0;
1844}
1845
1846
1847enum {
1848        CXT5051_LAPTOP,  /* Laptops w/ EAPD support */
1849        CXT5051_HP,     /* no docking */
1850        CXT5051_HP_DV6736,      /* HP without mic switch */
1851        CXT5051_LENOVO_X200,    /* Lenovo X200 laptop */
1852        CXT5051_MODELS
1853};
1854
1855static const char *cxt5051_models[CXT5051_MODELS] = {
1856        [CXT5051_LAPTOP]        = "laptop",
1857        [CXT5051_HP]            = "hp",
1858        [CXT5051_HP_DV6736]     = "hp-dv6736",
1859        [CXT5051_LENOVO_X200]   = "lenovo-x200",
1860};
1861
1862static struct snd_pci_quirk cxt5051_cfg_tbl[] = {
1863        SND_PCI_QUIRK(0x103c, 0x30cf, "HP DV6736", CXT5051_HP_DV6736),
1864        SND_PCI_QUIRK(0x103c, 0x360b, "Compaq Presario CQ60", CXT5051_HP),
1865        SND_PCI_QUIRK(0x14f1, 0x0101, "Conexant Reference board",
1866                      CXT5051_LAPTOP),
1867        SND_PCI_QUIRK(0x14f1, 0x5051, "HP Spartan 1.1", CXT5051_HP),
1868        SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo X200", CXT5051_LENOVO_X200),
1869        {}
1870};
1871
1872static int patch_cxt5051(struct hda_codec *codec)
1873{
1874        struct conexant_spec *spec;
1875        int board_config;
1876
1877        spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1878        if (!spec)
1879                return -ENOMEM;
1880        codec->spec = spec;
1881        codec->pin_amp_workaround = 1;
1882
1883        codec->patch_ops = conexant_patch_ops;
1884        codec->patch_ops.init = cxt5051_init;
1885
1886        spec->multiout.max_channels = 2;
1887        spec->multiout.num_dacs = ARRAY_SIZE(cxt5051_dac_nids);
1888        spec->multiout.dac_nids = cxt5051_dac_nids;
1889        spec->multiout.dig_out_nid = CXT5051_SPDIF_OUT;
1890        spec->num_adc_nids = 1; /* not 2; via auto-mic switch */
1891        spec->adc_nids = cxt5051_adc_nids;
1892        spec->num_mixers = 1;
1893        spec->mixers[0] = cxt5051_mixers;
1894        spec->num_init_verbs = 1;
1895        spec->init_verbs[0] = cxt5051_init_verbs;
1896        spec->spdif_route = 0;
1897        spec->num_channel_mode = ARRAY_SIZE(cxt5051_modes);
1898        spec->channel_mode = cxt5051_modes;
1899        spec->cur_adc = 0;
1900        spec->cur_adc_idx = 0;
1901
1902        codec->patch_ops.unsol_event = cxt5051_hp_unsol_event;
1903
1904        board_config = snd_hda_check_board_config(codec, CXT5051_MODELS,
1905                                                  cxt5051_models,
1906                                                  cxt5051_cfg_tbl);
1907        switch (board_config) {
1908        case CXT5051_HP:
1909                spec->mixers[0] = cxt5051_hp_mixers;
1910                break;
1911        case CXT5051_HP_DV6736:
1912                spec->init_verbs[0] = cxt5051_hp_dv6736_init_verbs;
1913                spec->mixers[0] = cxt5051_hp_dv6736_mixers;
1914                spec->no_auto_mic = 1;
1915                break;
1916        case CXT5051_LENOVO_X200:
1917                spec->init_verbs[0] = cxt5051_lenovo_x200_init_verbs;
1918                break;
1919        }
1920
1921        return 0;
1922}
1923
1924/* Conexant 5066 specific */
1925
1926static hda_nid_t cxt5066_dac_nids[1] = { 0x10 };
1927static hda_nid_t cxt5066_adc_nids[3] = { 0x14, 0x15, 0x16 };
1928static hda_nid_t cxt5066_capsrc_nids[1] = { 0x17 };
1929#define CXT5066_SPDIF_OUT       0x21
1930
1931/* OLPC's microphone port is DC coupled for use with external sensors,
1932 * therefore we use a 50% mic bias in order to center the input signal with
1933 * the DC input range of the codec. */
1934#define CXT5066_OLPC_EXT_MIC_BIAS PIN_VREF50
1935
1936static struct hda_channel_mode cxt5066_modes[1] = {
1937        { 2, NULL },
1938};
1939
1940static void cxt5066_update_speaker(struct hda_codec *codec)
1941{
1942        struct conexant_spec *spec = codec->spec;
1943        unsigned int pinctl;
1944
1945        snd_printdd("CXT5066: update speaker, hp_present=%d\n",
1946                spec->hp_present);
1947
1948        /* Port A (HP) */
1949        pinctl = ((spec->hp_present & 1) && spec->cur_eapd) ? PIN_HP : 0;
1950        snd_hda_codec_write(codec, 0x19, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
1951                        pinctl);
1952
1953        /* Port D (HP/LO) */
1954        pinctl = ((spec->hp_present & 2) && spec->cur_eapd)
1955                ? spec->port_d_mode : 0;
1956        snd_hda_codec_write(codec, 0x1c, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
1957                        pinctl);
1958
1959        /* CLASS_D AMP */
1960        pinctl = (!spec->hp_present && spec->cur_eapd) ? PIN_OUT : 0;
1961        snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
1962                        pinctl);
1963
1964        if (spec->dell_automute) {
1965                /* DELL AIO Port Rule: PortA > PortD > IntSpk */
1966                pinctl = (!(spec->hp_present & 1) && spec->cur_eapd)
1967                        ? PIN_OUT : 0;
1968                snd_hda_codec_write(codec, 0x1c, 0,
1969                        AC_VERB_SET_PIN_WIDGET_CONTROL, pinctl);
1970        }
1971}
1972
1973/* turn on/off EAPD (+ mute HP) as a master switch */
1974static int cxt5066_hp_master_sw_put(struct snd_kcontrol *kcontrol,
1975                                    struct snd_ctl_elem_value *ucontrol)
1976{
1977        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1978
1979        if (!cxt_eapd_put(kcontrol, ucontrol))
1980                return 0;
1981
1982        cxt5066_update_speaker(codec);
1983        return 1;
1984}
1985
1986/* toggle input of built-in and mic jack appropriately */
1987static void cxt5066_automic(struct hda_codec *codec)
1988{
1989        struct conexant_spec *spec = codec->spec;
1990        struct hda_verb ext_mic_present[] = {
1991                /* enable external mic, port B */
1992                {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, spec->ext_mic_bias},
1993
1994                /* switch to external mic input */
1995                {0x17, AC_VERB_SET_CONNECT_SEL, 0},
1996
1997                /* disable internal mic, port C */
1998                {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
1999                {}
2000        };
2001        static struct hda_verb ext_mic_absent[] = {
2002                /* enable internal mic, port C */
2003                {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2004
2005                /* switch to internal mic input */
2006                {0x17, AC_VERB_SET_CONNECT_SEL, 1},
2007
2008                /* disable external mic, port B */
2009                {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2010                {}
2011        };
2012        unsigned int present;
2013
2014        present = snd_hda_codec_read(codec, 0x1a, 0,
2015                                     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
2016        if (present) {
2017                snd_printdd("CXT5066: external microphone detected\n");
2018                snd_hda_sequence_write(codec, ext_mic_present);
2019        } else {
2020                snd_printdd("CXT5066: external microphone absent\n");
2021                snd_hda_sequence_write(codec, ext_mic_absent);
2022        }
2023}
2024
2025/* mute internal speaker if HP is plugged */
2026static void cxt5066_hp_automute(struct hda_codec *codec)
2027{
2028        struct conexant_spec *spec = codec->spec;
2029        unsigned int portA, portD;
2030
2031        /* Port A */
2032        portA = snd_hda_codec_read(codec, 0x19, 0, AC_VERB_GET_PIN_SENSE, 0)
2033                & AC_PINSENSE_PRESENCE;
2034
2035        /* Port D */
2036        portD = (snd_hda_codec_read(codec, 0x1c, 0, AC_VERB_GET_PIN_SENSE, 0)
2037                & AC_PINSENSE_PRESENCE) << 1;
2038
2039        spec->hp_present = !!(portA | portD);
2040        snd_printdd("CXT5066: hp automute portA=%x portD=%x present=%d\n",
2041                portA, portD, spec->hp_present);
2042        cxt5066_update_speaker(codec);
2043}
2044
2045/* unsolicited event for jack sensing */
2046static void cxt5066_unsol_event(struct hda_codec *codec, unsigned int res)
2047{
2048        snd_printdd("CXT5066: unsol event %x (%x)\n", res, res >> 26);
2049        switch (res >> 26) {
2050        case CONEXANT_HP_EVENT:
2051                cxt5066_hp_automute(codec);
2052                break;
2053        case CONEXANT_MIC_EVENT:
2054                cxt5066_automic(codec);
2055                break;
2056        }
2057}
2058
2059static const struct hda_input_mux cxt5066_analog_mic_boost = {
2060        .num_items = 5,
2061        .items = {
2062                { "0dB",  0 },
2063                { "10dB", 1 },
2064                { "20dB", 2 },
2065                { "30dB", 3 },
2066                { "40dB", 4 },
2067        },
2068};
2069
2070static int cxt5066_mic_boost_mux_enum_info(struct snd_kcontrol *kcontrol,
2071                                           struct snd_ctl_elem_info *uinfo)
2072{
2073        return snd_hda_input_mux_info(&cxt5066_analog_mic_boost, uinfo);
2074}
2075
2076static int cxt5066_mic_boost_mux_enum_get(struct snd_kcontrol *kcontrol,
2077                                          struct snd_ctl_elem_value *ucontrol)
2078{
2079        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2080        int val;
2081
2082        val = snd_hda_codec_read(codec, 0x17, 0,
2083                AC_VERB_GET_AMP_GAIN_MUTE, AC_AMP_GET_OUTPUT);
2084
2085        ucontrol->value.enumerated.item[0] = val & AC_AMP_GAIN;
2086        return 0;
2087}
2088
2089static int cxt5066_mic_boost_mux_enum_put(struct snd_kcontrol *kcontrol,
2090                                          struct snd_ctl_elem_value *ucontrol)
2091{
2092        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2093        const struct hda_input_mux *imux = &cxt5066_analog_mic_boost;
2094        unsigned int idx;
2095
2096        if (!imux->num_items)
2097                return 0;
2098        idx = ucontrol->value.enumerated.item[0];
2099        if (idx >= imux->num_items)
2100                idx = imux->num_items - 1;
2101
2102        snd_hda_codec_write_cache(codec, 0x17, 0,
2103                AC_VERB_SET_AMP_GAIN_MUTE,
2104                AC_AMP_SET_RIGHT | AC_AMP_SET_LEFT | AC_AMP_SET_OUTPUT |
2105                        imux->items[idx].index);
2106
2107        return 1;
2108}
2109
2110static struct hda_input_mux cxt5066_capture_source = {
2111        .num_items = 4,
2112        .items = {
2113                { "Mic B", 0 },
2114                { "Mic C", 1 },
2115                { "Mic E", 2 },
2116                { "Mic F", 3 },
2117        },
2118};
2119
2120static struct hda_bind_ctls cxt5066_bind_capture_vol_others = {
2121        .ops = &snd_hda_bind_vol,
2122        .values = {
2123                HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_INPUT),
2124                HDA_COMPOSE_AMP_VAL(0x14, 3, 2, HDA_INPUT),
2125                0
2126        },
2127};
2128
2129static struct hda_bind_ctls cxt5066_bind_capture_sw_others = {
2130        .ops = &snd_hda_bind_sw,
2131        .values = {
2132                HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_INPUT),
2133                HDA_COMPOSE_AMP_VAL(0x14, 3, 2, HDA_INPUT),
2134                0
2135        },
2136};
2137
2138static struct snd_kcontrol_new cxt5066_mixer_master[] = {
2139        HDA_CODEC_VOLUME("Master Playback Volume", 0x10, 0x00, HDA_OUTPUT),
2140        {}
2141};
2142
2143static struct snd_kcontrol_new cxt5066_mixer_master_olpc[] = {
2144        {
2145                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2146                .name = "Master Playback Volume",
2147                .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
2148                                  SNDRV_CTL_ELEM_ACCESS_TLV_READ |
2149                                  SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK,
2150                .info = snd_hda_mixer_amp_volume_info,
2151                .get = snd_hda_mixer_amp_volume_get,
2152                .put = snd_hda_mixer_amp_volume_put,
2153                .tlv = { .c = snd_hda_mixer_amp_tlv },
2154                /* offset by 28 volume steps to limit minimum gain to -46dB */
2155                .private_value =
2156                        HDA_COMPOSE_AMP_VAL_OFS(0x10, 3, 0, HDA_OUTPUT, 28),
2157        },
2158        {}
2159};
2160
2161static struct snd_kcontrol_new cxt5066_mixers[] = {
2162        {
2163                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2164                .name = "Master Playback Switch",
2165                .info = cxt_eapd_info,
2166                .get = cxt_eapd_get,
2167                .put = cxt5066_hp_master_sw_put,
2168                .private_value = 0x1d,
2169        },
2170
2171        {
2172                .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2173                .name = "Analog Mic Boost Capture Enum",
2174                .info = cxt5066_mic_boost_mux_enum_info,
2175                .get = cxt5066_mic_boost_mux_enum_get,
2176                .put = cxt5066_mic_boost_mux_enum_put,
2177        },
2178
2179        HDA_BIND_VOL("Capture Volume", &cxt5066_bind_capture_vol_others),
2180        HDA_BIND_SW("Capture Switch", &cxt5066_bind_capture_sw_others),
2181        {}
2182};
2183
2184static struct hda_verb cxt5066_init_verbs[] = {
2185        {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, /* Port B */
2186        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, /* Port C */
2187        {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Port F */
2188        {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Port E */
2189
2190        /* Speakers  */
2191        {0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2192        {0x1f, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
2193
2194        /* HP, Amp  */
2195        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2196        {0x19, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
2197
2198        {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2199        {0x1c, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
2200
2201        /* DAC1 */
2202        {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2203
2204        /* Node 14 connections: 0x17 0x18 0x23 0x24 0x27 */
2205        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x50},
2206        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2207        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2) | 0x50},
2208        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2209        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2210
2211        /* no digital microphone support yet */
2212        {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2213
2214        /* Audio input selector */
2215        {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x3},
2216
2217        /* SPDIF route: PCM */
2218        {0x20, AC_VERB_SET_CONNECT_SEL, 0x0},
2219        {0x22, AC_VERB_SET_CONNECT_SEL, 0x0},
2220
2221        {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2222        {0x22, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2223
2224        /* EAPD */
2225        {0x1d, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
2226
2227        /* not handling these yet */
2228        {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, 0},
2229        {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, 0},
2230        {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, 0},
2231        {0x1c, AC_VERB_SET_UNSOLICITED_ENABLE, 0},
2232        {0x1d, AC_VERB_SET_UNSOLICITED_ENABLE, 0},
2233        {0x1e, AC_VERB_SET_UNSOLICITED_ENABLE, 0},
2234        {0x20, AC_VERB_SET_UNSOLICITED_ENABLE, 0},
2235        {0x22, AC_VERB_SET_UNSOLICITED_ENABLE, 0},
2236        { } /* end */
2237};
2238
2239static struct hda_verb cxt5066_init_verbs_olpc[] = {
2240        /* Port A: headphones */
2241        {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2242        {0x19, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
2243
2244        /* Port B: external microphone */
2245        {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, CXT5066_OLPC_EXT_MIC_BIAS},
2246
2247        /* Port C: internal microphone */
2248        {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2249
2250        /* Port D: unused */
2251        {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2252
2253        /* Port E: unused, but has primary EAPD */
2254        {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2255        {0x1d, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
2256
2257        /* Port F: unused */
2258        {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2259
2260        /* Port G: internal speakers */
2261        {0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2262        {0x1f, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
2263
2264        /* DAC1 */
2265        {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2266
2267        /* DAC2: unused */
2268        {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2269
2270        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x50},
2271        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2272        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2273        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2274        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2275        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2276        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2277        {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2278        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2279        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2280        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2281        {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2282
2283        /* Disable digital microphone port */
2284        {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2285
2286        /* Audio input selectors */
2287        {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x3},
2288        {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2289
2290        /* Disable SPDIF */
2291        {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2292        {0x22, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2293
2294        /* enable unsolicited events for Port A and B */
2295        {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT},
2296        {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT},
2297        { } /* end */
2298};
2299
2300static struct hda_verb cxt5066_init_verbs_portd_lo[] = {
2301        {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2302        { } /* end */
2303};
2304
2305/* initialize jack-sensing, too */
2306static int cxt5066_init(struct hda_codec *codec)
2307{
2308        snd_printdd("CXT5066: init\n");
2309        conexant_init(codec);
2310        if (codec->patch_ops.unsol_event) {
2311                cxt5066_hp_automute(codec);
2312                cxt5066_automic(codec);
2313        }
2314        return 0;
2315}
2316
2317enum {
2318        CXT5066_LAPTOP,                 /* Laptops w/ EAPD support */
2319        CXT5066_DELL_LAPTOP,    /* Dell Laptop */
2320        CXT5066_OLPC_XO_1_5,    /* OLPC XO 1.5 */
2321        CXT5066_MODELS
2322};
2323
2324static const char *cxt5066_models[CXT5066_MODELS] = {
2325        [CXT5066_LAPTOP]                = "laptop",
2326        [CXT5066_DELL_LAPTOP]   = "dell-laptop",
2327        [CXT5066_OLPC_XO_1_5]   = "olpc-xo-1_5",
2328};
2329
2330static struct snd_pci_quirk cxt5066_cfg_tbl[] = {
2331        SND_PCI_QUIRK(0x14f1, 0x0101, "Conexant Reference board",
2332                      CXT5066_LAPTOP),
2333        SND_PCI_QUIRK(0x1028, 0x02f5, "Dell",
2334                      CXT5066_DELL_LAPTOP),
2335        SND_PCI_QUIRK(0x152d, 0x0833, "OLPC XO-1.5", CXT5066_OLPC_XO_1_5),
2336        {}
2337};
2338
2339static int patch_cxt5066(struct hda_codec *codec)
2340{
2341        struct conexant_spec *spec;
2342        int board_config;
2343
2344        spec = kzalloc(sizeof(*spec), GFP_KERNEL);
2345        if (!spec)
2346                return -ENOMEM;
2347        codec->spec = spec;
2348
2349        codec->patch_ops = conexant_patch_ops;
2350        codec->patch_ops.init = cxt5066_init;
2351
2352        spec->dell_automute = 0;
2353        spec->multiout.max_channels = 2;
2354        spec->multiout.num_dacs = ARRAY_SIZE(cxt5066_dac_nids);
2355        spec->multiout.dac_nids = cxt5066_dac_nids;
2356        spec->multiout.dig_out_nid = CXT5066_SPDIF_OUT;
2357        spec->num_adc_nids = 1;
2358        spec->adc_nids = cxt5066_adc_nids;
2359        spec->capsrc_nids = cxt5066_capsrc_nids;
2360        spec->input_mux = &cxt5066_capture_source;
2361
2362        spec->port_d_mode = PIN_HP;
2363        spec->ext_mic_bias = PIN_VREF80;
2364
2365        spec->num_init_verbs = 1;
2366        spec->init_verbs[0] = cxt5066_init_verbs;
2367        spec->num_channel_mode = ARRAY_SIZE(cxt5066_modes);
2368        spec->channel_mode = cxt5066_modes;
2369        spec->cur_adc = 0;
2370        spec->cur_adc_idx = 0;
2371
2372        board_config = snd_hda_check_board_config(codec, CXT5066_MODELS,
2373                                                  cxt5066_models, cxt5066_cfg_tbl);
2374        switch (board_config) {
2375        default:
2376        case CXT5066_LAPTOP:
2377                spec->mixers[spec->num_mixers++] = cxt5066_mixer_master;
2378                spec->mixers[spec->num_mixers++] = cxt5066_mixers;
2379                break;
2380        case CXT5066_DELL_LAPTOP:
2381                spec->mixers[spec->num_mixers++] = cxt5066_mixer_master;
2382                spec->mixers[spec->num_mixers++] = cxt5066_mixers;
2383
2384                spec->port_d_mode = PIN_OUT;
2385                spec->init_verbs[spec->num_init_verbs] = cxt5066_init_verbs_portd_lo;
2386                spec->num_init_verbs++;
2387                spec->dell_automute = 1;
2388                break;
2389        case CXT5066_OLPC_XO_1_5:
2390                codec->patch_ops.unsol_event = cxt5066_unsol_event;
2391                spec->init_verbs[0] = cxt5066_init_verbs_olpc;
2392                spec->mixers[spec->num_mixers++] = cxt5066_mixer_master_olpc;
2393                spec->mixers[spec->num_mixers++] = cxt5066_mixers;
2394                spec->port_d_mode = 0;
2395                spec->ext_mic_bias = CXT5066_OLPC_EXT_MIC_BIAS;
2396
2397                /* no S/PDIF out */
2398                spec->multiout.dig_out_nid = 0;
2399
2400                /* input source automatically selected */
2401                spec->input_mux = NULL;
2402                break;
2403        }
2404
2405        return 0;
2406}
2407
2408/*
2409 */
2410
2411static struct hda_codec_preset snd_hda_preset_conexant[] = {
2412        { .id = 0x14f15045, .name = "CX20549 (Venice)",
2413          .patch = patch_cxt5045 },
2414        { .id = 0x14f15047, .name = "CX20551 (Waikiki)",
2415          .patch = patch_cxt5047 },
2416        { .id = 0x14f15051, .name = "CX20561 (Hermosa)",
2417          .patch = patch_cxt5051 },
2418        { .id = 0x14f15066, .name = "CX20582 (Pebble)",
2419          .patch = patch_cxt5066 },
2420        {} /* terminator */
2421};
2422
2423MODULE_ALIAS("snd-hda-codec-id:14f15045");
2424MODULE_ALIAS("snd-hda-codec-id:14f15047");
2425MODULE_ALIAS("snd-hda-codec-id:14f15051");
2426MODULE_ALIAS("snd-hda-codec-id:14f15066");
2427
2428MODULE_LICENSE("GPL");
2429MODULE_DESCRIPTION("Conexant HD-audio codec");
2430
2431static struct hda_codec_preset_list conexant_list = {
2432        .preset = snd_hda_preset_conexant,
2433        .owner = THIS_MODULE,
2434};
2435
2436static int __init patch_conexant_init(void)
2437{
2438        return snd_hda_add_codec_preset(&conexant_list);
2439}
2440
2441static void __exit patch_conexant_exit(void)
2442{
2443        snd_hda_delete_codec_preset(&conexant_list);
2444}
2445
2446module_init(patch_conexant_init)
2447module_exit(patch_conexant_exit)
2448