linux/sound/soc/samsung/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/tlv.h>
  25
  26#include <asm/mach-types.h>
  27#include <asm/hardware/scoop.h>
  28#include <mach/regs-clock.h>
  29#include <mach/regs-gpio.h>
  30#include <mach/hardware.h>
  31#include <linux/io.h>
  32#include <mach/spi-gpio.h>
  33
  34#include <plat/regs-iis.h>
  35
  36#include "../codecs/wm8753.h"
  37#include "lm4857.h"
  38#include "dma.h"
  39#include "s3c24xx-i2s.h"
  40
  41/* define the scenarios */
  42#define NEO_AUDIO_OFF                   0
  43#define NEO_GSM_CALL_AUDIO_HANDSET      1
  44#define NEO_GSM_CALL_AUDIO_HEADSET      2
  45#define NEO_GSM_CALL_AUDIO_BLUETOOTH    3
  46#define NEO_STEREO_TO_SPEAKERS          4
  47#define NEO_STEREO_TO_HEADPHONES        5
  48#define NEO_CAPTURE_HANDSET             6
  49#define NEO_CAPTURE_HEADSET             7
  50#define NEO_CAPTURE_BLUETOOTH           8
  51
  52static struct snd_soc_card neo1973;
  53static struct i2c_client *i2c;
  54
  55static int neo1973_hifi_hw_params(struct snd_pcm_substream *substream,
  56        struct snd_pcm_hw_params *params)
  57{
  58        struct snd_soc_pcm_runtime *rtd = substream->private_data;
  59        struct snd_soc_dai *codec_dai = rtd->codec_dai;
  60        struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
  61        unsigned int pll_out = 0, bclk = 0;
  62        int ret = 0;
  63        unsigned long iis_clkrate;
  64
  65        pr_debug("Entered %s\n", __func__);
  66
  67        iis_clkrate = s3c24xx_i2s_get_clockrate();
  68
  69        switch (params_rate(params)) {
  70        case 8000:
  71        case 16000:
  72                pll_out = 12288000;
  73                break;
  74        case 48000:
  75                bclk = WM8753_BCLK_DIV_4;
  76                pll_out = 12288000;
  77                break;
  78        case 96000:
  79                bclk = WM8753_BCLK_DIV_2;
  80                pll_out = 12288000;
  81                break;
  82        case 11025:
  83                bclk = WM8753_BCLK_DIV_16;
  84                pll_out = 11289600;
  85                break;
  86        case 22050:
  87                bclk = WM8753_BCLK_DIV_8;
  88                pll_out = 11289600;
  89                break;
  90        case 44100:
  91                bclk = WM8753_BCLK_DIV_4;
  92                pll_out = 11289600;
  93                break;
  94        case 88200:
  95                bclk = WM8753_BCLK_DIV_2;
  96                pll_out = 11289600;
  97                break;
  98        }
  99
 100        /* set codec DAI configuration */
 101        ret = snd_soc_dai_set_fmt(codec_dai,
 102                SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
 103                SND_SOC_DAIFMT_CBM_CFM);
 104        if (ret < 0)
 105                return ret;
 106
 107        /* set cpu DAI configuration */
 108        ret = snd_soc_dai_set_fmt(cpu_dai,
 109                SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
 110                SND_SOC_DAIFMT_CBM_CFM);
 111        if (ret < 0)
 112                return ret;
 113
 114        /* set the codec system clock for DAC and ADC */
 115        ret = snd_soc_dai_set_sysclk(codec_dai, WM8753_MCLK, pll_out,
 116                SND_SOC_CLOCK_IN);
 117        if (ret < 0)
 118                return ret;
 119
 120        /* set MCLK division for sample rate */
 121        ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C24XX_DIV_MCLK,
 122                S3C2410_IISMOD_32FS);
 123        if (ret < 0)
 124                return ret;
 125
 126        /* set codec BCLK division for sample rate */
 127        ret = snd_soc_dai_set_clkdiv(codec_dai, WM8753_BCLKDIV, bclk);
 128        if (ret < 0)
 129                return ret;
 130
 131        /* set prescaler division for sample rate */
 132        ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C24XX_DIV_PRESCALER,
 133                S3C24XX_PRESCALE(4, 4));
 134        if (ret < 0)
 135                return ret;
 136
 137        /* codec PLL input is PCLK/4 */
 138        ret = snd_soc_dai_set_pll(codec_dai, WM8753_PLL1, 0,
 139                iis_clkrate / 4, pll_out);
 140        if (ret < 0)
 141                return ret;
 142
 143        return 0;
 144}
 145
 146static int neo1973_hifi_hw_free(struct snd_pcm_substream *substream)
 147{
 148        struct snd_soc_pcm_runtime *rtd = substream->private_data;
 149        struct snd_soc_dai *codec_dai = rtd->codec_dai;
 150
 151        pr_debug("Entered %s\n", __func__);
 152
 153        /* disable the PLL */
 154        return snd_soc_dai_set_pll(codec_dai, WM8753_PLL1, 0, 0, 0);
 155}
 156
 157/*
 158 * Neo1973 WM8753 HiFi DAI opserations.
 159 */
 160static struct snd_soc_ops neo1973_hifi_ops = {
 161        .hw_params = neo1973_hifi_hw_params,
 162        .hw_free = neo1973_hifi_hw_free,
 163};
 164
 165static int neo1973_voice_hw_params(struct snd_pcm_substream *substream,
 166        struct snd_pcm_hw_params *params)
 167{
 168        struct snd_soc_pcm_runtime *rtd = substream->private_data;
 169        struct snd_soc_dai *codec_dai = rtd->codec_dai;
 170        unsigned int pcmdiv = 0;
 171        int ret = 0;
 172        unsigned long iis_clkrate;
 173
 174        pr_debug("Entered %s\n", __func__);
 175
 176        iis_clkrate = s3c24xx_i2s_get_clockrate();
 177
 178        if (params_rate(params) != 8000)
 179                return -EINVAL;
 180        if (params_channels(params) != 1)
 181                return -EINVAL;
 182
 183        pcmdiv = WM8753_PCM_DIV_6; /* 2.048 MHz */
 184
 185        /* todo: gg check mode (DSP_B) against CSR datasheet */
 186        /* set codec DAI configuration */
 187        ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_DSP_B |
 188                SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
 189        if (ret < 0)
 190                return ret;
 191
 192        /* set the codec system clock for DAC and ADC */
 193        ret = snd_soc_dai_set_sysclk(codec_dai, WM8753_PCMCLK, 12288000,
 194                SND_SOC_CLOCK_IN);
 195        if (ret < 0)
 196                return ret;
 197
 198        /* set codec PCM division for sample rate */
 199        ret = snd_soc_dai_set_clkdiv(codec_dai, WM8753_PCMDIV, pcmdiv);
 200        if (ret < 0)
 201                return ret;
 202
 203        /* configure and enable PLL for 12.288MHz output */
 204        ret = snd_soc_dai_set_pll(codec_dai, WM8753_PLL2, 0,
 205                iis_clkrate / 4, 12288000);
 206        if (ret < 0)
 207                return ret;
 208
 209        return 0;
 210}
 211
 212static int neo1973_voice_hw_free(struct snd_pcm_substream *substream)
 213{
 214        struct snd_soc_pcm_runtime *rtd = substream->private_data;
 215        struct snd_soc_dai *codec_dai = rtd->codec_dai;
 216
 217        pr_debug("Entered %s\n", __func__);
 218
 219        /* disable the PLL */
 220        return snd_soc_dai_set_pll(codec_dai, WM8753_PLL2, 0, 0, 0);
 221}
 222
 223static struct snd_soc_ops neo1973_voice_ops = {
 224        .hw_params = neo1973_voice_hw_params,
 225        .hw_free = neo1973_voice_hw_free,
 226};
 227
 228static int neo1973_scenario;
 229
 230static int neo1973_get_scenario(struct snd_kcontrol *kcontrol,
 231        struct snd_ctl_elem_value *ucontrol)
 232{
 233        ucontrol->value.integer.value[0] = neo1973_scenario;
 234        return 0;
 235}
 236
 237static int set_scenario_endpoints(struct snd_soc_codec *codec, int scenario)
 238{
 239        struct snd_soc_dapm_context *dapm = &codec->dapm;
 240
 241        pr_debug("Entered %s\n", __func__);
 242
 243        switch (neo1973_scenario) {
 244        case NEO_AUDIO_OFF:
 245                snd_soc_dapm_disable_pin(dapm, "Audio Out");
 246                snd_soc_dapm_disable_pin(dapm, "GSM Line Out");
 247                snd_soc_dapm_disable_pin(dapm, "GSM Line In");
 248                snd_soc_dapm_disable_pin(dapm, "Headset Mic");
 249                snd_soc_dapm_disable_pin(dapm, "Call Mic");
 250                break;
 251        case NEO_GSM_CALL_AUDIO_HANDSET:
 252                snd_soc_dapm_enable_pin(dapm, "Audio Out");
 253                snd_soc_dapm_enable_pin(dapm, "GSM Line Out");
 254                snd_soc_dapm_enable_pin(dapm, "GSM Line In");
 255                snd_soc_dapm_disable_pin(dapm, "Headset Mic");
 256                snd_soc_dapm_enable_pin(dapm, "Call Mic");
 257                break;
 258        case NEO_GSM_CALL_AUDIO_HEADSET:
 259                snd_soc_dapm_enable_pin(dapm, "Audio Out");
 260                snd_soc_dapm_enable_pin(dapm, "GSM Line Out");
 261                snd_soc_dapm_enable_pin(dapm, "GSM Line In");
 262                snd_soc_dapm_enable_pin(dapm, "Headset Mic");
 263                snd_soc_dapm_disable_pin(dapm, "Call Mic");
 264                break;
 265        case NEO_GSM_CALL_AUDIO_BLUETOOTH:
 266                snd_soc_dapm_disable_pin(dapm, "Audio Out");
 267                snd_soc_dapm_enable_pin(dapm, "GSM Line Out");
 268                snd_soc_dapm_enable_pin(dapm, "GSM Line In");
 269                snd_soc_dapm_disable_pin(dapm, "Headset Mic");
 270                snd_soc_dapm_disable_pin(dapm, "Call Mic");
 271                break;
 272        case NEO_STEREO_TO_SPEAKERS:
 273                snd_soc_dapm_enable_pin(dapm, "Audio Out");
 274                snd_soc_dapm_disable_pin(dapm, "GSM Line Out");
 275                snd_soc_dapm_disable_pin(dapm, "GSM Line In");
 276                snd_soc_dapm_disable_pin(dapm, "Headset Mic");
 277                snd_soc_dapm_disable_pin(dapm, "Call Mic");
 278                break;
 279        case NEO_STEREO_TO_HEADPHONES:
 280                snd_soc_dapm_enable_pin(dapm, "Audio Out");
 281                snd_soc_dapm_disable_pin(dapm, "GSM Line Out");
 282                snd_soc_dapm_disable_pin(dapm, "GSM Line In");
 283                snd_soc_dapm_disable_pin(dapm, "Headset Mic");
 284                snd_soc_dapm_disable_pin(dapm, "Call Mic");
 285                break;
 286        case NEO_CAPTURE_HANDSET:
 287                snd_soc_dapm_disable_pin(dapm, "Audio Out");
 288                snd_soc_dapm_disable_pin(dapm, "GSM Line Out");
 289                snd_soc_dapm_disable_pin(dapm, "GSM Line In");
 290                snd_soc_dapm_disable_pin(dapm, "Headset Mic");
 291                snd_soc_dapm_enable_pin(dapm, "Call Mic");
 292                break;
 293        case NEO_CAPTURE_HEADSET:
 294                snd_soc_dapm_disable_pin(dapm, "Audio Out");
 295                snd_soc_dapm_disable_pin(dapm, "GSM Line Out");
 296                snd_soc_dapm_disable_pin(dapm, "GSM Line In");
 297                snd_soc_dapm_enable_pin(dapm, "Headset Mic");
 298                snd_soc_dapm_disable_pin(dapm, "Call Mic");
 299                break;
 300        case NEO_CAPTURE_BLUETOOTH:
 301                snd_soc_dapm_disable_pin(dapm, "Audio Out");
 302                snd_soc_dapm_disable_pin(dapm, "GSM Line Out");
 303                snd_soc_dapm_disable_pin(dapm, "GSM Line In");
 304                snd_soc_dapm_disable_pin(dapm, "Headset Mic");
 305                snd_soc_dapm_disable_pin(dapm, "Call Mic");
 306                break;
 307        default:
 308                snd_soc_dapm_disable_pin(dapm, "Audio Out");
 309                snd_soc_dapm_disable_pin(dapm, "GSM Line Out");
 310                snd_soc_dapm_disable_pin(dapm, "GSM Line In");
 311                snd_soc_dapm_disable_pin(dapm, "Headset Mic");
 312                snd_soc_dapm_disable_pin(dapm, "Call Mic");
 313        }
 314
 315        snd_soc_dapm_sync(dapm);
 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_pcm_runtime *rtd)
 504{
 505        struct snd_soc_codec *codec = rtd->codec;
 506        struct snd_soc_dapm_context *dapm = &codec->dapm;
 507        int err;
 508
 509        pr_debug("Entered %s\n", __func__);
 510
 511        /* set up NC codec pins */
 512        snd_soc_dapm_nc_pin(dapm, "LOUT2");
 513        snd_soc_dapm_nc_pin(dapm, "ROUT2");
 514        snd_soc_dapm_nc_pin(dapm, "OUT3");
 515        snd_soc_dapm_nc_pin(dapm, "OUT4");
 516        snd_soc_dapm_nc_pin(dapm, "LINE1");
 517        snd_soc_dapm_nc_pin(dapm, "LINE2");
 518
 519        /* Add neo1973 specific widgets */
 520        snd_soc_dapm_new_controls(dapm, wm8753_dapm_widgets,
 521                                  ARRAY_SIZE(wm8753_dapm_widgets));
 522
 523        /* set endpoints to default mode */
 524        set_scenario_endpoints(codec, NEO_AUDIO_OFF);
 525
 526        /* add neo1973 specific controls */
 527        err = snd_soc_add_controls(codec, wm8753_neo1973_controls,
 528                                ARRAY_SIZE(8753_neo1973_controls));
 529        if (err < 0)
 530                return err;
 531
 532        /* set up neo1973 specific audio routes */
 533        err = snd_soc_dapm_add_routes(dapm, dapm_routes,
 534                                      ARRAY_SIZE(dapm_routes));
 535
 536        snd_soc_dapm_sync(dapm);
 537        return 0;
 538}
 539
 540/*
 541 * BT Codec DAI
 542 */
 543static struct snd_soc_dai bt_dai = {
 544        .name = "bluetooth-dai",
 545        .playback = {
 546                .channels_min = 1,
 547                .channels_max = 1,
 548                .rates = SNDRV_PCM_RATE_8000,
 549                .formats = SNDRV_PCM_FMTBIT_S16_LE,},
 550        .capture = {
 551                .channels_min = 1,
 552                .channels_max = 1,
 553                .rates = SNDRV_PCM_RATE_8000,
 554                .formats = SNDRV_PCM_FMTBIT_S16_LE,},
 555};
 556
 557static struct snd_soc_dai_link neo1973_dai[] = {
 558{ /* Hifi Playback - for similatious use with voice below */
 559        .name = "WM8753",
 560        .stream_name = "WM8753 HiFi",
 561        .platform_name = "samsung-audio",
 562        .cpu_dai_name = "s3c24xx-iis",
 563        .codec_dai_name = "wm8753-hifi",
 564        .codec_name = "wm8753-codec.0-001a",
 565        .init = neo1973_wm8753_init,
 566        .ops = &neo1973_hifi_ops,
 567},
 568{ /* Voice via BT */
 569        .name = "Bluetooth",
 570        .stream_name = "Voice",
 571        .platform_name = "samsung-audio",
 572        .cpu_dai_name = "bluetooth-dai",
 573        .codec_dai_name = "wm8753-voice",
 574        .codec_name = "wm8753-codec.0-001a",
 575        .ops = &neo1973_voice_ops,
 576},
 577};
 578
 579static struct snd_soc_card neo1973 = {
 580        .name = "neo1973",
 581        .dai_link = neo1973_dai,
 582        .num_links = ARRAY_SIZE(neo1973_dai),
 583};
 584
 585static int lm4857_i2c_probe(struct i2c_client *client,
 586                            const struct i2c_device_id *id)
 587{
 588        pr_debug("Entered %s\n", __func__);
 589
 590        i2c = client;
 591
 592        lm4857_write_regs();
 593        return 0;
 594}
 595
 596static int lm4857_i2c_remove(struct i2c_client *client)
 597{
 598        pr_debug("Entered %s\n", __func__);
 599
 600        i2c = NULL;
 601
 602        return 0;
 603}
 604
 605static u8 lm4857_state;
 606
 607static int lm4857_suspend(struct i2c_client *dev, pm_message_t state)
 608{
 609        pr_debug("Entered %s\n", __func__);
 610
 611        dev_dbg(&dev->dev, "lm4857_suspend\n");
 612        lm4857_state = lm4857_regs[LM4857_CTRL] & 0xf;
 613        if (lm4857_state) {
 614                lm4857_regs[LM4857_CTRL] &= 0xf0;
 615                lm4857_write_regs();
 616        }
 617        return 0;
 618}
 619
 620static int lm4857_resume(struct i2c_client *dev)
 621{
 622        pr_debug("Entered %s\n", __func__);
 623
 624        if (lm4857_state) {
 625                lm4857_regs[LM4857_CTRL] |= (lm4857_state & 0x0f);
 626                lm4857_write_regs();
 627        }
 628        return 0;
 629}
 630
 631static void lm4857_shutdown(struct i2c_client *dev)
 632{
 633        pr_debug("Entered %s\n", __func__);
 634
 635        dev_dbg(&dev->dev, "lm4857_shutdown\n");
 636        lm4857_regs[LM4857_CTRL] &= 0xf0;
 637        lm4857_write_regs();
 638}
 639
 640static const struct i2c_device_id lm4857_i2c_id[] = {
 641        { "neo1973_lm4857", 0 },
 642        { }
 643};
 644
 645static struct i2c_driver lm4857_i2c_driver = {
 646        .driver = {
 647                .name = "LM4857 I2C Amp",
 648                .owner = THIS_MODULE,
 649        },
 650        .suspend =        lm4857_suspend,
 651        .resume =         lm4857_resume,
 652        .shutdown =       lm4857_shutdown,
 653        .probe =          lm4857_i2c_probe,
 654        .remove =         lm4857_i2c_remove,
 655        .id_table =       lm4857_i2c_id,
 656};
 657
 658static struct platform_device *neo1973_snd_device;
 659
 660static int __init neo1973_init(void)
 661{
 662        int ret;
 663
 664        pr_debug("Entered %s\n", __func__);
 665
 666        if (!machine_is_neo1973_gta01()) {
 667                printk(KERN_INFO
 668                        "Only GTA01 hardware supported by ASoC driver\n");
 669                return -ENODEV;
 670        }
 671
 672        neo1973_snd_device = platform_device_alloc("soc-audio", -1);
 673        if (!neo1973_snd_device)
 674                return -ENOMEM;
 675
 676        platform_set_drvdata(neo1973_snd_device, &neo1973);
 677        ret = platform_device_add(neo1973_snd_device);
 678
 679        if (ret) {
 680                platform_device_put(neo1973_snd_device);
 681                return ret;
 682        }
 683
 684        ret = i2c_add_driver(&lm4857_i2c_driver);
 685
 686        if (ret != 0)
 687                platform_device_unregister(neo1973_snd_device);
 688
 689        return ret;
 690}
 691
 692static void __exit neo1973_exit(void)
 693{
 694        pr_debug("Entered %s\n", __func__);
 695
 696        i2c_del_driver(&lm4857_i2c_driver);
 697        platform_device_unregister(neo1973_snd_device);
 698}
 699
 700module_init(neo1973_init);
 701module_exit(neo1973_exit);
 702
 703/* Module information */
 704MODULE_AUTHOR("Graeme Gregory, graeme@openmoko.org, www.openmoko.org");
 705MODULE_DESCRIPTION("ALSA SoC WM8753 Neo1973");
 706MODULE_LICENSE("GPL");
 707