linux/sound/soc/codecs/wm8737.c
<<
>>
Prefs
   1/*
   2 * wm8737.c  --  WM8737 ALSA SoC Audio driver
   3 *
   4 * Copyright 2010 Wolfson Microelectronics plc
   5 *
   6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
   7 *
   8 * This program is free software; you can redistribute it and/or modify
   9 * it under the terms of the GNU General Public License version 2 as
  10 * published by the Free Software Foundation.
  11 */
  12
  13#include <linux/module.h>
  14#include <linux/moduleparam.h>
  15#include <linux/init.h>
  16#include <linux/delay.h>
  17#include <linux/pm.h>
  18#include <linux/i2c.h>
  19#include <linux/platform_device.h>
  20#include <linux/regulator/consumer.h>
  21#include <linux/spi/spi.h>
  22#include <linux/slab.h>
  23#include <sound/core.h>
  24#include <sound/pcm.h>
  25#include <sound/pcm_params.h>
  26#include <sound/soc.h>
  27#include <sound/soc-dapm.h>
  28#include <sound/initval.h>
  29#include <sound/tlv.h>
  30
  31#include "wm8737.h"
  32
  33#define WM8737_NUM_SUPPLIES 4
  34static const char *wm8737_supply_names[WM8737_NUM_SUPPLIES] = {
  35        "DCVDD",
  36        "DBVDD",
  37        "AVDD",
  38        "MVDD",
  39};
  40
  41/* codec private data */
  42struct wm8737_priv {
  43        enum snd_soc_control_type control_type;
  44        struct regulator_bulk_data supplies[WM8737_NUM_SUPPLIES];
  45        unsigned int mclk;
  46};
  47
  48static const u16 wm8737_reg[WM8737_REGISTER_COUNT] = {
  49        0x00C3,     /* R0  - Left PGA volume */
  50        0x00C3,     /* R1  - Right PGA volume */
  51        0x0007,     /* R2  - AUDIO path L */
  52        0x0007,     /* R3  - AUDIO path R */
  53        0x0000,     /* R4  - 3D Enhance */
  54        0x0000,     /* R5  - ADC Control */
  55        0x0000,     /* R6  - Power Management */
  56        0x000A,     /* R7  - Audio Format */
  57        0x0000,     /* R8  - Clocking */
  58        0x000F,     /* R9  - MIC Preamp Control */
  59        0x0003,     /* R10 - Misc Bias Control */
  60        0x0000,     /* R11 - Noise Gate */
  61        0x007C,     /* R12 - ALC1 */
  62        0x0000,     /* R13 - ALC2 */
  63        0x0032,     /* R14 - ALC3 */
  64};
  65
  66static int wm8737_reset(struct snd_soc_codec *codec)
  67{
  68        return snd_soc_write(codec, WM8737_RESET, 0);
  69}
  70
  71static const unsigned int micboost_tlv[] = {
  72        TLV_DB_RANGE_HEAD(4),
  73        0, 0, TLV_DB_SCALE_ITEM(1300, 0, 0),
  74        1, 1, TLV_DB_SCALE_ITEM(1800, 0, 0),
  75        2, 2, TLV_DB_SCALE_ITEM(2800, 0, 0),
  76        3, 3, TLV_DB_SCALE_ITEM(3300, 0, 0),
  77};
  78static const DECLARE_TLV_DB_SCALE(pga_tlv, -9750, 50, 1);
  79static const DECLARE_TLV_DB_SCALE(adc_tlv, -600, 600, 0);
  80static const DECLARE_TLV_DB_SCALE(ng_tlv, -7800, 600, 0);
  81static const DECLARE_TLV_DB_SCALE(alc_max_tlv, -1200, 600, 0);
  82static const DECLARE_TLV_DB_SCALE(alc_target_tlv, -1800, 100, 0);
  83
  84static const char *micbias_enum_text[] = {
  85        "25%",
  86        "50%",
  87        "75%",
  88        "100%",
  89};
  90
  91static const struct soc_enum micbias_enum =
  92        SOC_ENUM_SINGLE(WM8737_MIC_PREAMP_CONTROL, 0, 4, micbias_enum_text);
  93
  94static const char *low_cutoff_text[] = {
  95        "Low", "High"
  96};
  97
  98static const struct soc_enum low_3d =
  99        SOC_ENUM_SINGLE(WM8737_3D_ENHANCE, 6, 2, low_cutoff_text);
 100
 101static const char *high_cutoff_text[] = {
 102        "High", "Low"
 103};
 104
 105static const struct soc_enum high_3d =
 106        SOC_ENUM_SINGLE(WM8737_3D_ENHANCE, 5, 2, high_cutoff_text);
 107
 108static const char *alc_fn_text[] = {
 109        "Disabled", "Right", "Left", "Stereo"
 110};
 111
 112static const struct soc_enum alc_fn =
 113        SOC_ENUM_SINGLE(WM8737_ALC1, 7, 4, alc_fn_text);
 114
 115static const char *alc_hold_text[] = {
 116        "0", "2.67ms", "5.33ms", "10.66ms", "21.32ms", "42.64ms", "85.28ms",
 117        "170.56ms", "341.12ms", "682.24ms", "1.364s", "2.728s", "5.458s",
 118        "10.916s", "21.832s", "43.691s"
 119};
 120
 121static const struct soc_enum alc_hold =
 122        SOC_ENUM_SINGLE(WM8737_ALC2, 0, 16, alc_hold_text);
 123
 124static const char *alc_atk_text[] = {
 125        "8.4ms", "16.8ms", "33.6ms", "67.2ms", "134.4ms", "268.8ms", "537.6ms",
 126        "1.075s", "2.15s", "4.3s", "8.6s"
 127};
 128
 129static const struct soc_enum alc_atk =
 130        SOC_ENUM_SINGLE(WM8737_ALC3, 0, 11, alc_atk_text);
 131
 132static const char *alc_dcy_text[] = {
 133        "33.6ms", "67.2ms", "134.4ms", "268.8ms", "537.6ms", "1.075s", "2.15s",
 134        "4.3s", "8.6s", "17.2s", "34.41s"
 135};
 136
 137static const struct soc_enum alc_dcy =
 138        SOC_ENUM_SINGLE(WM8737_ALC3, 4, 11, alc_dcy_text);
 139
 140static const struct snd_kcontrol_new wm8737_snd_controls[] = {
 141SOC_DOUBLE_R_TLV("Mic Boost Volume", WM8737_AUDIO_PATH_L, WM8737_AUDIO_PATH_R,
 142                 6, 3, 0, micboost_tlv),
 143SOC_DOUBLE_R("Mic Boost Switch", WM8737_AUDIO_PATH_L, WM8737_AUDIO_PATH_R,
 144             4, 1, 0),
 145SOC_DOUBLE("Mic ZC Switch", WM8737_AUDIO_PATH_L, WM8737_AUDIO_PATH_R,
 146           3, 1, 0),
 147
 148SOC_DOUBLE_R_TLV("Capture Volume", WM8737_LEFT_PGA_VOLUME,
 149                 WM8737_RIGHT_PGA_VOLUME, 0, 255, 0, pga_tlv),
 150SOC_DOUBLE("Capture ZC Switch", WM8737_AUDIO_PATH_L, WM8737_AUDIO_PATH_R,
 151           2, 1, 0),
 152
 153SOC_DOUBLE("INPUT1 DC Bias Switch", WM8737_MISC_BIAS_CONTROL, 0, 1, 1, 0),
 154
 155SOC_ENUM("Mic PGA Bias", micbias_enum),
 156SOC_SINGLE("ADC Low Power Switch", WM8737_ADC_CONTROL, 2, 1, 0),
 157SOC_SINGLE("High Pass Filter Switch", WM8737_ADC_CONTROL, 0, 1, 1),
 158SOC_DOUBLE("Polarity Invert Switch", WM8737_ADC_CONTROL, 5, 6, 1, 0),
 159
 160SOC_SINGLE("3D Switch", WM8737_3D_ENHANCE, 0, 1, 0),
 161SOC_SINGLE("3D Depth", WM8737_3D_ENHANCE, 1, 15, 0),
 162SOC_ENUM("3D Low Cut-off", low_3d),
 163SOC_ENUM("3D High Cut-off", low_3d),
 164SOC_SINGLE_TLV("3D ADC Volume", WM8737_3D_ENHANCE, 7, 1, 1, adc_tlv),
 165
 166SOC_SINGLE("Noise Gate Switch", WM8737_NOISE_GATE, 0, 1, 0),
 167SOC_SINGLE_TLV("Noise Gate Threshold Volume", WM8737_NOISE_GATE, 2, 7, 0,
 168               ng_tlv),
 169
 170SOC_ENUM("ALC", alc_fn),
 171SOC_SINGLE_TLV("ALC Max Gain Volume", WM8737_ALC1, 4, 7, 0, alc_max_tlv),
 172SOC_SINGLE_TLV("ALC Target Volume", WM8737_ALC1, 0, 15, 0, alc_target_tlv),
 173SOC_ENUM("ALC Hold Time", alc_hold),
 174SOC_SINGLE("ALC ZC Switch", WM8737_ALC2, 4, 1, 0),
 175SOC_ENUM("ALC Attack Time", alc_atk),
 176SOC_ENUM("ALC Decay Time", alc_dcy),
 177};
 178
 179static const char *linsel_text[] = {
 180        "LINPUT1", "LINPUT2", "LINPUT3", "LINPUT1 DC",
 181};
 182
 183static const struct soc_enum linsel_enum =
 184        SOC_ENUM_SINGLE(WM8737_AUDIO_PATH_L, 7, 4, linsel_text);
 185
 186static const struct snd_kcontrol_new linsel_mux =
 187        SOC_DAPM_ENUM("LINSEL", linsel_enum);
 188
 189
 190static const char *rinsel_text[] = {
 191        "RINPUT1", "RINPUT2", "RINPUT3", "RINPUT1 DC",
 192};
 193
 194static const struct soc_enum rinsel_enum =
 195        SOC_ENUM_SINGLE(WM8737_AUDIO_PATH_R, 7, 4, rinsel_text);
 196
 197static const struct snd_kcontrol_new rinsel_mux =
 198        SOC_DAPM_ENUM("RINSEL", rinsel_enum);
 199
 200static const char *bypass_text[] = {
 201        "Direct", "Preamp"
 202};
 203
 204static const struct soc_enum lbypass_enum =
 205        SOC_ENUM_SINGLE(WM8737_MIC_PREAMP_CONTROL, 2, 2, bypass_text);
 206
 207static const struct snd_kcontrol_new lbypass_mux =
 208        SOC_DAPM_ENUM("Left Bypass", lbypass_enum);
 209
 210
 211static const struct soc_enum rbypass_enum =
 212        SOC_ENUM_SINGLE(WM8737_MIC_PREAMP_CONTROL, 3, 2, bypass_text);
 213
 214static const struct snd_kcontrol_new rbypass_mux =
 215        SOC_DAPM_ENUM("Left Bypass", rbypass_enum);
 216
 217static const struct snd_soc_dapm_widget wm8737_dapm_widgets[] = {
 218SND_SOC_DAPM_INPUT("LINPUT1"),
 219SND_SOC_DAPM_INPUT("LINPUT2"),
 220SND_SOC_DAPM_INPUT("LINPUT3"),
 221SND_SOC_DAPM_INPUT("RINPUT1"),
 222SND_SOC_DAPM_INPUT("RINPUT2"),
 223SND_SOC_DAPM_INPUT("RINPUT3"),
 224SND_SOC_DAPM_INPUT("LACIN"),
 225SND_SOC_DAPM_INPUT("RACIN"),
 226
 227SND_SOC_DAPM_MUX("LINSEL", SND_SOC_NOPM, 0, 0, &linsel_mux),
 228SND_SOC_DAPM_MUX("RINSEL", SND_SOC_NOPM, 0, 0, &rinsel_mux),
 229
 230SND_SOC_DAPM_MUX("Left Preamp Mux", SND_SOC_NOPM, 0, 0, &lbypass_mux),
 231SND_SOC_DAPM_MUX("Right Preamp Mux", SND_SOC_NOPM, 0, 0, &rbypass_mux),
 232
 233SND_SOC_DAPM_PGA("PGAL", WM8737_POWER_MANAGEMENT, 5, 0, NULL, 0),
 234SND_SOC_DAPM_PGA("PGAR", WM8737_POWER_MANAGEMENT, 4, 0, NULL, 0),
 235
 236SND_SOC_DAPM_DAC("ADCL", NULL, WM8737_POWER_MANAGEMENT, 3, 0),
 237SND_SOC_DAPM_DAC("ADCR", NULL, WM8737_POWER_MANAGEMENT, 2, 0),
 238
 239SND_SOC_DAPM_AIF_OUT("AIF", "Capture", 0, WM8737_POWER_MANAGEMENT, 6, 0),
 240};
 241
 242static const struct snd_soc_dapm_route intercon[] = {
 243        { "LINSEL", "LINPUT1", "LINPUT1" },
 244        { "LINSEL", "LINPUT2", "LINPUT2" },
 245        { "LINSEL", "LINPUT3", "LINPUT3" },
 246        { "LINSEL", "LINPUT1 DC", "LINPUT1" },
 247
 248        { "RINSEL", "RINPUT1", "RINPUT1" },
 249        { "RINSEL", "RINPUT2", "RINPUT2" },
 250        { "RINSEL", "RINPUT3", "RINPUT3" },
 251        { "RINSEL", "RINPUT1 DC", "RINPUT1" },
 252
 253        { "Left Preamp Mux", "Preamp", "LINSEL" },
 254        { "Left Preamp Mux", "Direct", "LACIN" },
 255
 256        { "Right Preamp Mux", "Preamp", "RINSEL" },
 257        { "Right Preamp Mux", "Direct", "RACIN" },
 258
 259        { "PGAL", NULL, "Left Preamp Mux" },
 260        { "PGAR", NULL, "Right Preamp Mux" },
 261
 262        { "ADCL", NULL, "PGAL" },
 263        { "ADCR", NULL, "PGAR" },
 264
 265        { "AIF", NULL, "ADCL" },
 266        { "AIF", NULL, "ADCR" },
 267};
 268
 269static int wm8737_add_widgets(struct snd_soc_codec *codec)
 270{
 271        struct snd_soc_dapm_context *dapm = &codec->dapm;
 272
 273        snd_soc_dapm_new_controls(dapm, wm8737_dapm_widgets,
 274                                  ARRAY_SIZE(wm8737_dapm_widgets));
 275        snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon));
 276
 277        return 0;
 278}
 279
 280/* codec mclk clock divider coefficients */
 281static const struct {
 282        u32 mclk;
 283        u32 rate;
 284        u8 usb;
 285        u8 sr;
 286} coeff_div[] = {
 287        { 12288000,  8000, 0,  0x4 },
 288        { 12288000, 12000, 0,  0x8 },
 289        { 12288000, 16000, 0,  0xa },
 290        { 12288000, 24000, 0, 0x1c },
 291        { 12288000, 32000, 0,  0xc },
 292        { 12288000, 48000, 0,    0 },
 293        { 12288000, 96000, 0,  0xe },
 294
 295        { 11289600,  8000, 0, 0x14 },
 296        { 11289600, 11025, 0, 0x18 },
 297        { 11289600, 22050, 0, 0x1a },
 298        { 11289600, 44100, 0, 0x10 },
 299        { 11289600, 88200, 0, 0x1e },
 300
 301        { 18432000,  8000, 0,  0x5 },
 302        { 18432000, 12000, 0,  0x9 },
 303        { 18432000, 16000, 0,  0xb },
 304        { 18432000, 24000, 0, 0x1b },
 305        { 18432000, 32000, 0,  0xd },
 306        { 18432000, 48000, 0,  0x1 },
 307        { 18432000, 96000, 0, 0x1f },
 308
 309        { 16934400,  8000, 0, 0x15 },
 310        { 16934400, 11025, 0, 0x19 },
 311        { 16934400, 22050, 0, 0x1b },
 312        { 16934400, 44100, 0, 0x11 },
 313        { 16934400, 88200, 0, 0x1f },
 314
 315        { 12000000,  8000, 1,  0x4 },
 316        { 12000000, 11025, 1, 0x19 },
 317        { 12000000, 12000, 1,  0x8 },
 318        { 12000000, 16000, 1,  0xa },
 319        { 12000000, 22050, 1, 0x1b },
 320        { 12000000, 24000, 1, 0x1c },
 321        { 12000000, 32000, 1,  0xc },
 322        { 12000000, 44100, 1, 0x11 },
 323        { 12000000, 48000, 1,  0x0 },
 324        { 12000000, 88200, 1, 0x1f },
 325        { 12000000, 96000, 1,  0xe },
 326};
 327
 328static int wm8737_hw_params(struct snd_pcm_substream *substream,
 329                            struct snd_pcm_hw_params *params,
 330                            struct snd_soc_dai *dai)
 331{
 332        struct snd_soc_pcm_runtime *rtd = substream->private_data;
 333        struct snd_soc_codec *codec = rtd->codec;
 334        struct wm8737_priv *wm8737 = snd_soc_codec_get_drvdata(codec);
 335        int i;
 336        u16 clocking = 0;
 337        u16 af = 0;
 338
 339        for (i = 0; i < ARRAY_SIZE(coeff_div); i++) {
 340                if (coeff_div[i].rate != params_rate(params))
 341                        continue;
 342
 343                if (coeff_div[i].mclk == wm8737->mclk)
 344                        break;
 345
 346                if (coeff_div[i].mclk == wm8737->mclk * 2) {
 347                        clocking |= WM8737_CLKDIV2;
 348                        break;
 349                }
 350        }
 351
 352        if (i == ARRAY_SIZE(coeff_div)) {
 353                dev_err(codec->dev, "%dHz MCLK can't support %dHz\n",
 354                        wm8737->mclk, params_rate(params));
 355                return -EINVAL;
 356        }
 357
 358        clocking |= coeff_div[i].usb | (coeff_div[i].sr << WM8737_SR_SHIFT);
 359
 360        switch (params_format(params)) {
 361        case SNDRV_PCM_FORMAT_S16_LE:
 362                break;
 363        case SNDRV_PCM_FORMAT_S20_3LE:
 364                af |= 0x8;
 365                break;
 366        case SNDRV_PCM_FORMAT_S24_LE:
 367                af |= 0x10;
 368                break;
 369        case SNDRV_PCM_FORMAT_S32_LE:
 370                af |= 0x18;
 371                break;
 372        default:
 373                return -EINVAL;
 374        }
 375
 376        snd_soc_update_bits(codec, WM8737_AUDIO_FORMAT, WM8737_WL_MASK, af);
 377        snd_soc_update_bits(codec, WM8737_CLOCKING,
 378                            WM8737_USB_MODE | WM8737_CLKDIV2 | WM8737_SR_MASK,
 379                            clocking);
 380
 381        return 0;
 382}
 383
 384static int wm8737_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 385                                 int clk_id, unsigned int freq, int dir)
 386{
 387        struct snd_soc_codec *codec = codec_dai->codec;
 388        struct wm8737_priv *wm8737 = snd_soc_codec_get_drvdata(codec);
 389        int i;
 390
 391        for (i = 0; i < ARRAY_SIZE(coeff_div); i++) {
 392                if (freq == coeff_div[i].mclk ||
 393                    freq == coeff_div[i].mclk * 2) {
 394                        wm8737->mclk = freq;
 395                        return 0;
 396                }
 397        }
 398
 399        dev_err(codec->dev, "MCLK rate %dHz not supported\n", freq);
 400
 401        return -EINVAL;
 402}
 403
 404
 405static int wm8737_set_dai_fmt(struct snd_soc_dai *codec_dai,
 406                unsigned int fmt)
 407{
 408        struct snd_soc_codec *codec = codec_dai->codec;
 409        u16 af = 0;
 410
 411        switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
 412        case SND_SOC_DAIFMT_CBM_CFM:
 413                af |= WM8737_MS;
 414                break;
 415        case SND_SOC_DAIFMT_CBS_CFS:
 416                break;
 417        default:
 418                return -EINVAL;
 419        }
 420
 421        switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
 422        case SND_SOC_DAIFMT_I2S:
 423                af |= 0x2;
 424                break;
 425        case SND_SOC_DAIFMT_RIGHT_J:
 426                break;
 427        case SND_SOC_DAIFMT_LEFT_J:
 428                af |= 0x1;
 429                break;
 430        case SND_SOC_DAIFMT_DSP_A:
 431                af |= 0x3;
 432                break;
 433        case SND_SOC_DAIFMT_DSP_B:
 434                af |= 0x13;
 435                break;
 436        default:
 437                return -EINVAL;
 438        }
 439
 440        switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
 441        case SND_SOC_DAIFMT_NB_NF:
 442                break;
 443        case SND_SOC_DAIFMT_NB_IF:
 444                af |= WM8737_LRP;
 445                break;
 446        default:
 447                return -EINVAL;
 448        }
 449
 450        snd_soc_update_bits(codec, WM8737_AUDIO_FORMAT,
 451                            WM8737_FORMAT_MASK | WM8737_LRP | WM8737_MS, af);
 452
 453        return 0;
 454}
 455
 456static int wm8737_set_bias_level(struct snd_soc_codec *codec,
 457                                 enum snd_soc_bias_level level)
 458{
 459        struct wm8737_priv *wm8737 = snd_soc_codec_get_drvdata(codec);
 460        int ret;
 461
 462        switch (level) {
 463        case SND_SOC_BIAS_ON:
 464                break;
 465
 466        case SND_SOC_BIAS_PREPARE:
 467                /* VMID at 2*75k */
 468                snd_soc_update_bits(codec, WM8737_MISC_BIAS_CONTROL,
 469                                    WM8737_VMIDSEL_MASK, 0);
 470                break;
 471
 472        case SND_SOC_BIAS_STANDBY:
 473                if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
 474                        ret = regulator_bulk_enable(ARRAY_SIZE(wm8737->supplies),
 475                                                    wm8737->supplies);
 476                        if (ret != 0) {
 477                                dev_err(codec->dev,
 478                                        "Failed to enable supplies: %d\n",
 479                                        ret);
 480                                return ret;
 481                        }
 482
 483                        snd_soc_cache_sync(codec);
 484
 485                        /* Fast VMID ramp at 2*2.5k */
 486                        snd_soc_update_bits(codec, WM8737_MISC_BIAS_CONTROL,
 487                                            WM8737_VMIDSEL_MASK, 0x4);
 488
 489                        /* Bring VMID up */
 490                        snd_soc_update_bits(codec, WM8737_POWER_MANAGEMENT,
 491                                            WM8737_VMID_MASK |
 492                                            WM8737_VREF_MASK,
 493                                            WM8737_VMID_MASK |
 494                                            WM8737_VREF_MASK);
 495
 496                        msleep(500);
 497                }
 498
 499                /* VMID at 2*300k */
 500                snd_soc_update_bits(codec, WM8737_MISC_BIAS_CONTROL,
 501                                    WM8737_VMIDSEL_MASK, 2);
 502
 503                break;
 504
 505        case SND_SOC_BIAS_OFF:
 506                snd_soc_update_bits(codec, WM8737_POWER_MANAGEMENT,
 507                                    WM8737_VMID_MASK | WM8737_VREF_MASK, 0);
 508
 509                regulator_bulk_disable(ARRAY_SIZE(wm8737->supplies),
 510                                       wm8737->supplies);
 511                break;
 512        }
 513
 514        codec->dapm.bias_level = level;
 515        return 0;
 516}
 517
 518#define WM8737_RATES SNDRV_PCM_RATE_8000_96000
 519
 520#define WM8737_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
 521                        SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
 522
 523static struct snd_soc_dai_ops wm8737_dai_ops = {
 524        .hw_params      = wm8737_hw_params,
 525        .set_sysclk     = wm8737_set_dai_sysclk,
 526        .set_fmt        = wm8737_set_dai_fmt,
 527};
 528
 529static struct snd_soc_dai_driver wm8737_dai = {
 530        .name = "wm8737",
 531        .capture = {
 532                .stream_name = "Capture",
 533                .channels_min = 2,  /* Mono modes not yet supported */
 534                .channels_max = 2,
 535                .rates = WM8737_RATES,
 536                .formats = WM8737_FORMATS,
 537        },
 538        .ops = &wm8737_dai_ops,
 539};
 540
 541#ifdef CONFIG_PM
 542static int wm8737_suspend(struct snd_soc_codec *codec, pm_message_t state)
 543{
 544        wm8737_set_bias_level(codec, SND_SOC_BIAS_OFF);
 545        return 0;
 546}
 547
 548static int wm8737_resume(struct snd_soc_codec *codec)
 549{
 550        wm8737_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
 551        return 0;
 552}
 553#else
 554#define wm8737_suspend NULL
 555#define wm8737_resume NULL
 556#endif
 557
 558static int wm8737_probe(struct snd_soc_codec *codec)
 559{
 560        struct wm8737_priv *wm8737 = snd_soc_codec_get_drvdata(codec);
 561        int ret, i;
 562
 563        ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8737->control_type);
 564        if (ret != 0) {
 565                dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
 566                return ret;
 567        }
 568
 569        for (i = 0; i < ARRAY_SIZE(wm8737->supplies); i++)
 570                wm8737->supplies[i].supply = wm8737_supply_names[i];
 571
 572        ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8737->supplies),
 573                                 wm8737->supplies);
 574        if (ret != 0) {
 575                dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
 576                return ret;
 577        }
 578
 579        ret = regulator_bulk_enable(ARRAY_SIZE(wm8737->supplies),
 580                                    wm8737->supplies);
 581        if (ret != 0) {
 582                dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
 583                goto err_get;
 584        }
 585
 586        ret = wm8737_reset(codec);
 587        if (ret < 0) {
 588                dev_err(codec->dev, "Failed to issue reset\n");
 589                goto err_enable;
 590        }
 591
 592        snd_soc_update_bits(codec, WM8737_LEFT_PGA_VOLUME, WM8737_LVU,
 593                            WM8737_LVU);
 594        snd_soc_update_bits(codec, WM8737_RIGHT_PGA_VOLUME, WM8737_RVU,
 595                            WM8737_RVU);
 596
 597        wm8737_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
 598
 599        /* Bias level configuration will have done an extra enable */
 600        regulator_bulk_disable(ARRAY_SIZE(wm8737->supplies), wm8737->supplies);
 601
 602        snd_soc_add_controls(codec, wm8737_snd_controls,
 603                             ARRAY_SIZE(wm8737_snd_controls));
 604        wm8737_add_widgets(codec);
 605
 606        return 0;
 607
 608err_enable:
 609        regulator_bulk_disable(ARRAY_SIZE(wm8737->supplies), wm8737->supplies);
 610err_get:
 611        regulator_bulk_free(ARRAY_SIZE(wm8737->supplies), wm8737->supplies);
 612
 613        return ret;
 614}
 615
 616static int wm8737_remove(struct snd_soc_codec *codec)
 617{
 618        struct wm8737_priv *wm8737 = snd_soc_codec_get_drvdata(codec);
 619
 620        wm8737_set_bias_level(codec, SND_SOC_BIAS_OFF);
 621        regulator_bulk_free(ARRAY_SIZE(wm8737->supplies), wm8737->supplies);
 622        return 0;
 623}
 624
 625static struct snd_soc_codec_driver soc_codec_dev_wm8737 = {
 626        .probe          = wm8737_probe,
 627        .remove         = wm8737_remove,
 628        .suspend        = wm8737_suspend,
 629        .resume         = wm8737_resume,
 630        .set_bias_level = wm8737_set_bias_level,
 631
 632        .reg_cache_size = WM8737_REGISTER_COUNT - 1, /* Skip reset */
 633        .reg_word_size  = sizeof(u16),
 634        .reg_cache_default = wm8737_reg,
 635};
 636
 637#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
 638static __devinit int wm8737_i2c_probe(struct i2c_client *i2c,
 639                                      const struct i2c_device_id *id)
 640{
 641        struct wm8737_priv *wm8737;
 642        int ret;
 643
 644        wm8737 = kzalloc(sizeof(struct wm8737_priv), GFP_KERNEL);
 645        if (wm8737 == NULL)
 646                return -ENOMEM;
 647
 648        i2c_set_clientdata(i2c, wm8737);
 649        wm8737->control_type = SND_SOC_I2C;
 650
 651        ret =  snd_soc_register_codec(&i2c->dev,
 652                                      &soc_codec_dev_wm8737, &wm8737_dai, 1);
 653        if (ret < 0)
 654                kfree(wm8737);
 655        return ret;
 656
 657}
 658
 659static __devexit int wm8737_i2c_remove(struct i2c_client *client)
 660{
 661        snd_soc_unregister_codec(&client->dev);
 662        kfree(i2c_get_clientdata(client));
 663        return 0;
 664}
 665
 666static const struct i2c_device_id wm8737_i2c_id[] = {
 667        { "wm8737", 0 },
 668        { }
 669};
 670MODULE_DEVICE_TABLE(i2c, wm8737_i2c_id);
 671
 672static struct i2c_driver wm8737_i2c_driver = {
 673        .driver = {
 674                .name = "wm8737",
 675                .owner = THIS_MODULE,
 676        },
 677        .probe =    wm8737_i2c_probe,
 678        .remove =   __devexit_p(wm8737_i2c_remove),
 679        .id_table = wm8737_i2c_id,
 680};
 681#endif
 682
 683#if defined(CONFIG_SPI_MASTER)
 684static int __devinit wm8737_spi_probe(struct spi_device *spi)
 685{
 686        struct wm8737_priv *wm8737;
 687        int ret;
 688
 689        wm8737 = kzalloc(sizeof(struct wm8737_priv), GFP_KERNEL);
 690        if (wm8737 == NULL)
 691                return -ENOMEM;
 692
 693        wm8737->control_type = SND_SOC_SPI;
 694        spi_set_drvdata(spi, wm8737);
 695
 696        ret = snd_soc_register_codec(&spi->dev,
 697                                     &soc_codec_dev_wm8737, &wm8737_dai, 1);
 698        if (ret < 0)
 699                kfree(wm8737);
 700        return ret;
 701}
 702
 703static int __devexit wm8737_spi_remove(struct spi_device *spi)
 704{
 705        snd_soc_unregister_codec(&spi->dev);
 706        kfree(spi_get_drvdata(spi));
 707        return 0;
 708}
 709
 710static struct spi_driver wm8737_spi_driver = {
 711        .driver = {
 712                .name   = "wm8737",
 713                .owner  = THIS_MODULE,
 714        },
 715        .probe          = wm8737_spi_probe,
 716        .remove         = __devexit_p(wm8737_spi_remove),
 717};
 718#endif /* CONFIG_SPI_MASTER */
 719
 720static int __init wm8737_modinit(void)
 721{
 722        int ret;
 723#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
 724        ret = i2c_add_driver(&wm8737_i2c_driver);
 725        if (ret != 0) {
 726                printk(KERN_ERR "Failed to register WM8737 I2C driver: %d\n",
 727                       ret);
 728        }
 729#endif
 730#if defined(CONFIG_SPI_MASTER)
 731        ret = spi_register_driver(&wm8737_spi_driver);
 732        if (ret != 0) {
 733                printk(KERN_ERR "Failed to register WM8737 SPI driver: %d\n",
 734                       ret);
 735        }
 736#endif
 737        return 0;
 738}
 739module_init(wm8737_modinit);
 740
 741static void __exit wm8737_exit(void)
 742{
 743#if defined(CONFIG_SPI_MASTER)
 744        spi_unregister_driver(&wm8737_spi_driver);
 745#endif
 746#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
 747        i2c_del_driver(&wm8737_i2c_driver);
 748#endif
 749}
 750module_exit(wm8737_exit);
 751
 752MODULE_DESCRIPTION("ASoC WM8737 driver");
 753MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
 754MODULE_LICENSE("GPL");
 755