linux/sound/soc/s3c24xx/neo1973_wm8753.c
<<
>>
Prefs
   1/*
   2 * neo1973_wm8753.c  --  SoC audio for Neo1973
   3 *
   4 * Copyright 2007 Wolfson Microelectronics PLC.
   5 * Author: Graeme Gregory
   6 *         graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com
   7 *
   8 *  This program is free software; you can redistribute  it and/or modify it
   9 *  under  the terms of  the GNU General  Public License as published by the
  10 *  Free Software Foundation;  either version 2 of the  License, or (at your
  11 *  option) any later version.
  12 *
  13 */
  14
  15#include <linux/module.h>
  16#include <linux/moduleparam.h>
  17#include <linux/timer.h>
  18#include <linux/interrupt.h>
  19#include <linux/platform_device.h>
  20#include <linux/i2c.h>
  21#include <sound/core.h>
  22#include <sound/pcm.h>
  23#include <sound/soc.h>
  24#include <sound/soc-dapm.h>
  25#include <sound/tlv.h>
  26
  27#include <asm/mach-types.h>
  28#include <asm/hardware/scoop.h>
  29#include <mach/regs-clock.h>
  30#include <mach/regs-gpio.h>
  31#include <mach/hardware.h>
  32#include <plat/audio.h>
  33#include <linux/io.h>
  34#include <mach/spi-gpio.h>
  35
  36#include <plat/regs-iis.h>
  37
  38#include "../codecs/wm8753.h"
  39#include "lm4857.h"
  40#include "s3c24xx-pcm.h"
  41#include "s3c24xx-i2s.h"
  42
  43/* define the scenarios */
  44#define NEO_AUDIO_OFF                   0
  45#define NEO_GSM_CALL_AUDIO_HANDSET      1
  46#define NEO_GSM_CALL_AUDIO_HEADSET      2
  47#define NEO_GSM_CALL_AUDIO_BLUETOOTH    3
  48#define NEO_STEREO_TO_SPEAKERS          4
  49#define NEO_STEREO_TO_HEADPHONES        5
  50#define NEO_CAPTURE_HANDSET             6
  51#define NEO_CAPTURE_HEADSET             7
  52#define NEO_CAPTURE_BLUETOOTH           8
  53
  54static struct snd_soc_card neo1973;
  55static struct i2c_client *i2c;
  56
  57static int neo1973_hifi_hw_params(struct snd_pcm_substream *substream,
  58        struct snd_pcm_hw_params *params)
  59{
  60        struct snd_soc_pcm_runtime *rtd = substream->private_data;
  61        struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
  62        struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
  63        unsigned int pll_out = 0, bclk = 0;
  64        int ret = 0;
  65        unsigned long iis_clkrate;
  66
  67        pr_debug("Entered %s\n", __func__);
  68
  69        iis_clkrate = s3c24xx_i2s_get_clockrate();
  70
  71        switch (params_rate(params)) {
  72        case 8000:
  73        case 16000:
  74                pll_out = 12288000;
  75                break;
  76        case 48000:
  77                bclk = WM8753_BCLK_DIV_4;
  78                pll_out = 12288000;
  79                break;
  80        case 96000:
  81                bclk = WM8753_BCLK_DIV_2;
  82                pll_out = 12288000;
  83                break;
  84        case 11025:
  85                bclk = WM8753_BCLK_DIV_16;
  86                pll_out = 11289600;
  87                break;
  88        case 22050:
  89                bclk = WM8753_BCLK_DIV_8;
  90                pll_out = 11289600;
  91                break;
  92        case 44100:
  93                bclk = WM8753_BCLK_DIV_4;
  94                pll_out = 11289600;
  95                break;
  96        case 88200:
  97                bclk = WM8753_BCLK_DIV_2;
  98                pll_out = 11289600;
  99                break;
 100        }
 101
 102        /* set codec DAI configuration */
 103        ret = snd_soc_dai_set_fmt(codec_dai,
 104                SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
 105                SND_SOC_DAIFMT_CBM_CFM);
 106        if (ret < 0)
 107                return ret;
 108
 109        /* set cpu DAI configuration */
 110        ret = snd_soc_dai_set_fmt(cpu_dai,
 111                SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
 112                SND_SOC_DAIFMT_CBM_CFM);
 113        if (ret < 0)
 114                return ret;
 115
 116        /* set the codec system clock for DAC and ADC */
 117        ret = snd_soc_dai_set_sysclk(codec_dai, WM8753_MCLK, pll_out,
 118                SND_SOC_CLOCK_IN);
 119        if (ret < 0)
 120                return ret;
 121
 122        /* set MCLK division for sample rate */
 123        ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C24XX_DIV_MCLK,
 124                S3C2410_IISMOD_32FS);
 125        if (ret < 0)
 126                return ret;
 127
 128        /* set codec BCLK division for sample rate */
 129        ret = snd_soc_dai_set_clkdiv(codec_dai, WM8753_BCLKDIV, bclk);
 130        if (ret < 0)
 131                return ret;
 132
 133        /* set prescaler division for sample rate */
 134        ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C24XX_DIV_PRESCALER,
 135                S3C24XX_PRESCALE(4, 4));
 136        if (ret < 0)
 137                return ret;
 138
 139        /* codec PLL input is PCLK/4 */
 140        ret = snd_soc_dai_set_pll(codec_dai, WM8753_PLL1,
 141                iis_clkrate / 4, pll_out);
 142        if (ret < 0)
 143                return ret;
 144
 145        return 0;
 146}
 147
 148static int neo1973_hifi_hw_free(struct snd_pcm_substream *substream)
 149{
 150        struct snd_soc_pcm_runtime *rtd = substream->private_data;
 151        struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
 152
 153        pr_debug("Entered %s\n", __func__);
 154
 155        /* disable the PLL */
 156        return snd_soc_dai_set_pll(codec_dai, WM8753_PLL1, 0, 0);
 157}
 158
 159/*
 160 * Neo1973 WM8753 HiFi DAI opserations.
 161 */
 162static struct snd_soc_ops neo1973_hifi_ops = {
 163        .hw_params = neo1973_hifi_hw_params,
 164        .hw_free = neo1973_hifi_hw_free,
 165};
 166
 167static int neo1973_voice_hw_params(struct snd_pcm_substream *substream,
 168        struct snd_pcm_hw_params *params)
 169{
 170        struct snd_soc_pcm_runtime *rtd = substream->private_data;
 171        struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
 172        unsigned int pcmdiv = 0;
 173        int ret = 0;
 174        unsigned long iis_clkrate;
 175
 176        pr_debug("Entered %s\n", __func__);
 177
 178        iis_clkrate = s3c24xx_i2s_get_clockrate();
 179
 180        if (params_rate(params) != 8000)
 181                return -EINVAL;
 182        if (params_channels(params) != 1)
 183                return -EINVAL;
 184
 185        pcmdiv = WM8753_PCM_DIV_6; /* 2.048 MHz */
 186
 187        /* todo: gg check mode (DSP_B) against CSR datasheet */
 188        /* set codec DAI configuration */
 189        ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_DSP_B |
 190                SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
 191        if (ret < 0)
 192                return ret;
 193
 194        /* set the codec system clock for DAC and ADC */
 195        ret = snd_soc_dai_set_sysclk(codec_dai, WM8753_PCMCLK, 12288000,
 196                SND_SOC_CLOCK_IN);
 197        if (ret < 0)
 198                return ret;
 199
 200        /* set codec PCM division for sample rate */
 201        ret = snd_soc_dai_set_clkdiv(codec_dai, WM8753_PCMDIV, pcmdiv);
 202        if (ret < 0)
 203                return ret;
 204
 205        /* configue and enable PLL for 12.288MHz output */
 206        ret = snd_soc_dai_set_pll(codec_dai, WM8753_PLL2,
 207                iis_clkrate / 4, 12288000);
 208        if (ret < 0)
 209                return ret;
 210
 211        return 0;
 212}
 213
 214static int neo1973_voice_hw_free(struct snd_pcm_substream *substream)
 215{
 216        struct snd_soc_pcm_runtime *rtd = substream->private_data;
 217        struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
 218
 219        pr_debug("Entered %s\n", __func__);
 220
 221        /* disable the PLL */
 222        return snd_soc_dai_set_pll(codec_dai, WM8753_PLL2, 0, 0);
 223}
 224
 225static struct snd_soc_ops neo1973_voice_ops = {
 226        .hw_params = neo1973_voice_hw_params,
 227        .hw_free = neo1973_voice_hw_free,
 228};
 229
 230static int neo1973_scenario;
 231
 232static int neo1973_get_scenario(struct snd_kcontrol *kcontrol,
 233        struct snd_ctl_elem_value *ucontrol)
 234{
 235        ucontrol->value.integer.value[0] = neo1973_scenario;
 236        return 0;
 237}
 238
 239static int set_scenario_endpoints(struct snd_soc_codec *codec, int scenario)
 240{
 241        pr_debug("Entered %s\n", __func__);
 242
 243        switch (neo1973_scenario) {
 244        case NEO_AUDIO_OFF:
 245                snd_soc_dapm_disable_pin(codec, "Audio Out");
 246                snd_soc_dapm_disable_pin(codec, "GSM Line Out");
 247                snd_soc_dapm_disable_pin(codec, "GSM Line In");
 248                snd_soc_dapm_disable_pin(codec, "Headset Mic");
 249                snd_soc_dapm_disable_pin(codec, "Call Mic");
 250                break;
 251        case NEO_GSM_CALL_AUDIO_HANDSET:
 252                snd_soc_dapm_enable_pin(codec, "Audio Out");
 253                snd_soc_dapm_enable_pin(codec, "GSM Line Out");
 254                snd_soc_dapm_enable_pin(codec, "GSM Line In");
 255                snd_soc_dapm_disable_pin(codec, "Headset Mic");
 256                snd_soc_dapm_enable_pin(codec, "Call Mic");
 257                break;
 258        case NEO_GSM_CALL_AUDIO_HEADSET:
 259                snd_soc_dapm_enable_pin(codec, "Audio Out");
 260                snd_soc_dapm_enable_pin(codec, "GSM Line Out");
 261                snd_soc_dapm_enable_pin(codec, "GSM Line In");
 262                snd_soc_dapm_enable_pin(codec, "Headset Mic");
 263                snd_soc_dapm_disable_pin(codec, "Call Mic");
 264                break;
 265        case NEO_GSM_CALL_AUDIO_BLUETOOTH:
 266                snd_soc_dapm_disable_pin(codec, "Audio Out");
 267                snd_soc_dapm_enable_pin(codec, "GSM Line Out");
 268                snd_soc_dapm_enable_pin(codec, "GSM Line In");
 269                snd_soc_dapm_disable_pin(codec, "Headset Mic");
 270                snd_soc_dapm_disable_pin(codec, "Call Mic");
 271                break;
 272        case NEO_STEREO_TO_SPEAKERS:
 273                snd_soc_dapm_enable_pin(codec, "Audio Out");
 274                snd_soc_dapm_disable_pin(codec, "GSM Line Out");
 275                snd_soc_dapm_disable_pin(codec, "GSM Line In");
 276                snd_soc_dapm_disable_pin(codec, "Headset Mic");
 277                snd_soc_dapm_disable_pin(codec, "Call Mic");
 278                break;
 279        case NEO_STEREO_TO_HEADPHONES:
 280                snd_soc_dapm_enable_pin(codec, "Audio Out");
 281                snd_soc_dapm_disable_pin(codec, "GSM Line Out");
 282                snd_soc_dapm_disable_pin(codec, "GSM Line In");
 283                snd_soc_dapm_disable_pin(codec, "Headset Mic");
 284                snd_soc_dapm_disable_pin(codec, "Call Mic");
 285                break;
 286        case NEO_CAPTURE_HANDSET:
 287                snd_soc_dapm_disable_pin(codec, "Audio Out");
 288                snd_soc_dapm_disable_pin(codec, "GSM Line Out");
 289                snd_soc_dapm_disable_pin(codec, "GSM Line In");
 290                snd_soc_dapm_disable_pin(codec, "Headset Mic");
 291                snd_soc_dapm_enable_pin(codec, "Call Mic");
 292                break;
 293        case NEO_CAPTURE_HEADSET:
 294                snd_soc_dapm_disable_pin(codec, "Audio Out");
 295                snd_soc_dapm_disable_pin(codec, "GSM Line Out");
 296                snd_soc_dapm_disable_pin(codec, "GSM Line In");
 297                snd_soc_dapm_enable_pin(codec, "Headset Mic");
 298                snd_soc_dapm_disable_pin(codec, "Call Mic");
 299                break;
 300        case NEO_CAPTURE_BLUETOOTH:
 301                snd_soc_dapm_disable_pin(codec, "Audio Out");
 302                snd_soc_dapm_disable_pin(codec, "GSM Line Out");
 303                snd_soc_dapm_disable_pin(codec, "GSM Line In");
 304                snd_soc_dapm_disable_pin(codec, "Headset Mic");
 305                snd_soc_dapm_disable_pin(codec, "Call Mic");
 306                break;
 307        default:
 308                snd_soc_dapm_disable_pin(codec, "Audio Out");
 309                snd_soc_dapm_disable_pin(codec, "GSM Line Out");
 310                snd_soc_dapm_disable_pin(codec, "GSM Line In");
 311                snd_soc_dapm_disable_pin(codec, "Headset Mic");
 312                snd_soc_dapm_disable_pin(codec, "Call Mic");
 313        }
 314
 315        snd_soc_dapm_sync(codec);
 316
 317        return 0;
 318}
 319
 320static int neo1973_set_scenario(struct snd_kcontrol *kcontrol,
 321        struct snd_ctl_elem_value *ucontrol)
 322{
 323        struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
 324
 325        pr_debug("Entered %s\n", __func__);
 326
 327        if (neo1973_scenario == ucontrol->value.integer.value[0])
 328                return 0;
 329
 330        neo1973_scenario = ucontrol->value.integer.value[0];
 331        set_scenario_endpoints(codec, neo1973_scenario);
 332        return 1;
 333}
 334
 335static u8 lm4857_regs[4] = {0x00, 0x40, 0x80, 0xC0};
 336
 337static void lm4857_write_regs(void)
 338{
 339        pr_debug("Entered %s\n", __func__);
 340
 341        if (i2c_master_send(i2c, lm4857_regs, 4) != 4)
 342                printk(KERN_ERR "lm4857: i2c write failed\n");
 343}
 344
 345static int lm4857_get_reg(struct snd_kcontrol *kcontrol,
 346        struct snd_ctl_elem_value *ucontrol)
 347{
 348        struct soc_mixer_control *mc =
 349                (struct soc_mixer_control *)kcontrol->private_value;
 350        int reg = mc->reg;
 351        int shift = mc->shift;
 352        int mask = mc->max;
 353
 354        pr_debug("Entered %s\n", __func__);
 355
 356        ucontrol->value.integer.value[0] = (lm4857_regs[reg] >> shift) & mask;
 357        return 0;
 358}
 359
 360static int lm4857_set_reg(struct snd_kcontrol *kcontrol,
 361        struct snd_ctl_elem_value *ucontrol)
 362{
 363        struct soc_mixer_control *mc =
 364                (struct soc_mixer_control *)kcontrol->private_value;
 365        int reg = mc->reg;
 366        int shift = mc->shift;
 367        int mask = mc->max;
 368
 369        if (((lm4857_regs[reg] >> shift) & mask) ==
 370                ucontrol->value.integer.value[0])
 371                return 0;
 372
 373        lm4857_regs[reg] &= ~(mask << shift);
 374        lm4857_regs[reg] |= ucontrol->value.integer.value[0] << shift;
 375        lm4857_write_regs();
 376        return 1;
 377}
 378
 379static int lm4857_get_mode(struct snd_kcontrol *kcontrol,
 380        struct snd_ctl_elem_value *ucontrol)
 381{
 382        u8 value = lm4857_regs[LM4857_CTRL] & 0x0F;
 383
 384        pr_debug("Entered %s\n", __func__);
 385
 386        if (value)
 387                value -= 5;
 388
 389        ucontrol->value.integer.value[0] = value;
 390        return 0;
 391}
 392
 393static int lm4857_set_mode(struct snd_kcontrol *kcontrol,
 394        struct snd_ctl_elem_value *ucontrol)
 395{
 396        u8 value = ucontrol->value.integer.value[0];
 397
 398        pr_debug("Entered %s\n", __func__);
 399
 400        if (value)
 401                value += 5;
 402
 403        if ((lm4857_regs[LM4857_CTRL] & 0x0F) == value)
 404                return 0;
 405
 406        lm4857_regs[LM4857_CTRL] &= 0xF0;
 407        lm4857_regs[LM4857_CTRL] |= value;
 408        lm4857_write_regs();
 409        return 1;
 410}
 411
 412static const struct snd_soc_dapm_widget wm8753_dapm_widgets[] = {
 413        SND_SOC_DAPM_LINE("Audio Out", NULL),
 414        SND_SOC_DAPM_LINE("GSM Line Out", NULL),
 415        SND_SOC_DAPM_LINE("GSM Line In", NULL),
 416        SND_SOC_DAPM_MIC("Headset Mic", NULL),
 417        SND_SOC_DAPM_MIC("Call Mic", NULL),
 418};
 419
 420
 421static const struct snd_soc_dapm_route dapm_routes[] = {
 422
 423        /* Connections to the lm4857 amp */
 424        {"Audio Out", NULL, "LOUT1"},
 425        {"Audio Out", NULL, "ROUT1"},
 426
 427        /* Connections to the GSM Module */
 428        {"GSM Line Out", NULL, "MONO1"},
 429        {"GSM Line Out", NULL, "MONO2"},
 430        {"RXP", NULL, "GSM Line In"},
 431        {"RXN", NULL, "GSM Line In"},
 432
 433        /* Connections to Headset */
 434        {"MIC1", NULL, "Mic Bias"},
 435        {"Mic Bias", NULL, "Headset Mic"},
 436
 437        /* Call Mic */
 438        {"MIC2", NULL, "Mic Bias"},
 439        {"MIC2N", NULL, "Mic Bias"},
 440        {"Mic Bias", NULL, "Call Mic"},
 441
 442        /* Connect the ALC pins */
 443        {"ACIN", NULL, "ACOP"},
 444};
 445
 446static const char *lm4857_mode[] = {
 447        "Off",
 448        "Call Speaker",
 449        "Stereo Speakers",
 450        "Stereo Speakers + Headphones",
 451        "Headphones"
 452};
 453
 454static const struct soc_enum lm4857_mode_enum[] = {
 455        SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(lm4857_mode), lm4857_mode),
 456};
 457
 458static const char *neo_scenarios[] = {
 459        "Off",
 460        "GSM Handset",
 461        "GSM Headset",
 462        "GSM Bluetooth",
 463        "Speakers",
 464        "Headphones",
 465        "Capture Handset",
 466        "Capture Headset",
 467        "Capture Bluetooth"
 468};
 469
 470static const struct soc_enum neo_scenario_enum[] = {
 471        SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(neo_scenarios), neo_scenarios),
 472};
 473
 474static const DECLARE_TLV_DB_SCALE(stereo_tlv, -4050, 150, 0);
 475static const DECLARE_TLV_DB_SCALE(mono_tlv, -3450, 150, 0);
 476
 477static const struct snd_kcontrol_new wm8753_neo1973_controls[] = {
 478        SOC_SINGLE_EXT_TLV("Amp Left Playback Volume", LM4857_LVOL, 0, 31, 0,
 479                lm4857_get_reg, lm4857_set_reg, stereo_tlv),
 480        SOC_SINGLE_EXT_TLV("Amp Right Playback Volume", LM4857_RVOL, 0, 31, 0,
 481                lm4857_get_reg, lm4857_set_reg, stereo_tlv),
 482        SOC_SINGLE_EXT_TLV("Amp Mono Playback Volume", LM4857_MVOL, 0, 31, 0,
 483                lm4857_get_reg, lm4857_set_reg, mono_tlv),
 484        SOC_ENUM_EXT("Amp Mode", lm4857_mode_enum[0],
 485                lm4857_get_mode, lm4857_set_mode),
 486        SOC_ENUM_EXT("Neo Mode", neo_scenario_enum[0],
 487                neo1973_get_scenario, neo1973_set_scenario),
 488        SOC_SINGLE_EXT("Amp Spk 3D Playback Switch", LM4857_LVOL, 5, 1, 0,
 489                lm4857_get_reg, lm4857_set_reg),
 490        SOC_SINGLE_EXT("Amp HP 3d Playback Switch", LM4857_RVOL, 5, 1, 0,
 491                lm4857_get_reg, lm4857_set_reg),
 492        SOC_SINGLE_EXT("Amp Fast Wakeup Playback Switch", LM4857_CTRL, 5, 1, 0,
 493                lm4857_get_reg, lm4857_set_reg),
 494        SOC_SINGLE_EXT("Amp Earpiece 6dB Playback Switch", LM4857_CTRL, 4, 1, 0,
 495                lm4857_get_reg, lm4857_set_reg),
 496};
 497
 498/*
 499 * This is an example machine initialisation for a wm8753 connected to a
 500 * neo1973 II. It is missing logic to detect hp/mic insertions and logic
 501 * to re-route the audio in such an event.
 502 */
 503static int neo1973_wm8753_init(struct snd_soc_codec *codec)
 504{
 505        int err;
 506
 507        pr_debug("Entered %s\n", __func__);
 508
 509        /* set up NC codec pins */
 510        snd_soc_dapm_nc_pin(codec, "LOUT2");
 511        snd_soc_dapm_nc_pin(codec, "ROUT2");
 512        snd_soc_dapm_nc_pin(codec, "OUT3");
 513        snd_soc_dapm_nc_pin(codec, "OUT4");
 514        snd_soc_dapm_nc_pin(codec, "LINE1");
 515        snd_soc_dapm_nc_pin(codec, "LINE2");
 516
 517        /* Add neo1973 specific widgets */
 518        snd_soc_dapm_new_controls(codec, wm8753_dapm_widgets,
 519                                  ARRAY_SIZE(wm8753_dapm_widgets));
 520
 521        /* set endpoints to default mode */
 522        set_scenario_endpoints(codec, NEO_AUDIO_OFF);
 523
 524        /* add neo1973 specific controls */
 525        err = snd_soc_add_controls(codec, wm8753_neo1973_controls,
 526                                ARRAY_SIZE(8753_neo1973_controls));
 527        if (err < 0)
 528                return err;
 529
 530        /* set up neo1973 specific audio routes */
 531        err = snd_soc_dapm_add_routes(codec, dapm_routes,
 532                                      ARRAY_SIZE(dapm_routes));
 533
 534        snd_soc_dapm_sync(codec);
 535        return 0;
 536}
 537
 538/*
 539 * BT Codec DAI
 540 */
 541static struct snd_soc_dai bt_dai = {
 542        .name = "Bluetooth",
 543        .id = 0,
 544        .playback = {
 545                .channels_min = 1,
 546                .channels_max = 1,
 547                .rates = SNDRV_PCM_RATE_8000,
 548                .formats = SNDRV_PCM_FMTBIT_S16_LE,},
 549        .capture = {
 550                .channels_min = 1,
 551                .channels_max = 1,
 552                .rates = SNDRV_PCM_RATE_8000,
 553                .formats = SNDRV_PCM_FMTBIT_S16_LE,},
 554};
 555
 556static struct snd_soc_dai_link neo1973_dai[] = {
 557{ /* Hifi Playback - for similatious use with voice below */
 558        .name = "WM8753",
 559        .stream_name = "WM8753 HiFi",
 560        .cpu_dai = &s3c24xx_i2s_dai,
 561        .codec_dai = &wm8753_dai[WM8753_DAI_HIFI],
 562        .init = neo1973_wm8753_init,
 563        .ops = &neo1973_hifi_ops,
 564},
 565{ /* Voice via BT */
 566        .name = "Bluetooth",
 567        .stream_name = "Voice",
 568        .cpu_dai = &bt_dai,
 569        .codec_dai = &wm8753_dai[WM8753_DAI_VOICE],
 570        .ops = &neo1973_voice_ops,
 571},
 572};
 573
 574static struct snd_soc_card neo1973 = {
 575        .name = "neo1973",
 576        .platform = &s3c24xx_soc_platform,
 577        .dai_link = neo1973_dai,
 578        .num_links = ARRAY_SIZE(neo1973_dai),
 579};
 580
 581static struct snd_soc_device neo1973_snd_devdata = {
 582        .card = &neo1973,
 583        .codec_dev = &soc_codec_dev_wm8753,
 584};
 585
 586static int lm4857_i2c_probe(struct i2c_client *client,
 587                            const struct i2c_device_id *id)
 588{
 589        pr_debug("Entered %s\n", __func__);
 590
 591        i2c = client;
 592
 593        lm4857_write_regs();
 594        return 0;
 595}
 596
 597static int lm4857_i2c_remove(struct i2c_client *client)
 598{
 599        pr_debug("Entered %s\n", __func__);
 600
 601        i2c = NULL;
 602
 603        return 0;
 604}
 605
 606static u8 lm4857_state;
 607
 608static int lm4857_suspend(struct i2c_client *dev, pm_message_t state)
 609{
 610        pr_debug("Entered %s\n", __func__);
 611
 612        dev_dbg(&dev->dev, "lm4857_suspend\n");
 613        lm4857_state = lm4857_regs[LM4857_CTRL] & 0xf;
 614        if (lm4857_state) {
 615                lm4857_regs[LM4857_CTRL] &= 0xf0;
 616                lm4857_write_regs();
 617        }
 618        return 0;
 619}
 620
 621static int lm4857_resume(struct i2c_client *dev)
 622{
 623        pr_debug("Entered %s\n", __func__);
 624
 625        if (lm4857_state) {
 626                lm4857_regs[LM4857_CTRL] |= (lm4857_state & 0x0f);
 627                lm4857_write_regs();
 628        }
 629        return 0;
 630}
 631
 632static void lm4857_shutdown(struct i2c_client *dev)
 633{
 634        pr_debug("Entered %s\n", __func__);
 635
 636        dev_dbg(&dev->dev, "lm4857_shutdown\n");
 637        lm4857_regs[LM4857_CTRL] &= 0xf0;
 638        lm4857_write_regs();
 639}
 640
 641static const struct i2c_device_id lm4857_i2c_id[] = {
 642        { "neo1973_lm4857", 0 },
 643        { }
 644};
 645
 646static struct i2c_driver lm4857_i2c_driver = {
 647        .driver = {
 648                .name = "LM4857 I2C Amp",
 649                .owner = THIS_MODULE,
 650        },
 651        .suspend =        lm4857_suspend,
 652        .resume =         lm4857_resume,
 653        .shutdown =       lm4857_shutdown,
 654        .probe =          lm4857_i2c_probe,
 655        .remove =         lm4857_i2c_remove,
 656        .id_table =       lm4857_i2c_id,
 657};
 658
 659static struct platform_device *neo1973_snd_device;
 660
 661static int __init neo1973_init(void)
 662{
 663        int ret;
 664
 665        pr_debug("Entered %s\n", __func__);
 666
 667        if (!machine_is_neo1973_gta01()) {
 668                printk(KERN_INFO
 669                        "Only GTA01 hardware supported by ASoC driver\n");
 670                return -ENODEV;
 671        }
 672
 673        neo1973_snd_device = platform_device_alloc("soc-audio", -1);
 674        if (!neo1973_snd_device)
 675                return -ENOMEM;
 676
 677        platform_set_drvdata(neo1973_snd_device, &neo1973_snd_devdata);
 678        neo1973_snd_devdata.dev = &neo1973_snd_device->dev;
 679        ret = platform_device_add(neo1973_snd_device);
 680
 681        if (ret) {
 682                platform_device_put(neo1973_snd_device);
 683                return ret;
 684        }
 685
 686        ret = i2c_add_driver(&lm4857_i2c_driver);
 687
 688        if (ret != 0)
 689                platform_device_unregister(neo1973_snd_device);
 690
 691        return ret;
 692}
 693
 694static void __exit neo1973_exit(void)
 695{
 696        pr_debug("Entered %s\n", __func__);
 697
 698        i2c_del_driver(&lm4857_i2c_driver);
 699        platform_device_unregister(neo1973_snd_device);
 700}
 701
 702module_init(neo1973_init);
 703module_exit(neo1973_exit);
 704
 705/* Module information */
 706MODULE_AUTHOR("Graeme Gregory, graeme@openmoko.org, www.openmoko.org");
 707MODULE_DESCRIPTION("ALSA SoC WM8753 Neo1973");
 708MODULE_LICENSE("GPL");
 709