linux/sound/pci/hda/patch_cirrus.c
<<
>>
Prefs
   1/*
   2 * HD audio interface patch for Cirrus Logic CS420x chip
   3 *
   4 * Copyright (c) 2009 Takashi Iwai <tiwai@suse.de>
   5 *
   6 *  This driver is free software; you can redistribute it and/or modify
   7 *  it under the terms of the GNU General Public License as published by
   8 *  the Free Software Foundation; either version 2 of the License, or
   9 *  (at your option) any later version.
  10 *
  11 *  This driver is distributed in the hope that it will be useful,
  12 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14 *  GNU General Public License for more details.
  15 *
  16 *  You should have received a copy of the GNU General Public License
  17 *  along with this program; if not, write to the Free Software
  18 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  19 */
  20
  21#include <linux/init.h>
  22#include <linux/delay.h>
  23#include <linux/slab.h>
  24#include <linux/pci.h>
  25#include <sound/core.h>
  26#include "hda_codec.h"
  27#include "hda_local.h"
  28
  29/*
  30 */
  31
  32struct cs_spec {
  33        int board_config;
  34        struct auto_pin_cfg autocfg;
  35        struct hda_multi_out multiout;
  36        struct snd_kcontrol *vmaster_sw;
  37        struct snd_kcontrol *vmaster_vol;
  38
  39        hda_nid_t dac_nid[AUTO_CFG_MAX_OUTS];
  40        hda_nid_t slave_dig_outs[2];
  41
  42        unsigned int input_idx[AUTO_PIN_LAST];
  43        unsigned int capsrc_idx[AUTO_PIN_LAST];
  44        hda_nid_t adc_nid[AUTO_PIN_LAST];
  45        unsigned int adc_idx[AUTO_PIN_LAST];
  46        unsigned int num_inputs;
  47        unsigned int cur_input;
  48        unsigned int automic_idx;
  49        hda_nid_t cur_adc;
  50        unsigned int cur_adc_stream_tag;
  51        unsigned int cur_adc_format;
  52        hda_nid_t dig_in;
  53
  54        struct hda_bind_ctls *capture_bind[2];
  55
  56        unsigned int gpio_mask;
  57        unsigned int gpio_dir;
  58        unsigned int gpio_data;
  59
  60        struct hda_pcm pcm_rec[2];      /* PCM information */
  61
  62        unsigned int hp_detect:1;
  63        unsigned int mic_detect:1;
  64};
  65
  66/* available models */
  67enum {
  68        CS420X_MBP53,
  69        CS420X_MBP55,
  70        CS420X_IMAC27,
  71        CS420X_AUTO,
  72        CS420X_MODELS
  73};
  74
  75/* Vendor-specific processing widget */
  76#define CS420X_VENDOR_NID       0x11
  77#define CS_DIG_OUT1_PIN_NID     0x10
  78#define CS_DIG_OUT2_PIN_NID     0x15
  79#define CS_DMIC1_PIN_NID        0x12
  80#define CS_DMIC2_PIN_NID        0x0e
  81
  82/* coef indices */
  83#define IDX_SPDIF_STAT          0x0000
  84#define IDX_SPDIF_CTL           0x0001
  85#define IDX_ADC_CFG             0x0002
  86/* SZC bitmask, 4 modes below:
  87 * 0 = immediate,
  88 * 1 = digital immediate, analog zero-cross
  89 * 2 = digtail & analog soft-ramp
  90 * 3 = digital soft-ramp, analog zero-cross
  91 */
  92#define   CS_COEF_ADC_SZC_MASK          (3 << 0)
  93#define   CS_COEF_ADC_MIC_SZC_MODE      (3 << 0) /* SZC setup for mic */
  94#define   CS_COEF_ADC_LI_SZC_MODE       (3 << 0) /* SZC setup for line-in */
  95/* PGA mode: 0 = differential, 1 = signle-ended */
  96#define   CS_COEF_ADC_MIC_PGA_MODE      (1 << 5) /* PGA setup for mic */
  97#define   CS_COEF_ADC_LI_PGA_MODE       (1 << 6) /* PGA setup for line-in */
  98#define IDX_DAC_CFG             0x0003
  99/* SZC bitmask, 4 modes below:
 100 * 0 = Immediate
 101 * 1 = zero-cross
 102 * 2 = soft-ramp
 103 * 3 = soft-ramp on zero-cross
 104 */
 105#define   CS_COEF_DAC_HP_SZC_MODE       (3 << 0) /* nid 0x02 */
 106#define   CS_COEF_DAC_LO_SZC_MODE       (3 << 2) /* nid 0x03 */
 107#define   CS_COEF_DAC_SPK_SZC_MODE      (3 << 4) /* nid 0x04 */
 108
 109#define IDX_BEEP_CFG            0x0004
 110/* 0x0008 - test reg key */
 111/* 0x0009 - 0x0014 -> 12 test regs */
 112/* 0x0015 - visibility reg */
 113
 114
 115static inline int cs_vendor_coef_get(struct hda_codec *codec, unsigned int idx)
 116{
 117        snd_hda_codec_write(codec, CS420X_VENDOR_NID, 0,
 118                            AC_VERB_SET_COEF_INDEX, idx);
 119        return snd_hda_codec_read(codec, CS420X_VENDOR_NID, 0,
 120                                  AC_VERB_GET_PROC_COEF, 0);
 121}
 122
 123static inline void cs_vendor_coef_set(struct hda_codec *codec, unsigned int idx,
 124                                      unsigned int coef)
 125{
 126        snd_hda_codec_write(codec, CS420X_VENDOR_NID, 0,
 127                            AC_VERB_SET_COEF_INDEX, idx);
 128        snd_hda_codec_write(codec, CS420X_VENDOR_NID, 0,
 129                            AC_VERB_SET_PROC_COEF, coef);
 130}
 131
 132
 133#define HP_EVENT        1
 134#define MIC_EVENT       2
 135
 136/*
 137 * PCM callbacks
 138 */
 139static int cs_playback_pcm_open(struct hda_pcm_stream *hinfo,
 140                                struct hda_codec *codec,
 141                                struct snd_pcm_substream *substream)
 142{
 143        struct cs_spec *spec = codec->spec;
 144        return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
 145                                             hinfo);
 146}
 147
 148static int cs_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
 149                                   struct hda_codec *codec,
 150                                   unsigned int stream_tag,
 151                                   unsigned int format,
 152                                   struct snd_pcm_substream *substream)
 153{
 154        struct cs_spec *spec = codec->spec;
 155        return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
 156                                                stream_tag, format, substream);
 157}
 158
 159static int cs_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
 160                                   struct hda_codec *codec,
 161                                   struct snd_pcm_substream *substream)
 162{
 163        struct cs_spec *spec = codec->spec;
 164        return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
 165}
 166
 167/*
 168 * Digital out
 169 */
 170static int cs_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
 171                                    struct hda_codec *codec,
 172                                    struct snd_pcm_substream *substream)
 173{
 174        struct cs_spec *spec = codec->spec;
 175        return snd_hda_multi_out_dig_open(codec, &spec->multiout);
 176}
 177
 178static int cs_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
 179                                     struct hda_codec *codec,
 180                                     struct snd_pcm_substream *substream)
 181{
 182        struct cs_spec *spec = codec->spec;
 183        return snd_hda_multi_out_dig_close(codec, &spec->multiout);
 184}
 185
 186static int cs_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
 187                                       struct hda_codec *codec,
 188                                       unsigned int stream_tag,
 189                                       unsigned int format,
 190                                       struct snd_pcm_substream *substream)
 191{
 192        struct cs_spec *spec = codec->spec;
 193        return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, stream_tag,
 194                                             format, substream);
 195}
 196
 197static int cs_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
 198                                       struct hda_codec *codec,
 199                                       struct snd_pcm_substream *substream)
 200{
 201        struct cs_spec *spec = codec->spec;
 202        return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout);
 203}
 204
 205/*
 206 * Analog capture
 207 */
 208static int cs_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
 209                                  struct hda_codec *codec,
 210                                  unsigned int stream_tag,
 211                                  unsigned int format,
 212                                  struct snd_pcm_substream *substream)
 213{
 214        struct cs_spec *spec = codec->spec;
 215        spec->cur_adc = spec->adc_nid[spec->cur_input];
 216        spec->cur_adc_stream_tag = stream_tag;
 217        spec->cur_adc_format = format;
 218        snd_hda_codec_setup_stream(codec, spec->cur_adc, stream_tag, 0, format);
 219        return 0;
 220}
 221
 222static int cs_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
 223                                  struct hda_codec *codec,
 224                                  struct snd_pcm_substream *substream)
 225{
 226        struct cs_spec *spec = codec->spec;
 227        snd_hda_codec_cleanup_stream(codec, spec->cur_adc);
 228        spec->cur_adc = 0;
 229        return 0;
 230}
 231
 232/*
 233 */
 234static struct hda_pcm_stream cs_pcm_analog_playback = {
 235        .substreams = 1,
 236        .channels_min = 2,
 237        .channels_max = 2,
 238        .ops = {
 239                .open = cs_playback_pcm_open,
 240                .prepare = cs_playback_pcm_prepare,
 241                .cleanup = cs_playback_pcm_cleanup
 242        },
 243};
 244
 245static struct hda_pcm_stream cs_pcm_analog_capture = {
 246        .substreams = 1,
 247        .channels_min = 2,
 248        .channels_max = 2,
 249        .ops = {
 250                .prepare = cs_capture_pcm_prepare,
 251                .cleanup = cs_capture_pcm_cleanup
 252        },
 253};
 254
 255static struct hda_pcm_stream cs_pcm_digital_playback = {
 256        .substreams = 1,
 257        .channels_min = 2,
 258        .channels_max = 2,
 259        .ops = {
 260                .open = cs_dig_playback_pcm_open,
 261                .close = cs_dig_playback_pcm_close,
 262                .prepare = cs_dig_playback_pcm_prepare,
 263                .cleanup = cs_dig_playback_pcm_cleanup
 264        },
 265};
 266
 267static struct hda_pcm_stream cs_pcm_digital_capture = {
 268        .substreams = 1,
 269        .channels_min = 2,
 270        .channels_max = 2,
 271};
 272
 273static int cs_build_pcms(struct hda_codec *codec)
 274{
 275        struct cs_spec *spec = codec->spec;
 276        struct hda_pcm *info = spec->pcm_rec;
 277
 278        codec->pcm_info = info;
 279        codec->num_pcms = 0;
 280
 281        info->name = "Cirrus Analog";
 282        info->stream[SNDRV_PCM_STREAM_PLAYBACK] = cs_pcm_analog_playback;
 283        info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->dac_nid[0];
 284        info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max =
 285                spec->multiout.max_channels;
 286        info->stream[SNDRV_PCM_STREAM_CAPTURE] = cs_pcm_analog_capture;
 287        info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
 288                spec->adc_nid[spec->cur_input];
 289        codec->num_pcms++;
 290
 291        if (!spec->multiout.dig_out_nid && !spec->dig_in)
 292                return 0;
 293
 294        info++;
 295        info->name = "Cirrus Digital";
 296        info->pcm_type = spec->autocfg.dig_out_type[0];
 297        if (!info->pcm_type)
 298                info->pcm_type = HDA_PCM_TYPE_SPDIF;
 299        if (spec->multiout.dig_out_nid) {
 300                info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
 301                        cs_pcm_digital_playback;
 302                info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
 303                        spec->multiout.dig_out_nid;
 304        }
 305        if (spec->dig_in) {
 306                info->stream[SNDRV_PCM_STREAM_CAPTURE] =
 307                        cs_pcm_digital_capture;
 308                info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in;
 309        }
 310        codec->num_pcms++;
 311
 312        return 0;
 313}
 314
 315/*
 316 * parse codec topology
 317 */
 318
 319static hda_nid_t get_dac(struct hda_codec *codec, hda_nid_t pin)
 320{
 321        hda_nid_t dac;
 322        if (!pin)
 323                return 0;
 324        if (snd_hda_get_connections(codec, pin, &dac, 1) != 1)
 325                return 0;
 326        return dac;
 327}
 328
 329static int is_ext_mic(struct hda_codec *codec, unsigned int idx)
 330{
 331        struct cs_spec *spec = codec->spec;
 332        struct auto_pin_cfg *cfg = &spec->autocfg;
 333        hda_nid_t pin = cfg->inputs[idx].pin;
 334        unsigned int val = snd_hda_query_pin_caps(codec, pin);
 335        if (!(val & AC_PINCAP_PRES_DETECT))
 336                return 0;
 337        val = snd_hda_codec_get_pincfg(codec, pin);
 338        return (snd_hda_get_input_pin_attr(val) != INPUT_PIN_ATTR_INT);
 339}
 340
 341static hda_nid_t get_adc(struct hda_codec *codec, hda_nid_t pin,
 342                         unsigned int *idxp)
 343{
 344        int i;
 345        hda_nid_t nid;
 346
 347        nid = codec->start_nid;
 348        for (i = 0; i < codec->num_nodes; i++, nid++) {
 349                hda_nid_t pins[2];
 350                unsigned int type;
 351                int j, nums;
 352                type = (get_wcaps(codec, nid) & AC_WCAP_TYPE)
 353                        >> AC_WCAP_TYPE_SHIFT;
 354                if (type != AC_WID_AUD_IN)
 355                        continue;
 356                nums = snd_hda_get_connections(codec, nid, pins,
 357                                               ARRAY_SIZE(pins));
 358                if (nums <= 0)
 359                        continue;
 360                for (j = 0; j < nums; j++) {
 361                        if (pins[j] == pin) {
 362                                *idxp = j;
 363                                return nid;
 364                        }
 365                }
 366        }
 367        return 0;
 368}
 369
 370static int is_active_pin(struct hda_codec *codec, hda_nid_t nid)
 371{
 372        unsigned int val;
 373        val = snd_hda_codec_get_pincfg(codec, nid);
 374        return (get_defcfg_connect(val) != AC_JACK_PORT_NONE);
 375}
 376
 377static int parse_output(struct hda_codec *codec)
 378{
 379        struct cs_spec *spec = codec->spec;
 380        struct auto_pin_cfg *cfg = &spec->autocfg;
 381        int i, extra_nids;
 382        hda_nid_t dac;
 383
 384        for (i = 0; i < cfg->line_outs; i++) {
 385                dac = get_dac(codec, cfg->line_out_pins[i]);
 386                if (!dac)
 387                        break;
 388                spec->dac_nid[i] = dac;
 389        }
 390        spec->multiout.num_dacs = i;
 391        spec->multiout.dac_nids = spec->dac_nid;
 392        spec->multiout.max_channels = i * 2;
 393
 394        /* add HP and speakers */
 395        extra_nids = 0;
 396        for (i = 0; i < cfg->hp_outs; i++) {
 397                dac = get_dac(codec, cfg->hp_pins[i]);
 398                if (!dac)
 399                        break;
 400                if (!i)
 401                        spec->multiout.hp_nid = dac;
 402                else
 403                        spec->multiout.extra_out_nid[extra_nids++] = dac;
 404        }
 405        for (i = 0; i < cfg->speaker_outs; i++) {
 406                dac = get_dac(codec, cfg->speaker_pins[i]);
 407                if (!dac)
 408                        break;
 409                spec->multiout.extra_out_nid[extra_nids++] = dac;
 410        }
 411
 412        if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) {
 413                cfg->speaker_outs = cfg->line_outs;
 414                memcpy(cfg->speaker_pins, cfg->line_out_pins,
 415                       sizeof(cfg->speaker_pins));
 416                cfg->line_outs = 0;
 417        }
 418
 419        return 0;
 420}
 421
 422static int parse_input(struct hda_codec *codec)
 423{
 424        struct cs_spec *spec = codec->spec;
 425        struct auto_pin_cfg *cfg = &spec->autocfg;
 426        int i;
 427
 428        for (i = 0; i < cfg->num_inputs; i++) {
 429                hda_nid_t pin = cfg->inputs[i].pin;
 430                spec->input_idx[spec->num_inputs] = i;
 431                spec->capsrc_idx[i] = spec->num_inputs++;
 432                spec->cur_input = i;
 433                spec->adc_nid[i] = get_adc(codec, pin, &spec->adc_idx[i]);
 434        }
 435        if (!spec->num_inputs)
 436                return 0;
 437
 438        /* check whether the automatic mic switch is available */
 439        if (spec->num_inputs == 2 &&
 440            cfg->inputs[0].type == AUTO_PIN_MIC &&
 441            cfg->inputs[1].type == AUTO_PIN_MIC) {
 442                if (is_ext_mic(codec, cfg->inputs[0].pin)) {
 443                        if (!is_ext_mic(codec, cfg->inputs[1].pin)) {
 444                                spec->mic_detect = 1;
 445                                spec->automic_idx = 0;
 446                        }
 447                } else {
 448                        if (is_ext_mic(codec, cfg->inputs[1].pin)) {
 449                                spec->mic_detect = 1;
 450                                spec->automic_idx = 1;
 451                        }
 452                }
 453        }
 454        return 0;
 455}
 456
 457
 458static int parse_digital_output(struct hda_codec *codec)
 459{
 460        struct cs_spec *spec = codec->spec;
 461        struct auto_pin_cfg *cfg = &spec->autocfg;
 462        hda_nid_t nid;
 463
 464        if (!cfg->dig_outs)
 465                return 0;
 466        if (snd_hda_get_connections(codec, cfg->dig_out_pins[0], &nid, 1) < 1)
 467                return 0;
 468        spec->multiout.dig_out_nid = nid;
 469        spec->multiout.share_spdif = 1;
 470        if (cfg->dig_outs > 1 &&
 471            snd_hda_get_connections(codec, cfg->dig_out_pins[1], &nid, 1) > 0) {
 472                spec->slave_dig_outs[0] = nid;
 473                codec->slave_dig_outs = spec->slave_dig_outs;
 474        }
 475        return 0;
 476}
 477
 478static int parse_digital_input(struct hda_codec *codec)
 479{
 480        struct cs_spec *spec = codec->spec;
 481        struct auto_pin_cfg *cfg = &spec->autocfg;
 482        int idx;
 483
 484        if (cfg->dig_in_pin)
 485                spec->dig_in = get_adc(codec, cfg->dig_in_pin, &idx);
 486        return 0;
 487}
 488
 489/*
 490 * create mixer controls
 491 */
 492
 493static const char * const dir_sfx[2] = { "Playback", "Capture" };
 494
 495static int add_mute(struct hda_codec *codec, const char *name, int index,
 496                    unsigned int pval, int dir, struct snd_kcontrol **kctlp)
 497{
 498        char tmp[44];
 499        struct snd_kcontrol_new knew =
 500                HDA_CODEC_MUTE_IDX(tmp, index, 0, 0, HDA_OUTPUT);
 501        knew.private_value = pval;
 502        snprintf(tmp, sizeof(tmp), "%s %s Switch", name, dir_sfx[dir]);
 503        *kctlp = snd_ctl_new1(&knew, codec);
 504        (*kctlp)->id.subdevice = HDA_SUBDEV_AMP_FLAG;
 505        return snd_hda_ctl_add(codec, 0, *kctlp);
 506}
 507
 508static int add_volume(struct hda_codec *codec, const char *name,
 509                      int index, unsigned int pval, int dir,
 510                      struct snd_kcontrol **kctlp)
 511{
 512        char tmp[32];
 513        struct snd_kcontrol_new knew =
 514                HDA_CODEC_VOLUME_IDX(tmp, index, 0, 0, HDA_OUTPUT);
 515        knew.private_value = pval;
 516        snprintf(tmp, sizeof(tmp), "%s %s Volume", name, dir_sfx[dir]);
 517        *kctlp = snd_ctl_new1(&knew, codec);
 518        (*kctlp)->id.subdevice = HDA_SUBDEV_AMP_FLAG;
 519        return snd_hda_ctl_add(codec, 0, *kctlp);
 520}
 521
 522static void fix_volume_caps(struct hda_codec *codec, hda_nid_t dac)
 523{
 524        unsigned int caps;
 525
 526        /* set the upper-limit for mixer amp to 0dB */
 527        caps = query_amp_caps(codec, dac, HDA_OUTPUT);
 528        caps &= ~(0x7f << AC_AMPCAP_NUM_STEPS_SHIFT);
 529        caps |= ((caps >> AC_AMPCAP_OFFSET_SHIFT) & 0x7f)
 530                << AC_AMPCAP_NUM_STEPS_SHIFT;
 531        snd_hda_override_amp_caps(codec, dac, HDA_OUTPUT, caps);
 532}
 533
 534static int add_vmaster(struct hda_codec *codec, hda_nid_t dac)
 535{
 536        struct cs_spec *spec = codec->spec;
 537        unsigned int tlv[4];
 538        int err;
 539
 540        spec->vmaster_sw =
 541                snd_ctl_make_virtual_master("Master Playback Switch", NULL);
 542        err = snd_hda_ctl_add(codec, dac, spec->vmaster_sw);
 543        if (err < 0)
 544                return err;
 545
 546        snd_hda_set_vmaster_tlv(codec, dac, HDA_OUTPUT, tlv);
 547        spec->vmaster_vol =
 548                snd_ctl_make_virtual_master("Master Playback Volume", tlv);
 549        err = snd_hda_ctl_add(codec, dac, spec->vmaster_vol);
 550        if (err < 0)
 551                return err;
 552        return 0;
 553}
 554
 555static int add_output(struct hda_codec *codec, hda_nid_t dac, int idx,
 556                      int num_ctls, int type)
 557{
 558        struct cs_spec *spec = codec->spec;
 559        const char *name;
 560        int err, index;
 561        struct snd_kcontrol *kctl;
 562        static char *speakers[] = {
 563                "Front Speaker", "Surround Speaker", "Bass Speaker"
 564        };
 565        static char *line_outs[] = {
 566                "Front Line-Out", "Surround Line-Out", "Bass Line-Out"
 567        };
 568
 569        fix_volume_caps(codec, dac);
 570        if (!spec->vmaster_sw) {
 571                err = add_vmaster(codec, dac);
 572                if (err < 0)
 573                        return err;
 574        }
 575
 576        index = 0;
 577        switch (type) {
 578        case AUTO_PIN_HP_OUT:
 579                name = "Headphone";
 580                index = idx;
 581                break;
 582        case AUTO_PIN_SPEAKER_OUT:
 583                if (num_ctls > 1)
 584                        name = speakers[idx];
 585                else
 586                        name = "Speaker";
 587                break;
 588        default:
 589                if (num_ctls > 1)
 590                        name = line_outs[idx];
 591                else
 592                        name = "Line-Out";
 593                break;
 594        }
 595
 596        err = add_mute(codec, name, index,
 597                       HDA_COMPOSE_AMP_VAL(dac, 3, 0, HDA_OUTPUT), 0, &kctl);
 598        if (err < 0)
 599                return err;
 600        err = snd_ctl_add_slave(spec->vmaster_sw, kctl);
 601        if (err < 0)
 602                return err;
 603
 604        err = add_volume(codec, name, index,
 605                         HDA_COMPOSE_AMP_VAL(dac, 3, 0, HDA_OUTPUT), 0, &kctl);
 606        if (err < 0)
 607                return err;
 608        err = snd_ctl_add_slave(spec->vmaster_vol, kctl);
 609        if (err < 0)
 610                return err;
 611
 612        return 0;
 613}               
 614
 615static int build_output(struct hda_codec *codec)
 616{
 617        struct cs_spec *spec = codec->spec;
 618        struct auto_pin_cfg *cfg = &spec->autocfg;
 619        int i, err;
 620
 621        for (i = 0; i < cfg->line_outs; i++) {
 622                err = add_output(codec, get_dac(codec, cfg->line_out_pins[i]),
 623                                 i, cfg->line_outs, cfg->line_out_type);
 624                if (err < 0)
 625                        return err;
 626        }
 627        for (i = 0; i < cfg->hp_outs; i++) {
 628                err = add_output(codec, get_dac(codec, cfg->hp_pins[i]),
 629                                 i, cfg->hp_outs, AUTO_PIN_HP_OUT);
 630                if (err < 0)
 631                        return err;
 632        }
 633        for (i = 0; i < cfg->speaker_outs; i++) {
 634                err = add_output(codec, get_dac(codec, cfg->speaker_pins[i]),
 635                                 i, cfg->speaker_outs, AUTO_PIN_SPEAKER_OUT);
 636                if (err < 0)
 637                        return err;
 638        }
 639        return 0;
 640}
 641
 642/*
 643 */
 644
 645static struct snd_kcontrol_new cs_capture_ctls[] = {
 646        HDA_BIND_SW("Capture Switch", 0),
 647        HDA_BIND_VOL("Capture Volume", 0),
 648};
 649
 650static int change_cur_input(struct hda_codec *codec, unsigned int idx,
 651                            int force)
 652{
 653        struct cs_spec *spec = codec->spec;
 654        
 655        if (spec->cur_input == idx && !force)
 656                return 0;
 657        if (spec->cur_adc && spec->cur_adc != spec->adc_nid[idx]) {
 658                /* stream is running, let's swap the current ADC */
 659                __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1);
 660                spec->cur_adc = spec->adc_nid[idx];
 661                snd_hda_codec_setup_stream(codec, spec->cur_adc,
 662                                           spec->cur_adc_stream_tag, 0,
 663                                           spec->cur_adc_format);
 664        }
 665        snd_hda_codec_write(codec, spec->cur_adc, 0,
 666                            AC_VERB_SET_CONNECT_SEL,
 667                            spec->adc_idx[idx]);
 668        spec->cur_input = idx;
 669        return 1;
 670}
 671
 672static int cs_capture_source_info(struct snd_kcontrol *kcontrol,
 673                                  struct snd_ctl_elem_info *uinfo)
 674{
 675        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 676        struct cs_spec *spec = codec->spec;
 677        struct auto_pin_cfg *cfg = &spec->autocfg;
 678        unsigned int idx;
 679
 680        uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
 681        uinfo->count = 1;
 682        uinfo->value.enumerated.items = spec->num_inputs;
 683        if (uinfo->value.enumerated.item >= spec->num_inputs)
 684                uinfo->value.enumerated.item = spec->num_inputs - 1;
 685        idx = spec->input_idx[uinfo->value.enumerated.item];
 686        strcpy(uinfo->value.enumerated.name,
 687               hda_get_input_pin_label(codec, cfg->inputs[idx].pin, 1));
 688        return 0;
 689}
 690
 691static int cs_capture_source_get(struct snd_kcontrol *kcontrol,
 692                                 struct snd_ctl_elem_value *ucontrol)
 693{
 694        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 695        struct cs_spec *spec = codec->spec;
 696        ucontrol->value.enumerated.item[0] = spec->capsrc_idx[spec->cur_input];
 697        return 0;
 698}
 699
 700static int cs_capture_source_put(struct snd_kcontrol *kcontrol,
 701                                 struct snd_ctl_elem_value *ucontrol)
 702{
 703        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
 704        struct cs_spec *spec = codec->spec;
 705        unsigned int idx = ucontrol->value.enumerated.item[0];
 706
 707        if (idx >= spec->num_inputs)
 708                return -EINVAL;
 709        idx = spec->input_idx[idx];
 710        return change_cur_input(codec, idx, 0);
 711}
 712
 713static struct snd_kcontrol_new cs_capture_source = {
 714        .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 715        .name = "Capture Source",
 716        .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
 717        .info = cs_capture_source_info,
 718        .get = cs_capture_source_get,
 719        .put = cs_capture_source_put,
 720};
 721
 722static struct hda_bind_ctls *make_bind_capture(struct hda_codec *codec,
 723                                               struct hda_ctl_ops *ops)
 724{
 725        struct cs_spec *spec = codec->spec;
 726        struct hda_bind_ctls *bind;
 727        int i, n;
 728
 729        bind = kzalloc(sizeof(*bind) + sizeof(long) * (spec->num_inputs + 1),
 730                       GFP_KERNEL);
 731        if (!bind)
 732                return NULL;
 733        bind->ops = ops;
 734        n = 0;
 735        for (i = 0; i < AUTO_PIN_LAST; i++) {
 736                if (!spec->adc_nid[i])
 737                        continue;
 738                bind->values[n++] =
 739                        HDA_COMPOSE_AMP_VAL(spec->adc_nid[i], 3,
 740                                            spec->adc_idx[i], HDA_INPUT);
 741        }
 742        return bind;
 743}
 744
 745/* add a (input-boost) volume control to the given input pin */
 746static int add_input_volume_control(struct hda_codec *codec,
 747                                    struct auto_pin_cfg *cfg,
 748                                    int item)
 749{
 750        hda_nid_t pin = cfg->inputs[item].pin;
 751        u32 caps;
 752        const char *label;
 753        struct snd_kcontrol *kctl;
 754                
 755        if (!(get_wcaps(codec, pin) & AC_WCAP_IN_AMP))
 756                return 0;
 757        caps = query_amp_caps(codec, pin, HDA_INPUT);
 758        caps = (caps & AC_AMPCAP_NUM_STEPS) >> AC_AMPCAP_NUM_STEPS_SHIFT;
 759        if (caps <= 1)
 760                return 0;
 761        label = hda_get_autocfg_input_label(codec, cfg, item);
 762        return add_volume(codec, label, 0,
 763                          HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_INPUT), 1, &kctl);
 764}
 765
 766static int build_input(struct hda_codec *codec)
 767{
 768        struct cs_spec *spec = codec->spec;
 769        int i, err;
 770
 771        if (!spec->num_inputs)
 772                return 0;
 773
 774        /* make bind-capture */
 775        spec->capture_bind[0] = make_bind_capture(codec, &snd_hda_bind_sw);
 776        spec->capture_bind[1] = make_bind_capture(codec, &snd_hda_bind_vol);
 777        for (i = 0; i < 2; i++) {
 778                struct snd_kcontrol *kctl;
 779                int n;
 780                if (!spec->capture_bind[i])
 781                        return -ENOMEM;
 782                kctl = snd_ctl_new1(&cs_capture_ctls[i], codec);
 783                if (!kctl)
 784                        return -ENOMEM;
 785                kctl->private_value = (long)spec->capture_bind[i];
 786                err = snd_hda_ctl_add(codec, 0, kctl);
 787                if (err < 0)
 788                        return err;
 789                for (n = 0; n < AUTO_PIN_LAST; n++) {
 790                        if (!spec->adc_nid[n])
 791                                continue;
 792                        err = snd_hda_add_nid(codec, kctl, 0, spec->adc_nid[n]);
 793                        if (err < 0)
 794                                return err;
 795                }
 796        }
 797        
 798        if (spec->num_inputs > 1 && !spec->mic_detect) {
 799                err = snd_hda_ctl_add(codec, 0,
 800                                      snd_ctl_new1(&cs_capture_source, codec));
 801                if (err < 0)
 802                        return err;
 803        }
 804
 805        for (i = 0; i < spec->num_inputs; i++) {
 806                err = add_input_volume_control(codec, &spec->autocfg, i);
 807                if (err < 0)
 808                        return err;
 809        }
 810
 811        return 0;
 812}
 813
 814/*
 815 */
 816
 817static int build_digital_output(struct hda_codec *codec)
 818{
 819        struct cs_spec *spec = codec->spec;
 820        int err;
 821
 822        if (!spec->multiout.dig_out_nid)
 823                return 0;
 824
 825        err = snd_hda_create_spdif_out_ctls(codec, spec->multiout.dig_out_nid);
 826        if (err < 0)
 827                return err;
 828        err = snd_hda_create_spdif_share_sw(codec, &spec->multiout);
 829        if (err < 0)
 830                return err;
 831        return 0;
 832}
 833
 834static int build_digital_input(struct hda_codec *codec)
 835{
 836        struct cs_spec *spec = codec->spec;
 837        if (spec->dig_in)
 838                return snd_hda_create_spdif_in_ctls(codec, spec->dig_in);
 839        return 0;
 840}
 841
 842/*
 843 * auto-mute and auto-mic switching
 844 */
 845
 846static void cs_automute(struct hda_codec *codec)
 847{
 848        struct cs_spec *spec = codec->spec;
 849        struct auto_pin_cfg *cfg = &spec->autocfg;
 850        unsigned int caps, hp_present;
 851        hda_nid_t nid;
 852        int i;
 853
 854        hp_present = 0;
 855        for (i = 0; i < cfg->hp_outs; i++) {
 856                nid = cfg->hp_pins[i];
 857                caps = snd_hda_query_pin_caps(codec, nid);
 858                if (!(caps & AC_PINCAP_PRES_DETECT))
 859                        continue;
 860                hp_present = snd_hda_jack_detect(codec, nid);
 861                if (hp_present)
 862                        break;
 863        }
 864        for (i = 0; i < cfg->speaker_outs; i++) {
 865                nid = cfg->speaker_pins[i];
 866                snd_hda_codec_write(codec, nid, 0,
 867                                    AC_VERB_SET_PIN_WIDGET_CONTROL,
 868                                    hp_present ? 0 : PIN_OUT);
 869        }
 870        if (spec->board_config == CS420X_MBP53 ||
 871            spec->board_config == CS420X_MBP55 ||
 872            spec->board_config == CS420X_IMAC27) {
 873                unsigned int gpio = hp_present ? 0x02 : 0x08;
 874                snd_hda_codec_write(codec, 0x01, 0,
 875                                    AC_VERB_SET_GPIO_DATA, gpio);
 876        }
 877}
 878
 879static void cs_automic(struct hda_codec *codec)
 880{
 881        struct cs_spec *spec = codec->spec;
 882        struct auto_pin_cfg *cfg = &spec->autocfg;
 883        hda_nid_t nid;
 884        unsigned int present;
 885        
 886        nid = cfg->inputs[spec->automic_idx].pin;
 887        present = snd_hda_jack_detect(codec, nid);
 888        if (present)
 889                change_cur_input(codec, spec->automic_idx, 0);
 890        else
 891                change_cur_input(codec, !spec->automic_idx, 0);
 892}
 893
 894/*
 895 */
 896
 897static void init_output(struct hda_codec *codec)
 898{
 899        struct cs_spec *spec = codec->spec;
 900        struct auto_pin_cfg *cfg = &spec->autocfg;
 901        int i;
 902
 903        /* mute first */
 904        for (i = 0; i < spec->multiout.num_dacs; i++)
 905                snd_hda_codec_write(codec, spec->multiout.dac_nids[i], 0,
 906                                    AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
 907        if (spec->multiout.hp_nid)
 908                snd_hda_codec_write(codec, spec->multiout.hp_nid, 0,
 909                                    AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
 910        for (i = 0; i < ARRAY_SIZE(spec->multiout.extra_out_nid); i++) {
 911                if (!spec->multiout.extra_out_nid[i])
 912                        break;
 913                snd_hda_codec_write(codec, spec->multiout.extra_out_nid[i], 0,
 914                                    AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
 915        }
 916
 917        /* set appropriate pin controls */
 918        for (i = 0; i < cfg->line_outs; i++)
 919                snd_hda_codec_write(codec, cfg->line_out_pins[i], 0,
 920                                    AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
 921        for (i = 0; i < cfg->hp_outs; i++) {
 922                hda_nid_t nid = cfg->hp_pins[i];
 923                snd_hda_codec_write(codec, nid, 0,
 924                                    AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP);
 925                if (!cfg->speaker_outs)
 926                        continue;
 927                if (get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP) {
 928                        snd_hda_codec_write(codec, nid, 0,
 929                                            AC_VERB_SET_UNSOLICITED_ENABLE,
 930                                            AC_USRSP_EN | HP_EVENT);
 931                        spec->hp_detect = 1;
 932                }
 933        }
 934        for (i = 0; i < cfg->speaker_outs; i++)
 935                snd_hda_codec_write(codec, cfg->speaker_pins[i], 0,
 936                                    AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
 937        if (spec->hp_detect)
 938                cs_automute(codec);
 939}
 940
 941static void init_input(struct hda_codec *codec)
 942{
 943        struct cs_spec *spec = codec->spec;
 944        struct auto_pin_cfg *cfg = &spec->autocfg;
 945        unsigned int coef;
 946        int i;
 947
 948        for (i = 0; i < cfg->num_inputs; i++) {
 949                unsigned int ctl;
 950                hda_nid_t pin = cfg->inputs[i].pin;
 951                if (!spec->adc_nid[i])
 952                        continue;
 953                /* set appropriate pin control and mute first */
 954                ctl = PIN_IN;
 955                if (cfg->inputs[i].type == AUTO_PIN_MIC) {
 956                        unsigned int caps = snd_hda_query_pin_caps(codec, pin);
 957                        caps >>= AC_PINCAP_VREF_SHIFT;
 958                        if (caps & AC_PINCAP_VREF_80)
 959                                ctl = PIN_VREF80;
 960                }
 961                snd_hda_codec_write(codec, pin, 0,
 962                                    AC_VERB_SET_PIN_WIDGET_CONTROL, ctl);
 963                snd_hda_codec_write(codec, spec->adc_nid[i], 0,
 964                                    AC_VERB_SET_AMP_GAIN_MUTE,
 965                                    AMP_IN_MUTE(spec->adc_idx[i]));
 966                if (spec->mic_detect && spec->automic_idx == i)
 967                        snd_hda_codec_write(codec, pin, 0,
 968                                            AC_VERB_SET_UNSOLICITED_ENABLE,
 969                                            AC_USRSP_EN | MIC_EVENT);
 970        }
 971        change_cur_input(codec, spec->cur_input, 1);
 972        if (spec->mic_detect)
 973                cs_automic(codec);
 974
 975        coef = 0x000a; /* ADC1/2 - Digital and Analog Soft Ramp */
 976        if (is_active_pin(codec, CS_DMIC2_PIN_NID))
 977                coef |= 0x0500; /* DMIC2 enable 2 channels, disable GPIO1 */
 978        if (is_active_pin(codec, CS_DMIC1_PIN_NID))
 979                coef |= 0x1800; /* DMIC1 enable 2 channels, disable GPIO0 
 980                                 * No effect if SPDIF_OUT2 is selected in 
 981                                 * IDX_SPDIF_CTL.
 982                                  */
 983        cs_vendor_coef_set(codec, IDX_ADC_CFG, coef);
 984}
 985
 986static struct hda_verb cs_coef_init_verbs[] = {
 987        {0x11, AC_VERB_SET_PROC_STATE, 1},
 988        {0x11, AC_VERB_SET_COEF_INDEX, IDX_DAC_CFG},
 989        {0x11, AC_VERB_SET_PROC_COEF,
 990         (0x002a /* DAC1/2/3 SZCMode Soft Ramp */
 991          | 0x0040 /* Mute DACs on FIFO error */
 992          | 0x1000 /* Enable DACs High Pass Filter */
 993          | 0x0400 /* Disable Coefficient Auto increment */
 994          )},
 995        /* Beep */
 996        {0x11, AC_VERB_SET_COEF_INDEX, IDX_DAC_CFG},
 997        {0x11, AC_VERB_SET_PROC_COEF, 0x0007}, /* Enable Beep thru DAC1/2/3 */
 998
 999        {} /* terminator */
1000};
1001
1002/* Errata: CS4207 rev C0/C1/C2 Silicon
1003 *
1004 * http://www.cirrus.com/en/pubs/errata/ER880C3.pdf
1005 *
1006 * 6. At high temperature (TA > +85\xC2\xB0C), the digital supply current (IVD)
1007 * may be excessive (up to an additional 200 \xCE\xBCA), which is most easily
1008 * observed while the part is being held in reset (RESET# active low).
1009 *
1010 * Root Cause: At initial powerup of the device, the logic that drives
1011 * the clock and write enable to the S/PDIF SRC RAMs is not properly
1012 * initialized.
1013 * Certain random patterns will cause a steady leakage current in those
1014 * RAM cells. The issue will resolve once the SRCs are used (turned on).
1015 *
1016 * Workaround: The following verb sequence briefly turns on the S/PDIF SRC
1017 * blocks, which will alleviate the issue.
1018 */
1019
1020static struct hda_verb cs_errata_init_verbs[] = {
1021        {0x01, AC_VERB_SET_POWER_STATE, 0x00}, /* AFG: D0 */
1022        {0x11, AC_VERB_SET_PROC_STATE, 0x01},  /* VPW: processing on */
1023
1024        {0x11, AC_VERB_SET_COEF_INDEX, 0x0008},
1025        {0x11, AC_VERB_SET_PROC_COEF, 0x9999},
1026        {0x11, AC_VERB_SET_COEF_INDEX, 0x0017},
1027        {0x11, AC_VERB_SET_PROC_COEF, 0xa412},
1028        {0x11, AC_VERB_SET_COEF_INDEX, 0x0001},
1029        {0x11, AC_VERB_SET_PROC_COEF, 0x0009},
1030
1031        {0x07, AC_VERB_SET_POWER_STATE, 0x00}, /* S/PDIF Rx: D0 */
1032        {0x08, AC_VERB_SET_POWER_STATE, 0x00}, /* S/PDIF Tx: D0 */
1033
1034        {0x11, AC_VERB_SET_COEF_INDEX, 0x0017},
1035        {0x11, AC_VERB_SET_PROC_COEF, 0x2412},
1036        {0x11, AC_VERB_SET_COEF_INDEX, 0x0008},
1037        {0x11, AC_VERB_SET_PROC_COEF, 0x0000},
1038        {0x11, AC_VERB_SET_COEF_INDEX, 0x0001},
1039        {0x11, AC_VERB_SET_PROC_COEF, 0x0008},
1040        {0x11, AC_VERB_SET_PROC_STATE, 0x00},
1041
1042#if 0 /* Don't to set to D3 as we are in power-up sequence */
1043        {0x07, AC_VERB_SET_POWER_STATE, 0x03}, /* S/PDIF Rx: D3 */
1044        {0x08, AC_VERB_SET_POWER_STATE, 0x03}, /* S/PDIF Tx: D3 */
1045        /*{0x01, AC_VERB_SET_POWER_STATE, 0x03},*/ /* AFG: D3 This is already handled */
1046#endif
1047
1048        {} /* terminator */
1049};
1050
1051/* SPDIF setup */
1052static void init_digital(struct hda_codec *codec)
1053{
1054        unsigned int coef;
1055
1056        coef = 0x0002; /* SRC_MUTE soft-mute on SPDIF (if no lock) */
1057        coef |= 0x0008; /* Replace with mute on error */
1058        if (is_active_pin(codec, CS_DIG_OUT2_PIN_NID))
1059                coef |= 0x4000; /* RX to TX1 or TX2 Loopthru / SPDIF2
1060                                 * SPDIF_OUT2 is shared with GPIO1 and
1061                                 * DMIC_SDA2.
1062                                 */
1063        cs_vendor_coef_set(codec, IDX_SPDIF_CTL, coef);
1064}
1065
1066static int cs_init(struct hda_codec *codec)
1067{
1068        struct cs_spec *spec = codec->spec;
1069
1070        /* init_verb sequence for C0/C1/C2 errata*/
1071        snd_hda_sequence_write(codec, cs_errata_init_verbs);
1072
1073        snd_hda_sequence_write(codec, cs_coef_init_verbs);
1074
1075        if (spec->gpio_mask) {
1076                snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_MASK,
1077                                    spec->gpio_mask);
1078                snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DIRECTION,
1079                                    spec->gpio_dir);
1080                snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA,
1081                                    spec->gpio_data);
1082        }
1083
1084        init_output(codec);
1085        init_input(codec);
1086        init_digital(codec);
1087        return 0;
1088}
1089
1090static int cs_build_controls(struct hda_codec *codec)
1091{
1092        int err;
1093
1094        err = build_output(codec);
1095        if (err < 0)
1096                return err;
1097        err = build_input(codec);
1098        if (err < 0)
1099                return err;
1100        err = build_digital_output(codec);
1101        if (err < 0)
1102                return err;
1103        err = build_digital_input(codec);
1104        if (err < 0)
1105                return err;
1106        return cs_init(codec);
1107}
1108
1109static void cs_free(struct hda_codec *codec)
1110{
1111        struct cs_spec *spec = codec->spec;
1112        kfree(spec->capture_bind[0]);
1113        kfree(spec->capture_bind[1]);
1114        kfree(codec->spec);
1115}
1116
1117static void cs_unsol_event(struct hda_codec *codec, unsigned int res)
1118{
1119        switch ((res >> 26) & 0x7f) {
1120        case HP_EVENT:
1121                cs_automute(codec);
1122                break;
1123        case MIC_EVENT:
1124                cs_automic(codec);
1125                break;
1126        }
1127}
1128
1129static struct hda_codec_ops cs_patch_ops = {
1130        .build_controls = cs_build_controls,
1131        .build_pcms = cs_build_pcms,
1132        .init = cs_init,
1133        .free = cs_free,
1134        .unsol_event = cs_unsol_event,
1135};
1136
1137static int cs_parse_auto_config(struct hda_codec *codec)
1138{
1139        struct cs_spec *spec = codec->spec;
1140        int err;
1141
1142        err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
1143        if (err < 0)
1144                return err;
1145
1146        err = parse_output(codec);
1147        if (err < 0)
1148                return err;
1149        err = parse_input(codec);
1150        if (err < 0)
1151                return err;
1152        err = parse_digital_output(codec);
1153        if (err < 0)
1154                return err;
1155        err = parse_digital_input(codec);
1156        if (err < 0)
1157                return err;
1158        return 0;
1159}
1160
1161static const char * const cs420x_models[CS420X_MODELS] = {
1162        [CS420X_MBP53] = "mbp53",
1163        [CS420X_MBP55] = "mbp55",
1164        [CS420X_IMAC27] = "imac27",
1165        [CS420X_AUTO] = "auto",
1166};
1167
1168
1169static struct snd_pci_quirk cs420x_cfg_tbl[] = {
1170        SND_PCI_QUIRK(0x10de, 0x0ac0, "MacBookPro 5,3", CS420X_MBP53),
1171        SND_PCI_QUIRK(0x10de, 0x0d94, "MacBookAir 3,1(2)", CS420X_MBP55),
1172        SND_PCI_QUIRK(0x10de, 0xcb79, "MacBookPro 5,5", CS420X_MBP55),
1173        SND_PCI_QUIRK(0x10de, 0xcb89, "MacBookPro 7,1", CS420X_MBP55),
1174        SND_PCI_QUIRK(0x8086, 0x7270, "IMac 27 Inch", CS420X_IMAC27),
1175        {} /* terminator */
1176};
1177
1178struct cs_pincfg {
1179        hda_nid_t nid;
1180        u32 val;
1181};
1182
1183static struct cs_pincfg mbp53_pincfgs[] = {
1184        { 0x09, 0x012b4050 },
1185        { 0x0a, 0x90100141 },
1186        { 0x0b, 0x90100140 },
1187        { 0x0c, 0x018b3020 },
1188        { 0x0d, 0x90a00110 },
1189        { 0x0e, 0x400000f0 },
1190        { 0x0f, 0x01cbe030 },
1191        { 0x10, 0x014be060 },
1192        { 0x12, 0x400000f0 },
1193        { 0x15, 0x400000f0 },
1194        {} /* terminator */
1195};
1196
1197static struct cs_pincfg mbp55_pincfgs[] = {
1198        { 0x09, 0x012b4030 },
1199        { 0x0a, 0x90100121 },
1200        { 0x0b, 0x90100120 },
1201        { 0x0c, 0x400000f0 },
1202        { 0x0d, 0x90a00110 },
1203        { 0x0e, 0x400000f0 },
1204        { 0x0f, 0x400000f0 },
1205        { 0x10, 0x014be040 },
1206        { 0x12, 0x400000f0 },
1207        { 0x15, 0x400000f0 },
1208        {} /* terminator */
1209};
1210
1211static struct cs_pincfg imac27_pincfgs[] = {
1212        { 0x09, 0x012b4050 },
1213        { 0x0a, 0x90100140 },
1214        { 0x0b, 0x90100142 },
1215        { 0x0c, 0x018b3020 },
1216        { 0x0d, 0x90a00110 },
1217        { 0x0e, 0x400000f0 },
1218        { 0x0f, 0x01cbe030 },
1219        { 0x10, 0x014be060 },
1220        { 0x12, 0x01ab9070 },
1221        { 0x15, 0x400000f0 },
1222        {} /* terminator */
1223};
1224
1225static struct cs_pincfg *cs_pincfgs[CS420X_MODELS] = {
1226        [CS420X_MBP53] = mbp53_pincfgs,
1227        [CS420X_MBP55] = mbp55_pincfgs,
1228        [CS420X_IMAC27] = imac27_pincfgs,
1229};
1230
1231static void fix_pincfg(struct hda_codec *codec, int model)
1232{
1233        const struct cs_pincfg *cfg = cs_pincfgs[model];
1234        if (!cfg)
1235                return;
1236        for (; cfg->nid; cfg++)
1237                snd_hda_codec_set_pincfg(codec, cfg->nid, cfg->val);
1238}
1239
1240
1241static int patch_cs420x(struct hda_codec *codec)
1242{
1243        struct cs_spec *spec;
1244        int err;
1245
1246        spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1247        if (!spec)
1248                return -ENOMEM;
1249        codec->spec = spec;
1250
1251        spec->board_config =
1252                snd_hda_check_board_config(codec, CS420X_MODELS,
1253                                           cs420x_models, cs420x_cfg_tbl);
1254        if (spec->board_config >= 0)
1255                fix_pincfg(codec, spec->board_config);
1256
1257        switch (spec->board_config) {
1258        case CS420X_IMAC27:
1259        case CS420X_MBP53:
1260        case CS420X_MBP55:
1261                /* GPIO1 = headphones */
1262                /* GPIO3 = speakers */
1263                spec->gpio_mask = 0x0a;
1264                spec->gpio_dir = 0x0a;
1265                break;
1266        }
1267
1268        err = cs_parse_auto_config(codec);
1269        if (err < 0)
1270                goto error;
1271
1272        codec->patch_ops = cs_patch_ops;
1273
1274        return 0;
1275
1276 error:
1277        kfree(codec->spec);
1278        codec->spec = NULL;
1279        return err;
1280}
1281
1282
1283/*
1284 * patch entries
1285 */
1286static struct hda_codec_preset snd_hda_preset_cirrus[] = {
1287        { .id = 0x10134206, .name = "CS4206", .patch = patch_cs420x },
1288        { .id = 0x10134207, .name = "CS4207", .patch = patch_cs420x },
1289        {} /* terminator */
1290};
1291
1292MODULE_ALIAS("snd-hda-codec-id:10134206");
1293MODULE_ALIAS("snd-hda-codec-id:10134207");
1294
1295MODULE_LICENSE("GPL");
1296MODULE_DESCRIPTION("Cirrus Logic HD-audio codec");
1297
1298static struct hda_codec_preset_list cirrus_list = {
1299        .preset = snd_hda_preset_cirrus,
1300        .owner = THIS_MODULE,
1301};
1302
1303static int __init patch_cirrus_init(void)
1304{
1305        return snd_hda_add_codec_preset(&cirrus_list);
1306}
1307
1308static void __exit patch_cirrus_exit(void)
1309{
1310        snd_hda_delete_codec_preset(&cirrus_list);
1311}
1312
1313module_init(patch_cirrus_init)
1314module_exit(patch_cirrus_exit)
1315