linux/sound/soc/codecs/wm8731.c
<<
>>
Prefs
   1/*
   2 * wm8731.c  --  WM8731 ALSA SoC Audio driver
   3 *
   4 * Copyright 2005 Openedhand Ltd.
   5 *
   6 * Author: Richard Purdie <richard@openedhand.com>
   7 *
   8 * Based on wm8753.c by Liam Girdwood
   9 *
  10 * This program is free software; you can redistribute it and/or modify
  11 * it under the terms of the GNU General Public License version 2 as
  12 * published by the Free Software Foundation.
  13 */
  14
  15#include <linux/module.h>
  16#include <linux/moduleparam.h>
  17#include <linux/init.h>
  18#include <linux/delay.h>
  19#include <linux/pm.h>
  20#include <linux/i2c.h>
  21#include <linux/platform_device.h>
  22#include <linux/spi/spi.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
  30#include "wm8731.h"
  31
  32static struct snd_soc_codec *wm8731_codec;
  33struct snd_soc_codec_device soc_codec_dev_wm8731;
  34
  35/* codec private data */
  36struct wm8731_priv {
  37        struct snd_soc_codec codec;
  38        u16 reg_cache[WM8731_CACHEREGNUM];
  39        unsigned int sysclk;
  40};
  41
  42#ifdef CONFIG_SPI_MASTER
  43static int wm8731_spi_write(struct spi_device *spi, const char *data, int len);
  44#endif
  45
  46/*
  47 * wm8731 register cache
  48 * We can't read the WM8731 register space when we are
  49 * using 2 wire for device control, so we cache them instead.
  50 * There is no point in caching the reset register
  51 */
  52static const u16 wm8731_reg[WM8731_CACHEREGNUM] = {
  53    0x0097, 0x0097, 0x0079, 0x0079,
  54    0x000a, 0x0008, 0x009f, 0x000a,
  55    0x0000, 0x0000
  56};
  57
  58/*
  59 * read wm8731 register cache
  60 */
  61static inline unsigned int wm8731_read_reg_cache(struct snd_soc_codec *codec,
  62        unsigned int reg)
  63{
  64        u16 *cache = codec->reg_cache;
  65        if (reg == WM8731_RESET)
  66                return 0;
  67        if (reg >= WM8731_CACHEREGNUM)
  68                return -1;
  69        return cache[reg];
  70}
  71
  72/*
  73 * write wm8731 register cache
  74 */
  75static inline void wm8731_write_reg_cache(struct snd_soc_codec *codec,
  76        u16 reg, unsigned int value)
  77{
  78        u16 *cache = codec->reg_cache;
  79        if (reg >= WM8731_CACHEREGNUM)
  80                return;
  81        cache[reg] = value;
  82}
  83
  84/*
  85 * write to the WM8731 register space
  86 */
  87static int wm8731_write(struct snd_soc_codec *codec, unsigned int reg,
  88        unsigned int value)
  89{
  90        u8 data[2];
  91
  92        /* data is
  93         *   D15..D9 WM8731 register offset
  94         *   D8...D0 register data
  95         */
  96        data[0] = (reg << 1) | ((value >> 8) & 0x0001);
  97        data[1] = value & 0x00ff;
  98
  99        wm8731_write_reg_cache(codec, reg, value);
 100        if (codec->hw_write(codec->control_data, data, 2) == 2)
 101                return 0;
 102        else
 103                return -EIO;
 104}
 105
 106#define wm8731_reset(c) wm8731_write(c, WM8731_RESET, 0)
 107
 108static const char *wm8731_input_select[] = {"Line In", "Mic"};
 109static const char *wm8731_deemph[] = {"None", "32Khz", "44.1Khz", "48Khz"};
 110
 111static const struct soc_enum wm8731_enum[] = {
 112        SOC_ENUM_SINGLE(WM8731_APANA, 2, 2, wm8731_input_select),
 113        SOC_ENUM_SINGLE(WM8731_APDIGI, 1, 4, wm8731_deemph),
 114};
 115
 116static const struct snd_kcontrol_new wm8731_snd_controls[] = {
 117
 118SOC_DOUBLE_R("Master Playback Volume", WM8731_LOUT1V, WM8731_ROUT1V,
 119        0, 127, 0),
 120SOC_DOUBLE_R("Master Playback ZC Switch", WM8731_LOUT1V, WM8731_ROUT1V,
 121        7, 1, 0),
 122
 123SOC_DOUBLE_R("Capture Volume", WM8731_LINVOL, WM8731_RINVOL, 0, 31, 0),
 124SOC_DOUBLE_R("Line Capture Switch", WM8731_LINVOL, WM8731_RINVOL, 7, 1, 1),
 125
 126SOC_SINGLE("Mic Boost (+20dB)", WM8731_APANA, 0, 1, 0),
 127SOC_SINGLE("Capture Mic Switch", WM8731_APANA, 1, 1, 1),
 128
 129SOC_SINGLE("Sidetone Playback Volume", WM8731_APANA, 6, 3, 1),
 130
 131SOC_SINGLE("ADC High Pass Filter Switch", WM8731_APDIGI, 0, 1, 1),
 132SOC_SINGLE("Store DC Offset Switch", WM8731_APDIGI, 4, 1, 0),
 133
 134SOC_ENUM("Playback De-emphasis", wm8731_enum[1]),
 135};
 136
 137/* Output Mixer */
 138static const struct snd_kcontrol_new wm8731_output_mixer_controls[] = {
 139SOC_DAPM_SINGLE("Line Bypass Switch", WM8731_APANA, 3, 1, 0),
 140SOC_DAPM_SINGLE("Mic Sidetone Switch", WM8731_APANA, 5, 1, 0),
 141SOC_DAPM_SINGLE("HiFi Playback Switch", WM8731_APANA, 4, 1, 0),
 142};
 143
 144/* Input mux */
 145static const struct snd_kcontrol_new wm8731_input_mux_controls =
 146SOC_DAPM_ENUM("Input Select", wm8731_enum[0]);
 147
 148static const struct snd_soc_dapm_widget wm8731_dapm_widgets[] = {
 149SND_SOC_DAPM_MIXER("Output Mixer", WM8731_PWR, 4, 1,
 150        &wm8731_output_mixer_controls[0],
 151        ARRAY_SIZE(wm8731_output_mixer_controls)),
 152SND_SOC_DAPM_DAC("DAC", "HiFi Playback", WM8731_PWR, 3, 1),
 153SND_SOC_DAPM_OUTPUT("LOUT"),
 154SND_SOC_DAPM_OUTPUT("LHPOUT"),
 155SND_SOC_DAPM_OUTPUT("ROUT"),
 156SND_SOC_DAPM_OUTPUT("RHPOUT"),
 157SND_SOC_DAPM_ADC("ADC", "HiFi Capture", WM8731_PWR, 2, 1),
 158SND_SOC_DAPM_MUX("Input Mux", SND_SOC_NOPM, 0, 0, &wm8731_input_mux_controls),
 159SND_SOC_DAPM_PGA("Line Input", WM8731_PWR, 0, 1, NULL, 0),
 160SND_SOC_DAPM_MICBIAS("Mic Bias", WM8731_PWR, 1, 1),
 161SND_SOC_DAPM_INPUT("MICIN"),
 162SND_SOC_DAPM_INPUT("RLINEIN"),
 163SND_SOC_DAPM_INPUT("LLINEIN"),
 164};
 165
 166static const struct snd_soc_dapm_route intercon[] = {
 167        /* output mixer */
 168        {"Output Mixer", "Line Bypass Switch", "Line Input"},
 169        {"Output Mixer", "HiFi Playback Switch", "DAC"},
 170        {"Output Mixer", "Mic Sidetone Switch", "Mic Bias"},
 171
 172        /* outputs */
 173        {"RHPOUT", NULL, "Output Mixer"},
 174        {"ROUT", NULL, "Output Mixer"},
 175        {"LHPOUT", NULL, "Output Mixer"},
 176        {"LOUT", NULL, "Output Mixer"},
 177
 178        /* input mux */
 179        {"Input Mux", "Line In", "Line Input"},
 180        {"Input Mux", "Mic", "Mic Bias"},
 181        {"ADC", NULL, "Input Mux"},
 182
 183        /* inputs */
 184        {"Line Input", NULL, "LLINEIN"},
 185        {"Line Input", NULL, "RLINEIN"},
 186        {"Mic Bias", NULL, "MICIN"},
 187};
 188
 189static int wm8731_add_widgets(struct snd_soc_codec *codec)
 190{
 191        snd_soc_dapm_new_controls(codec, wm8731_dapm_widgets,
 192                                  ARRAY_SIZE(wm8731_dapm_widgets));
 193
 194        snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
 195
 196        snd_soc_dapm_new_widgets(codec);
 197        return 0;
 198}
 199
 200struct _coeff_div {
 201        u32 mclk;
 202        u32 rate;
 203        u16 fs;
 204        u8 sr:4;
 205        u8 bosr:1;
 206        u8 usb:1;
 207};
 208
 209/* codec mclk clock divider coefficients */
 210static const struct _coeff_div coeff_div[] = {
 211        /* 48k */
 212        {12288000, 48000, 256, 0x0, 0x0, 0x0},
 213        {18432000, 48000, 384, 0x0, 0x1, 0x0},
 214        {12000000, 48000, 250, 0x0, 0x0, 0x1},
 215
 216        /* 32k */
 217        {12288000, 32000, 384, 0x6, 0x0, 0x0},
 218        {18432000, 32000, 576, 0x6, 0x1, 0x0},
 219        {12000000, 32000, 375, 0x6, 0x0, 0x1},
 220
 221        /* 8k */
 222        {12288000, 8000, 1536, 0x3, 0x0, 0x0},
 223        {18432000, 8000, 2304, 0x3, 0x1, 0x0},
 224        {11289600, 8000, 1408, 0xb, 0x0, 0x0},
 225        {16934400, 8000, 2112, 0xb, 0x1, 0x0},
 226        {12000000, 8000, 1500, 0x3, 0x0, 0x1},
 227
 228        /* 96k */
 229        {12288000, 96000, 128, 0x7, 0x0, 0x0},
 230        {18432000, 96000, 192, 0x7, 0x1, 0x0},
 231        {12000000, 96000, 125, 0x7, 0x0, 0x1},
 232
 233        /* 44.1k */
 234        {11289600, 44100, 256, 0x8, 0x0, 0x0},
 235        {16934400, 44100, 384, 0x8, 0x1, 0x0},
 236        {12000000, 44100, 272, 0x8, 0x1, 0x1},
 237
 238        /* 88.2k */
 239        {11289600, 88200, 128, 0xf, 0x0, 0x0},
 240        {16934400, 88200, 192, 0xf, 0x1, 0x0},
 241        {12000000, 88200, 136, 0xf, 0x1, 0x1},
 242};
 243
 244static inline int get_coeff(int mclk, int rate)
 245{
 246        int i;
 247
 248        for (i = 0; i < ARRAY_SIZE(coeff_div); i++) {
 249                if (coeff_div[i].rate == rate && coeff_div[i].mclk == mclk)
 250                        return i;
 251        }
 252        return 0;
 253}
 254
 255static int wm8731_hw_params(struct snd_pcm_substream *substream,
 256                            struct snd_pcm_hw_params *params,
 257                            struct snd_soc_dai *dai)
 258{
 259        struct snd_soc_pcm_runtime *rtd = substream->private_data;
 260        struct snd_soc_device *socdev = rtd->socdev;
 261        struct snd_soc_codec *codec = socdev->card->codec;
 262        struct wm8731_priv *wm8731 = codec->private_data;
 263        u16 iface = wm8731_read_reg_cache(codec, WM8731_IFACE) & 0xfff3;
 264        int i = get_coeff(wm8731->sysclk, params_rate(params));
 265        u16 srate = (coeff_div[i].sr << 2) |
 266                (coeff_div[i].bosr << 1) | coeff_div[i].usb;
 267
 268        wm8731_write(codec, WM8731_SRATE, srate);
 269
 270        /* bit size */
 271        switch (params_format(params)) {
 272        case SNDRV_PCM_FORMAT_S16_LE:
 273                break;
 274        case SNDRV_PCM_FORMAT_S20_3LE:
 275                iface |= 0x0004;
 276                break;
 277        case SNDRV_PCM_FORMAT_S24_LE:
 278                iface |= 0x0008;
 279                break;
 280        }
 281
 282        wm8731_write(codec, WM8731_IFACE, iface);
 283        return 0;
 284}
 285
 286static int wm8731_pcm_prepare(struct snd_pcm_substream *substream,
 287                              struct snd_soc_dai *dai)
 288{
 289        struct snd_soc_pcm_runtime *rtd = substream->private_data;
 290        struct snd_soc_device *socdev = rtd->socdev;
 291        struct snd_soc_codec *codec = socdev->card->codec;
 292
 293        /* set active */
 294        wm8731_write(codec, WM8731_ACTIVE, 0x0001);
 295
 296        return 0;
 297}
 298
 299static void wm8731_shutdown(struct snd_pcm_substream *substream,
 300                            struct snd_soc_dai *dai)
 301{
 302        struct snd_soc_pcm_runtime *rtd = substream->private_data;
 303        struct snd_soc_device *socdev = rtd->socdev;
 304        struct snd_soc_codec *codec = socdev->card->codec;
 305
 306        /* deactivate */
 307        if (!codec->active) {
 308                udelay(50);
 309                wm8731_write(codec, WM8731_ACTIVE, 0x0);
 310        }
 311}
 312
 313static int wm8731_mute(struct snd_soc_dai *dai, int mute)
 314{
 315        struct snd_soc_codec *codec = dai->codec;
 316        u16 mute_reg = wm8731_read_reg_cache(codec, WM8731_APDIGI) & 0xfff7;
 317
 318        if (mute)
 319                wm8731_write(codec, WM8731_APDIGI, mute_reg | 0x8);
 320        else
 321                wm8731_write(codec, WM8731_APDIGI, mute_reg);
 322        return 0;
 323}
 324
 325static int wm8731_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 326                int clk_id, unsigned int freq, int dir)
 327{
 328        struct snd_soc_codec *codec = codec_dai->codec;
 329        struct wm8731_priv *wm8731 = codec->private_data;
 330
 331        switch (freq) {
 332        case 11289600:
 333        case 12000000:
 334        case 12288000:
 335        case 16934400:
 336        case 18432000:
 337                wm8731->sysclk = freq;
 338                return 0;
 339        }
 340        return -EINVAL;
 341}
 342
 343
 344static int wm8731_set_dai_fmt(struct snd_soc_dai *codec_dai,
 345                unsigned int fmt)
 346{
 347        struct snd_soc_codec *codec = codec_dai->codec;
 348        u16 iface = 0;
 349
 350        /* set master/slave audio interface */
 351        switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
 352        case SND_SOC_DAIFMT_CBM_CFM:
 353                iface |= 0x0040;
 354                break;
 355        case SND_SOC_DAIFMT_CBS_CFS:
 356                break;
 357        default:
 358                return -EINVAL;
 359        }
 360
 361        /* interface format */
 362        switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
 363        case SND_SOC_DAIFMT_I2S:
 364                iface |= 0x0002;
 365                break;
 366        case SND_SOC_DAIFMT_RIGHT_J:
 367                break;
 368        case SND_SOC_DAIFMT_LEFT_J:
 369                iface |= 0x0001;
 370                break;
 371        case SND_SOC_DAIFMT_DSP_A:
 372                iface |= 0x0003;
 373                break;
 374        case SND_SOC_DAIFMT_DSP_B:
 375                iface |= 0x0013;
 376                break;
 377        default:
 378                return -EINVAL;
 379        }
 380
 381        /* clock inversion */
 382        switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
 383        case SND_SOC_DAIFMT_NB_NF:
 384                break;
 385        case SND_SOC_DAIFMT_IB_IF:
 386                iface |= 0x0090;
 387                break;
 388        case SND_SOC_DAIFMT_IB_NF:
 389                iface |= 0x0080;
 390                break;
 391        case SND_SOC_DAIFMT_NB_IF:
 392                iface |= 0x0010;
 393                break;
 394        default:
 395                return -EINVAL;
 396        }
 397
 398        /* set iface */
 399        wm8731_write(codec, WM8731_IFACE, iface);
 400        return 0;
 401}
 402
 403static int wm8731_set_bias_level(struct snd_soc_codec *codec,
 404                                 enum snd_soc_bias_level level)
 405{
 406        u16 reg;
 407
 408        switch (level) {
 409        case SND_SOC_BIAS_ON:
 410                break;
 411        case SND_SOC_BIAS_PREPARE:
 412                break;
 413        case SND_SOC_BIAS_STANDBY:
 414                /* Clear PWROFF, gate CLKOUT, everything else as-is */
 415                reg = wm8731_read_reg_cache(codec, WM8731_PWR) & 0xff7f;
 416                wm8731_write(codec, WM8731_PWR, reg | 0x0040);
 417                break;
 418        case SND_SOC_BIAS_OFF:
 419                wm8731_write(codec, WM8731_ACTIVE, 0x0);
 420                wm8731_write(codec, WM8731_PWR, 0xffff);
 421                break;
 422        }
 423        codec->bias_level = level;
 424        return 0;
 425}
 426
 427#define WM8731_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
 428                SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |\
 429                SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |\
 430                SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 |\
 431                SNDRV_PCM_RATE_96000)
 432
 433#define WM8731_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
 434        SNDRV_PCM_FMTBIT_S24_LE)
 435
 436static struct snd_soc_dai_ops wm8731_dai_ops = {
 437        .prepare        = wm8731_pcm_prepare,
 438        .hw_params      = wm8731_hw_params,
 439        .shutdown       = wm8731_shutdown,
 440        .digital_mute   = wm8731_mute,
 441        .set_sysclk     = wm8731_set_dai_sysclk,
 442        .set_fmt        = wm8731_set_dai_fmt,
 443};
 444
 445struct snd_soc_dai wm8731_dai = {
 446        .name = "WM8731",
 447        .playback = {
 448                .stream_name = "Playback",
 449                .channels_min = 1,
 450                .channels_max = 2,
 451                .rates = WM8731_RATES,
 452                .formats = WM8731_FORMATS,},
 453        .capture = {
 454                .stream_name = "Capture",
 455                .channels_min = 1,
 456                .channels_max = 2,
 457                .rates = WM8731_RATES,
 458                .formats = WM8731_FORMATS,},
 459        .ops = &wm8731_dai_ops,
 460};
 461EXPORT_SYMBOL_GPL(wm8731_dai);
 462
 463static int wm8731_suspend(struct platform_device *pdev, pm_message_t state)
 464{
 465        struct snd_soc_device *socdev = platform_get_drvdata(pdev);
 466        struct snd_soc_codec *codec = socdev->card->codec;
 467
 468        wm8731_write(codec, WM8731_ACTIVE, 0x0);
 469        wm8731_set_bias_level(codec, SND_SOC_BIAS_OFF);
 470        return 0;
 471}
 472
 473static int wm8731_resume(struct platform_device *pdev)
 474{
 475        struct snd_soc_device *socdev = platform_get_drvdata(pdev);
 476        struct snd_soc_codec *codec = socdev->card->codec;
 477        int i;
 478        u8 data[2];
 479        u16 *cache = codec->reg_cache;
 480
 481        /* Sync reg_cache with the hardware */
 482        for (i = 0; i < ARRAY_SIZE(wm8731_reg); i++) {
 483                data[0] = (i << 1) | ((cache[i] >> 8) & 0x0001);
 484                data[1] = cache[i] & 0x00ff;
 485                codec->hw_write(codec->control_data, data, 2);
 486        }
 487        wm8731_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
 488        wm8731_set_bias_level(codec, codec->suspend_bias_level);
 489        return 0;
 490}
 491
 492static int wm8731_probe(struct platform_device *pdev)
 493{
 494        struct snd_soc_device *socdev = platform_get_drvdata(pdev);
 495        struct snd_soc_codec *codec;
 496        int ret = 0;
 497
 498        if (wm8731_codec == NULL) {
 499                dev_err(&pdev->dev, "Codec device not registered\n");
 500                return -ENODEV;
 501        }
 502
 503        socdev->card->codec = wm8731_codec;
 504        codec = wm8731_codec;
 505
 506        /* register pcms */
 507        ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
 508        if (ret < 0) {
 509                dev_err(codec->dev, "failed to create pcms: %d\n", ret);
 510                goto pcm_err;
 511        }
 512
 513        snd_soc_add_controls(codec, wm8731_snd_controls,
 514                             ARRAY_SIZE(wm8731_snd_controls));
 515        wm8731_add_widgets(codec);
 516        ret = snd_soc_init_card(socdev);
 517        if (ret < 0) {
 518                dev_err(codec->dev, "failed to register card: %d\n", ret);
 519                goto card_err;
 520        }
 521
 522        return ret;
 523
 524card_err:
 525        snd_soc_free_pcms(socdev);
 526        snd_soc_dapm_free(socdev);
 527pcm_err:
 528        return ret;
 529}
 530
 531/* power down chip */
 532static int wm8731_remove(struct platform_device *pdev)
 533{
 534        struct snd_soc_device *socdev = platform_get_drvdata(pdev);
 535
 536        snd_soc_free_pcms(socdev);
 537        snd_soc_dapm_free(socdev);
 538
 539        return 0;
 540}
 541
 542struct snd_soc_codec_device soc_codec_dev_wm8731 = {
 543        .probe =        wm8731_probe,
 544        .remove =       wm8731_remove,
 545        .suspend =      wm8731_suspend,
 546        .resume =       wm8731_resume,
 547};
 548EXPORT_SYMBOL_GPL(soc_codec_dev_wm8731);
 549
 550static int wm8731_register(struct wm8731_priv *wm8731)
 551{
 552        int ret;
 553        struct snd_soc_codec *codec = &wm8731->codec;
 554        u16 reg;
 555
 556        if (wm8731_codec) {
 557                dev_err(codec->dev, "Another WM8731 is registered\n");
 558                return -EINVAL;
 559        }
 560
 561        mutex_init(&codec->mutex);
 562        INIT_LIST_HEAD(&codec->dapm_widgets);
 563        INIT_LIST_HEAD(&codec->dapm_paths);
 564
 565        codec->private_data = wm8731;
 566        codec->name = "WM8731";
 567        codec->owner = THIS_MODULE;
 568        codec->read = wm8731_read_reg_cache;
 569        codec->write = wm8731_write;
 570        codec->bias_level = SND_SOC_BIAS_OFF;
 571        codec->set_bias_level = wm8731_set_bias_level;
 572        codec->dai = &wm8731_dai;
 573        codec->num_dai = 1;
 574        codec->reg_cache_size = WM8731_CACHEREGNUM;
 575        codec->reg_cache = &wm8731->reg_cache;
 576
 577        memcpy(codec->reg_cache, wm8731_reg, sizeof(wm8731_reg));
 578
 579        ret = wm8731_reset(codec);
 580        if (ret < 0) {
 581                dev_err(codec->dev, "Failed to issue reset\n");
 582                return ret;
 583        }
 584
 585        wm8731_dai.dev = codec->dev;
 586
 587        wm8731_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
 588
 589        /* Latch the update bits */
 590        reg = wm8731_read_reg_cache(codec, WM8731_LOUT1V);
 591        wm8731_write(codec, WM8731_LOUT1V, reg & ~0x0100);
 592        reg = wm8731_read_reg_cache(codec, WM8731_ROUT1V);
 593        wm8731_write(codec, WM8731_ROUT1V, reg & ~0x0100);
 594        reg = wm8731_read_reg_cache(codec, WM8731_LINVOL);
 595        wm8731_write(codec, WM8731_LINVOL, reg & ~0x0100);
 596        reg = wm8731_read_reg_cache(codec, WM8731_RINVOL);
 597        wm8731_write(codec, WM8731_RINVOL, reg & ~0x0100);
 598
 599        /* Disable bypass path by default */
 600        reg = wm8731_read_reg_cache(codec, WM8731_APANA);
 601        wm8731_write(codec, WM8731_APANA, reg & ~0x4);
 602
 603        wm8731_codec = codec;
 604
 605        ret = snd_soc_register_codec(codec);
 606        if (ret != 0) {
 607                dev_err(codec->dev, "Failed to register codec: %d\n", ret);
 608                return ret;
 609        }
 610
 611        ret = snd_soc_register_dai(&wm8731_dai);
 612        if (ret != 0) {
 613                dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
 614                snd_soc_unregister_codec(codec);
 615                return ret;
 616        }
 617
 618        return 0;
 619}
 620
 621static void wm8731_unregister(struct wm8731_priv *wm8731)
 622{
 623        wm8731_set_bias_level(&wm8731->codec, SND_SOC_BIAS_OFF);
 624        snd_soc_unregister_dai(&wm8731_dai);
 625        snd_soc_unregister_codec(&wm8731->codec);
 626        kfree(wm8731);
 627        wm8731_codec = NULL;
 628}
 629
 630#if defined(CONFIG_SPI_MASTER)
 631static int wm8731_spi_write(struct spi_device *spi, const char *data, int len)
 632{
 633        struct spi_transfer t;
 634        struct spi_message m;
 635        u8 msg[2];
 636
 637        if (len <= 0)
 638                return 0;
 639
 640        msg[0] = data[0];
 641        msg[1] = data[1];
 642
 643        spi_message_init(&m);
 644        memset(&t, 0, (sizeof t));
 645
 646        t.tx_buf = &msg[0];
 647        t.len = len;
 648
 649        spi_message_add_tail(&t, &m);
 650        spi_sync(spi, &m);
 651
 652        return len;
 653}
 654
 655static int __devinit wm8731_spi_probe(struct spi_device *spi)
 656{
 657        struct snd_soc_codec *codec;
 658        struct wm8731_priv *wm8731;
 659
 660        wm8731 = kzalloc(sizeof(struct wm8731_priv), GFP_KERNEL);
 661        if (wm8731 == NULL)
 662                return -ENOMEM;
 663
 664        codec = &wm8731->codec;
 665        codec->control_data = spi;
 666        codec->hw_write = (hw_write_t)wm8731_spi_write;
 667        codec->dev = &spi->dev;
 668
 669        dev_set_drvdata(&spi->dev, wm8731);
 670
 671        return wm8731_register(wm8731);
 672}
 673
 674static int __devexit wm8731_spi_remove(struct spi_device *spi)
 675{
 676        struct wm8731_priv *wm8731 = dev_get_drvdata(&spi->dev);
 677
 678        wm8731_unregister(wm8731);
 679
 680        return 0;
 681}
 682
 683static struct spi_driver wm8731_spi_driver = {
 684        .driver = {
 685                .name   = "wm8731",
 686                .bus    = &spi_bus_type,
 687                .owner  = THIS_MODULE,
 688        },
 689        .probe          = wm8731_spi_probe,
 690        .remove         = __devexit_p(wm8731_spi_remove),
 691};
 692#endif /* CONFIG_SPI_MASTER */
 693
 694#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
 695static __devinit int wm8731_i2c_probe(struct i2c_client *i2c,
 696                                      const struct i2c_device_id *id)
 697{
 698        struct wm8731_priv *wm8731;
 699        struct snd_soc_codec *codec;
 700
 701        wm8731 = kzalloc(sizeof(struct wm8731_priv), GFP_KERNEL);
 702        if (wm8731 == NULL)
 703                return -ENOMEM;
 704
 705        codec = &wm8731->codec;
 706        codec->hw_write = (hw_write_t)i2c_master_send;
 707
 708        i2c_set_clientdata(i2c, wm8731);
 709        codec->control_data = i2c;
 710
 711        codec->dev = &i2c->dev;
 712
 713        return wm8731_register(wm8731);
 714}
 715
 716static __devexit int wm8731_i2c_remove(struct i2c_client *client)
 717{
 718        struct wm8731_priv *wm8731 = i2c_get_clientdata(client);
 719        wm8731_unregister(wm8731);
 720        return 0;
 721}
 722
 723static const struct i2c_device_id wm8731_i2c_id[] = {
 724        { "wm8731", 0 },
 725        { }
 726};
 727MODULE_DEVICE_TABLE(i2c, wm8731_i2c_id);
 728
 729static struct i2c_driver wm8731_i2c_driver = {
 730        .driver = {
 731                .name = "WM8731 I2C Codec",
 732                .owner = THIS_MODULE,
 733        },
 734        .probe =    wm8731_i2c_probe,
 735        .remove =   __devexit_p(wm8731_i2c_remove),
 736        .id_table = wm8731_i2c_id,
 737};
 738#endif
 739
 740static int __init wm8731_modinit(void)
 741{
 742        int ret;
 743#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
 744        ret = i2c_add_driver(&wm8731_i2c_driver);
 745        if (ret != 0) {
 746                printk(KERN_ERR "Failed to register WM8731 I2C driver: %d\n",
 747                       ret);
 748        }
 749#endif
 750#if defined(CONFIG_SPI_MASTER)
 751        ret = spi_register_driver(&wm8731_spi_driver);
 752        if (ret != 0) {
 753                printk(KERN_ERR "Failed to register WM8731 SPI driver: %d\n",
 754                       ret);
 755        }
 756#endif
 757        return 0;
 758}
 759module_init(wm8731_modinit);
 760
 761static void __exit wm8731_exit(void)
 762{
 763#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
 764        i2c_del_driver(&wm8731_i2c_driver);
 765#endif
 766#if defined(CONFIG_SPI_MASTER)
 767        spi_unregister_driver(&wm8731_spi_driver);
 768#endif
 769}
 770module_exit(wm8731_exit);
 771
 772MODULE_DESCRIPTION("ASoC WM8731 driver");
 773MODULE_AUTHOR("Richard Purdie");
 774MODULE_LICENSE("GPL");
 775
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.