linux/sound/soc/codecs/wm8741.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * wm8741.c  --  WM8741 ALSA SoC Audio driver
   4 *
   5 * Copyright 2010-1 Wolfson Microelectronics plc
   6 *
   7 * Author: Ian Lartey <ian@opensource.wolfsonmicro.com>
   8 */
   9
  10#include <linux/module.h>
  11#include <linux/moduleparam.h>
  12#include <linux/init.h>
  13#include <linux/delay.h>
  14#include <linux/pm.h>
  15#include <linux/i2c.h>
  16#include <linux/spi/spi.h>
  17#include <linux/regmap.h>
  18#include <linux/regulator/consumer.h>
  19#include <linux/slab.h>
  20#include <linux/of_device.h>
  21#include <sound/core.h>
  22#include <sound/pcm.h>
  23#include <sound/pcm_params.h>
  24#include <sound/soc.h>
  25#include <sound/initval.h>
  26#include <sound/tlv.h>
  27
  28#include "wm8741.h"
  29
  30#define WM8741_NUM_SUPPLIES 2
  31static const char *wm8741_supply_names[WM8741_NUM_SUPPLIES] = {
  32        "AVDD",
  33        "DVDD",
  34};
  35
  36/* codec private data */
  37struct wm8741_priv {
  38        struct wm8741_platform_data pdata;
  39        struct regmap *regmap;
  40        struct regulator_bulk_data supplies[WM8741_NUM_SUPPLIES];
  41        unsigned int sysclk;
  42        const struct snd_pcm_hw_constraint_list *sysclk_constraints;
  43};
  44
  45static const struct reg_default wm8741_reg_defaults[] = {
  46        {  0, 0x0000 },     /* R0  - DACLLSB Attenuation */
  47        {  1, 0x0000 },     /* R1  - DACLMSB Attenuation */
  48        {  2, 0x0000 },     /* R2  - DACRLSB Attenuation */
  49        {  3, 0x0000 },     /* R3  - DACRMSB Attenuation */
  50        {  4, 0x0000 },     /* R4  - Volume Control */
  51        {  5, 0x000A },     /* R5  - Format Control */
  52        {  6, 0x0000 },     /* R6  - Filter Control */
  53        {  7, 0x0000 },     /* R7  - Mode Control 1 */
  54        {  8, 0x0002 },     /* R8  - Mode Control 2 */
  55        { 32, 0x0002 },     /* R32 - ADDITONAL_CONTROL_1 */
  56};
  57
  58static int wm8741_reset(struct snd_soc_component *component)
  59{
  60        return snd_soc_component_write(component, WM8741_RESET, 0);
  61}
  62
  63static const DECLARE_TLV_DB_SCALE(dac_tlv_fine, -12700, 13, 0);
  64static const DECLARE_TLV_DB_SCALE(dac_tlv, -12700, 400, 0);
  65
  66static const struct snd_kcontrol_new wm8741_snd_controls_stereo[] = {
  67SOC_DOUBLE_R_TLV("Fine Playback Volume", WM8741_DACLLSB_ATTENUATION,
  68                 WM8741_DACRLSB_ATTENUATION, 1, 255, 1, dac_tlv_fine),
  69SOC_DOUBLE_R_TLV("Playback Volume", WM8741_DACLMSB_ATTENUATION,
  70                 WM8741_DACRMSB_ATTENUATION, 0, 511, 1, dac_tlv),
  71};
  72
  73static const struct snd_kcontrol_new wm8741_snd_controls_mono_left[] = {
  74SOC_SINGLE_TLV("Fine Playback Volume", WM8741_DACLLSB_ATTENUATION,
  75                 1, 255, 1, dac_tlv_fine),
  76SOC_SINGLE_TLV("Playback Volume", WM8741_DACLMSB_ATTENUATION,
  77                 0, 511, 1, dac_tlv),
  78};
  79
  80static const struct snd_kcontrol_new wm8741_snd_controls_mono_right[] = {
  81SOC_SINGLE_TLV("Fine Playback Volume", WM8741_DACRLSB_ATTENUATION,
  82                1, 255, 1, dac_tlv_fine),
  83SOC_SINGLE_TLV("Playback Volume", WM8741_DACRMSB_ATTENUATION,
  84                0, 511, 1, dac_tlv),
  85};
  86
  87static const struct snd_soc_dapm_widget wm8741_dapm_widgets[] = {
  88SND_SOC_DAPM_DAC("DACL", "Playback", SND_SOC_NOPM, 0, 0),
  89SND_SOC_DAPM_DAC("DACR", "Playback", SND_SOC_NOPM, 0, 0),
  90SND_SOC_DAPM_OUTPUT("VOUTLP"),
  91SND_SOC_DAPM_OUTPUT("VOUTLN"),
  92SND_SOC_DAPM_OUTPUT("VOUTRP"),
  93SND_SOC_DAPM_OUTPUT("VOUTRN"),
  94};
  95
  96static const struct snd_soc_dapm_route wm8741_dapm_routes[] = {
  97        { "VOUTLP", NULL, "DACL" },
  98        { "VOUTLN", NULL, "DACL" },
  99        { "VOUTRP", NULL, "DACR" },
 100        { "VOUTRN", NULL, "DACR" },
 101};
 102
 103static const unsigned int rates_11289[] = {
 104        44100, 88200,
 105};
 106
 107static const struct snd_pcm_hw_constraint_list constraints_11289 = {
 108        .count  = ARRAY_SIZE(rates_11289),
 109        .list   = rates_11289,
 110};
 111
 112static const unsigned int rates_12288[] = {
 113        32000, 48000, 96000,
 114};
 115
 116static const struct snd_pcm_hw_constraint_list constraints_12288 = {
 117        .count  = ARRAY_SIZE(rates_12288),
 118        .list   = rates_12288,
 119};
 120
 121static const unsigned int rates_16384[] = {
 122        32000,
 123};
 124
 125static const struct snd_pcm_hw_constraint_list constraints_16384 = {
 126        .count  = ARRAY_SIZE(rates_16384),
 127        .list   = rates_16384,
 128};
 129
 130static const unsigned int rates_16934[] = {
 131        44100, 88200,
 132};
 133
 134static const struct snd_pcm_hw_constraint_list constraints_16934 = {
 135        .count  = ARRAY_SIZE(rates_16934),
 136        .list   = rates_16934,
 137};
 138
 139static const unsigned int rates_18432[] = {
 140        48000, 96000,
 141};
 142
 143static const struct snd_pcm_hw_constraint_list constraints_18432 = {
 144        .count  = ARRAY_SIZE(rates_18432),
 145        .list   = rates_18432,
 146};
 147
 148static const unsigned int rates_22579[] = {
 149        44100, 88200, 176400
 150};
 151
 152static const struct snd_pcm_hw_constraint_list constraints_22579 = {
 153        .count  = ARRAY_SIZE(rates_22579),
 154        .list   = rates_22579,
 155};
 156
 157static const unsigned int rates_24576[] = {
 158        32000, 48000, 96000, 192000
 159};
 160
 161static const struct snd_pcm_hw_constraint_list constraints_24576 = {
 162        .count  = ARRAY_SIZE(rates_24576),
 163        .list   = rates_24576,
 164};
 165
 166static const unsigned int rates_36864[] = {
 167        48000, 96000, 192000
 168};
 169
 170static const struct snd_pcm_hw_constraint_list constraints_36864 = {
 171        .count  = ARRAY_SIZE(rates_36864),
 172        .list   = rates_36864,
 173};
 174
 175static int wm8741_startup(struct snd_pcm_substream *substream,
 176                          struct snd_soc_dai *dai)
 177{
 178        struct snd_soc_component *component = dai->component;
 179        struct wm8741_priv *wm8741 = snd_soc_component_get_drvdata(component);
 180
 181        if (wm8741->sysclk)
 182                snd_pcm_hw_constraint_list(substream->runtime, 0,
 183                                SNDRV_PCM_HW_PARAM_RATE,
 184                                wm8741->sysclk_constraints);
 185
 186        return 0;
 187}
 188
 189static int wm8741_hw_params(struct snd_pcm_substream *substream,
 190                            struct snd_pcm_hw_params *params,
 191                            struct snd_soc_dai *dai)
 192{
 193        struct snd_soc_component *component = dai->component;
 194        struct wm8741_priv *wm8741 = snd_soc_component_get_drvdata(component);
 195        unsigned int iface, mode;
 196        int i;
 197
 198        /* The set of sample rates that can be supported depends on the
 199         * MCLK supplied to the CODEC - enforce this.
 200         */
 201        if (!wm8741->sysclk) {
 202                dev_err(component->dev,
 203                        "No MCLK configured, call set_sysclk() on init or in hw_params\n");
 204                return -EINVAL;
 205        }
 206
 207        /* Find a supported LRCLK rate */
 208        for (i = 0; i < wm8741->sysclk_constraints->count; i++) {
 209                if (wm8741->sysclk_constraints->list[i] == params_rate(params))
 210                        break;
 211        }
 212
 213        if (i == wm8741->sysclk_constraints->count) {
 214                dev_err(component->dev, "LRCLK %d unsupported with MCLK %d\n",
 215                        params_rate(params), wm8741->sysclk);
 216                return -EINVAL;
 217        }
 218
 219        /* bit size */
 220        switch (params_width(params)) {
 221        case 16:
 222                iface = 0x0;
 223                break;
 224        case 20:
 225                iface = 0x1;
 226                break;
 227        case 24:
 228                iface = 0x2;
 229                break;
 230        case 32:
 231                iface = 0x3;
 232                break;
 233        default:
 234                dev_dbg(component->dev, "wm8741_hw_params:    Unsupported bit size param = %d",
 235                        params_width(params));
 236                return -EINVAL;
 237        }
 238
 239        /* oversampling rate */
 240        if (params_rate(params) > 96000)
 241                mode = 0x40;
 242        else if (params_rate(params) > 48000)
 243                mode = 0x20;
 244        else
 245                mode = 0x00;
 246
 247        dev_dbg(component->dev, "wm8741_hw_params:    bit size param = %d, rate param = %d",
 248                params_width(params), params_rate(params));
 249
 250        snd_soc_component_update_bits(component, WM8741_FORMAT_CONTROL, WM8741_IWL_MASK,
 251                            iface);
 252        snd_soc_component_update_bits(component, WM8741_MODE_CONTROL_1, WM8741_OSR_MASK,
 253                            mode);
 254
 255        return 0;
 256}
 257
 258static int wm8741_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 259                int clk_id, unsigned int freq, int dir)
 260{
 261        struct snd_soc_component *component = codec_dai->component;
 262        struct wm8741_priv *wm8741 = snd_soc_component_get_drvdata(component);
 263
 264        dev_dbg(component->dev, "wm8741_set_dai_sysclk info: freq=%dHz\n", freq);
 265
 266        switch (freq) {
 267        case 0:
 268                wm8741->sysclk_constraints = NULL;
 269                break;
 270        case 11289600:
 271                wm8741->sysclk_constraints = &constraints_11289;
 272                break;
 273        case 12288000:
 274                wm8741->sysclk_constraints = &constraints_12288;
 275                break;
 276        case 16384000:
 277                wm8741->sysclk_constraints = &constraints_16384;
 278                break;
 279        case 16934400:
 280                wm8741->sysclk_constraints = &constraints_16934;
 281                break;
 282        case 18432000:
 283                wm8741->sysclk_constraints = &constraints_18432;
 284                break;
 285        case 22579200:
 286        case 33868800:
 287                wm8741->sysclk_constraints = &constraints_22579;
 288                break;
 289        case 24576000:
 290                wm8741->sysclk_constraints = &constraints_24576;
 291                break;
 292        case 36864000:
 293                wm8741->sysclk_constraints = &constraints_36864;
 294                break;
 295        default:
 296                return -EINVAL;
 297        }
 298
 299        wm8741->sysclk = freq;
 300        return 0;
 301}
 302
 303static int wm8741_set_dai_fmt(struct snd_soc_dai *codec_dai,
 304                unsigned int fmt)
 305{
 306        struct snd_soc_component *component = codec_dai->component;
 307        unsigned int iface;
 308
 309        /* check master/slave audio interface */
 310        switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
 311        case SND_SOC_DAIFMT_CBS_CFS:
 312                break;
 313        default:
 314                return -EINVAL;
 315        }
 316
 317        /* interface format */
 318        switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
 319        case SND_SOC_DAIFMT_I2S:
 320                iface = 0x08;
 321                break;
 322        case SND_SOC_DAIFMT_RIGHT_J:
 323                iface = 0x00;
 324                break;
 325        case SND_SOC_DAIFMT_LEFT_J:
 326                iface = 0x04;
 327                break;
 328        case SND_SOC_DAIFMT_DSP_A:
 329                iface = 0x0C;
 330                break;
 331        case SND_SOC_DAIFMT_DSP_B:
 332                iface = 0x1C;
 333                break;
 334        default:
 335                return -EINVAL;
 336        }
 337
 338        /* clock inversion */
 339        switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
 340        case SND_SOC_DAIFMT_NB_NF:
 341                break;
 342        case SND_SOC_DAIFMT_NB_IF:
 343                iface |= 0x10;
 344                break;
 345        case SND_SOC_DAIFMT_IB_NF:
 346                iface |= 0x20;
 347                break;
 348        case SND_SOC_DAIFMT_IB_IF:
 349                iface |= 0x30;
 350                break;
 351        default:
 352                return -EINVAL;
 353        }
 354
 355
 356        dev_dbg(component->dev, "wm8741_set_dai_fmt:    Format=%x, Clock Inv=%x\n",
 357                                fmt & SND_SOC_DAIFMT_FORMAT_MASK,
 358                                ((fmt & SND_SOC_DAIFMT_INV_MASK)));
 359
 360        snd_soc_component_update_bits(component, WM8741_FORMAT_CONTROL,
 361                            WM8741_BCP_MASK | WM8741_LRP_MASK | WM8741_FMT_MASK,
 362                            iface);
 363
 364        return 0;
 365}
 366
 367static int wm8741_mute(struct snd_soc_dai *codec_dai, int mute, int direction)
 368{
 369        struct snd_soc_component *component = codec_dai->component;
 370
 371        snd_soc_component_update_bits(component, WM8741_VOLUME_CONTROL,
 372                        WM8741_SOFT_MASK, !!mute << WM8741_SOFT_SHIFT);
 373        return 0;
 374}
 375
 376#define WM8741_RATES (SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \
 377                        SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | \
 378                        SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 | \
 379                        SNDRV_PCM_RATE_192000)
 380
 381#define WM8741_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
 382                        SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
 383
 384static const struct snd_soc_dai_ops wm8741_dai_ops = {
 385        .startup        = wm8741_startup,
 386        .hw_params      = wm8741_hw_params,
 387        .set_sysclk     = wm8741_set_dai_sysclk,
 388        .set_fmt        = wm8741_set_dai_fmt,
 389        .mute_stream    = wm8741_mute,
 390        .no_capture_mute = 1,
 391};
 392
 393static struct snd_soc_dai_driver wm8741_dai = {
 394        .name = "wm8741",
 395        .playback = {
 396                .stream_name = "Playback",
 397                .channels_min = 2,
 398                .channels_max = 2,
 399                .rates = WM8741_RATES,
 400                .formats = WM8741_FORMATS,
 401        },
 402        .ops = &wm8741_dai_ops,
 403};
 404
 405#ifdef CONFIG_PM
 406static int wm8741_resume(struct snd_soc_component *component)
 407{
 408        snd_soc_component_cache_sync(component);
 409        return 0;
 410}
 411#else
 412#define wm8741_resume NULL
 413#endif
 414
 415static int wm8741_configure(struct snd_soc_component *component)
 416{
 417        struct wm8741_priv *wm8741 = snd_soc_component_get_drvdata(component);
 418
 419        /* Configure differential mode */
 420        switch (wm8741->pdata.diff_mode) {
 421        case WM8741_DIFF_MODE_STEREO:
 422        case WM8741_DIFF_MODE_STEREO_REVERSED:
 423        case WM8741_DIFF_MODE_MONO_LEFT:
 424        case WM8741_DIFF_MODE_MONO_RIGHT:
 425                snd_soc_component_update_bits(component, WM8741_MODE_CONTROL_2,
 426                                WM8741_DIFF_MASK,
 427                                wm8741->pdata.diff_mode << WM8741_DIFF_SHIFT);
 428                break;
 429        default:
 430                return -EINVAL;
 431        }
 432
 433        /* Change some default settings - latch VU */
 434        snd_soc_component_update_bits(component, WM8741_DACLLSB_ATTENUATION,
 435                        WM8741_UPDATELL, WM8741_UPDATELL);
 436        snd_soc_component_update_bits(component, WM8741_DACLMSB_ATTENUATION,
 437                        WM8741_UPDATELM, WM8741_UPDATELM);
 438        snd_soc_component_update_bits(component, WM8741_DACRLSB_ATTENUATION,
 439                        WM8741_UPDATERL, WM8741_UPDATERL);
 440        snd_soc_component_update_bits(component, WM8741_DACRMSB_ATTENUATION,
 441                        WM8741_UPDATERM, WM8741_UPDATERM);
 442
 443        return 0;
 444}
 445
 446static int wm8741_add_controls(struct snd_soc_component *component)
 447{
 448        struct wm8741_priv *wm8741 = snd_soc_component_get_drvdata(component);
 449
 450        switch (wm8741->pdata.diff_mode) {
 451        case WM8741_DIFF_MODE_STEREO:
 452        case WM8741_DIFF_MODE_STEREO_REVERSED:
 453                snd_soc_add_component_controls(component,
 454                                wm8741_snd_controls_stereo,
 455                                ARRAY_SIZE(wm8741_snd_controls_stereo));
 456                break;
 457        case WM8741_DIFF_MODE_MONO_LEFT:
 458                snd_soc_add_component_controls(component,
 459                                wm8741_snd_controls_mono_left,
 460                                ARRAY_SIZE(wm8741_snd_controls_mono_left));
 461                break;
 462        case WM8741_DIFF_MODE_MONO_RIGHT:
 463                snd_soc_add_component_controls(component,
 464                                wm8741_snd_controls_mono_right,
 465                                ARRAY_SIZE(wm8741_snd_controls_mono_right));
 466                break;
 467        default:
 468                return -EINVAL;
 469        }
 470
 471        return 0;
 472}
 473
 474static int wm8741_probe(struct snd_soc_component *component)
 475{
 476        struct wm8741_priv *wm8741 = snd_soc_component_get_drvdata(component);
 477        int ret = 0;
 478
 479        ret = regulator_bulk_enable(ARRAY_SIZE(wm8741->supplies),
 480                                    wm8741->supplies);
 481        if (ret != 0) {
 482                dev_err(component->dev, "Failed to enable supplies: %d\n", ret);
 483                goto err_get;
 484        }
 485
 486        ret = wm8741_reset(component);
 487        if (ret < 0) {
 488                dev_err(component->dev, "Failed to issue reset\n");
 489                goto err_enable;
 490        }
 491
 492        ret = wm8741_configure(component);
 493        if (ret < 0) {
 494                dev_err(component->dev, "Failed to change default settings\n");
 495                goto err_enable;
 496        }
 497
 498        ret = wm8741_add_controls(component);
 499        if (ret < 0) {
 500                dev_err(component->dev, "Failed to add controls\n");
 501                goto err_enable;
 502        }
 503
 504        dev_dbg(component->dev, "Successful registration\n");
 505        return ret;
 506
 507err_enable:
 508        regulator_bulk_disable(ARRAY_SIZE(wm8741->supplies), wm8741->supplies);
 509err_get:
 510        return ret;
 511}
 512
 513static void wm8741_remove(struct snd_soc_component *component)
 514{
 515        struct wm8741_priv *wm8741 = snd_soc_component_get_drvdata(component);
 516
 517        regulator_bulk_disable(ARRAY_SIZE(wm8741->supplies), wm8741->supplies);
 518}
 519
 520static const struct snd_soc_component_driver soc_component_dev_wm8741 = {
 521        .probe                  = wm8741_probe,
 522        .remove                 = wm8741_remove,
 523        .resume                 = wm8741_resume,
 524        .dapm_widgets           = wm8741_dapm_widgets,
 525        .num_dapm_widgets       = ARRAY_SIZE(wm8741_dapm_widgets),
 526        .dapm_routes            = wm8741_dapm_routes,
 527        .num_dapm_routes        = ARRAY_SIZE(wm8741_dapm_routes),
 528        .idle_bias_on           = 1,
 529        .use_pmdown_time        = 1,
 530        .endianness             = 1,
 531        .non_legacy_dai_naming  = 1,
 532};
 533
 534static const struct of_device_id wm8741_of_match[] = {
 535        { .compatible = "wlf,wm8741", },
 536        { }
 537};
 538MODULE_DEVICE_TABLE(of, wm8741_of_match);
 539
 540static const struct regmap_config wm8741_regmap = {
 541        .reg_bits = 7,
 542        .val_bits = 9,
 543        .max_register = WM8741_MAX_REGISTER,
 544
 545        .reg_defaults = wm8741_reg_defaults,
 546        .num_reg_defaults = ARRAY_SIZE(wm8741_reg_defaults),
 547        .cache_type = REGCACHE_RBTREE,
 548};
 549
 550static int wm8741_set_pdata(struct device *dev, struct wm8741_priv *wm8741)
 551{
 552        const struct wm8741_platform_data *pdata = dev_get_platdata(dev);
 553        u32 diff_mode;
 554
 555        if (dev->of_node) {
 556                if (of_property_read_u32(dev->of_node, "diff-mode", &diff_mode)
 557                                >= 0)
 558                        wm8741->pdata.diff_mode = diff_mode;
 559        } else {
 560                if (pdata != NULL)
 561                        memcpy(&wm8741->pdata, pdata, sizeof(wm8741->pdata));
 562        }
 563
 564        return 0;
 565}
 566
 567#if IS_ENABLED(CONFIG_I2C)
 568static int wm8741_i2c_probe(struct i2c_client *i2c,
 569                            const struct i2c_device_id *id)
 570{
 571        struct wm8741_priv *wm8741;
 572        int ret, i;
 573
 574        wm8741 = devm_kzalloc(&i2c->dev, sizeof(struct wm8741_priv),
 575                              GFP_KERNEL);
 576        if (wm8741 == NULL)
 577                return -ENOMEM;
 578
 579        for (i = 0; i < ARRAY_SIZE(wm8741->supplies); i++)
 580                wm8741->supplies[i].supply = wm8741_supply_names[i];
 581
 582        ret = devm_regulator_bulk_get(&i2c->dev, ARRAY_SIZE(wm8741->supplies),
 583                                      wm8741->supplies);
 584        if (ret != 0) {
 585                dev_err(&i2c->dev, "Failed to request supplies: %d\n", ret);
 586                return ret;
 587        }
 588
 589        wm8741->regmap = devm_regmap_init_i2c(i2c, &wm8741_regmap);
 590        if (IS_ERR(wm8741->regmap)) {
 591                ret = PTR_ERR(wm8741->regmap);
 592                dev_err(&i2c->dev, "Failed to init regmap: %d\n", ret);
 593                return ret;
 594        }
 595
 596        ret = wm8741_set_pdata(&i2c->dev, wm8741);
 597        if (ret != 0) {
 598                dev_err(&i2c->dev, "Failed to set pdata: %d\n", ret);
 599                return ret;
 600        }
 601
 602        i2c_set_clientdata(i2c, wm8741);
 603
 604        ret = devm_snd_soc_register_component(&i2c->dev,
 605                                     &soc_component_dev_wm8741, &wm8741_dai, 1);
 606
 607        return ret;
 608}
 609
 610static const struct i2c_device_id wm8741_i2c_id[] = {
 611        { "wm8741", 0 },
 612        { }
 613};
 614MODULE_DEVICE_TABLE(i2c, wm8741_i2c_id);
 615
 616static struct i2c_driver wm8741_i2c_driver = {
 617        .driver = {
 618                .name = "wm8741",
 619                .of_match_table = wm8741_of_match,
 620        },
 621        .probe =    wm8741_i2c_probe,
 622        .id_table = wm8741_i2c_id,
 623};
 624#endif
 625
 626#if defined(CONFIG_SPI_MASTER)
 627static int wm8741_spi_probe(struct spi_device *spi)
 628{
 629        struct wm8741_priv *wm8741;
 630        int ret, i;
 631
 632        wm8741 = devm_kzalloc(&spi->dev, sizeof(struct wm8741_priv),
 633                             GFP_KERNEL);
 634        if (wm8741 == NULL)
 635                return -ENOMEM;
 636
 637        for (i = 0; i < ARRAY_SIZE(wm8741->supplies); i++)
 638                wm8741->supplies[i].supply = wm8741_supply_names[i];
 639
 640        ret = devm_regulator_bulk_get(&spi->dev, ARRAY_SIZE(wm8741->supplies),
 641                                      wm8741->supplies);
 642        if (ret != 0) {
 643                dev_err(&spi->dev, "Failed to request supplies: %d\n", ret);
 644                return ret;
 645        }
 646
 647        wm8741->regmap = devm_regmap_init_spi(spi, &wm8741_regmap);
 648        if (IS_ERR(wm8741->regmap)) {
 649                ret = PTR_ERR(wm8741->regmap);
 650                dev_err(&spi->dev, "Failed to init regmap: %d\n", ret);
 651                return ret;
 652        }
 653
 654        ret = wm8741_set_pdata(&spi->dev, wm8741);
 655        if (ret != 0) {
 656                dev_err(&spi->dev, "Failed to set pdata: %d\n", ret);
 657                return ret;
 658        }
 659
 660        spi_set_drvdata(spi, wm8741);
 661
 662        ret = devm_snd_soc_register_component(&spi->dev,
 663                        &soc_component_dev_wm8741, &wm8741_dai, 1);
 664        return ret;
 665}
 666
 667static struct spi_driver wm8741_spi_driver = {
 668        .driver = {
 669                .name   = "wm8741",
 670                .of_match_table = wm8741_of_match,
 671        },
 672        .probe          = wm8741_spi_probe,
 673};
 674#endif /* CONFIG_SPI_MASTER */
 675
 676static int __init wm8741_modinit(void)
 677{
 678        int ret = 0;
 679
 680#if IS_ENABLED(CONFIG_I2C)
 681        ret = i2c_add_driver(&wm8741_i2c_driver);
 682        if (ret != 0)
 683                pr_err("Failed to register WM8741 I2C driver: %d\n", ret);
 684#endif
 685#if defined(CONFIG_SPI_MASTER)
 686        ret = spi_register_driver(&wm8741_spi_driver);
 687        if (ret != 0) {
 688                printk(KERN_ERR "Failed to register wm8741 SPI driver: %d\n",
 689                       ret);
 690        }
 691#endif
 692
 693        return ret;
 694}
 695module_init(wm8741_modinit);
 696
 697static void __exit wm8741_exit(void)
 698{
 699#if defined(CONFIG_SPI_MASTER)
 700        spi_unregister_driver(&wm8741_spi_driver);
 701#endif
 702#if IS_ENABLED(CONFIG_I2C)
 703        i2c_del_driver(&wm8741_i2c_driver);
 704#endif
 705}
 706module_exit(wm8741_exit);
 707
 708MODULE_DESCRIPTION("ASoC WM8741 driver");
 709MODULE_AUTHOR("Ian Lartey <ian@opensource.wolfsonmicro.com>");
 710MODULE_LICENSE("GPL");
 711