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