~ubuntu-branches/ubuntu/karmic/linux-mvl-dove/karmic-proposed

« back to all changes in this revision

Viewing changes to sound/soc/codecs/cs42l51.c

  • Committer: Bazaar Package Importer
  • Author(s): Stefan Bader
  • Date: 2010-03-10 22:24:12 UTC
  • mto: (15.1.2 karmic-security)
  • mto: This revision was merged to the branch mainline in revision 18.
  • Revision ID: james.westby@ubuntu.com-20100310222412-k86m3r53jw0je7x1
Tags: upstream-2.6.31
ImportĀ upstreamĀ versionĀ 2.6.31

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
#include <linux/module.h>
2
 
#include <linux/moduleparam.h>
3
 
#include <linux/init.h>
4
 
#include <linux/interrupt.h>
5
 
#include <linux/delay.h>
6
 
#include <linux/pm.h>
7
 
#include <linux/i2c.h>
8
 
#include <linux/platform_device.h>
9
 
#include <linux/workqueue.h>
10
 
#include <sound/core.h>
11
 
#include <sound/pcm.h>
12
 
#include <sound/pcm_params.h>
13
 
#include <sound/soc.h>
14
 
#include <sound/soc-dai.h>
15
 
#include <sound/soc-dapm.h>
16
 
#include <sound/initval.h>
17
 
#include "cs42l51.h"
18
 
 
19
 
#define AUDIO_NAME "cs42l51"
20
 
 
21
 
#define CS42L51_CACHE_SIZE (CS42L51_REG_MAX+1)
22
 
 
23
 
 
24
 
/*
25
 
#define CS42L51_DEBUG(format, args...) \
26
 
        printk(KERN_DEBUG "%s(%d): "format"\n", __FUNCTION__, __LINE__, ##args)
27
 
*/
28
 
 
29
 
#define CS42L51_DEBUG(format, args...)
30
 
 
31
 
/* codec private data */
32
 
struct cs42l51_priv {
33
 
        unsigned int sysclk;
34
 
        struct snd_soc_codec *codec;
35
 
};
36
 
 
37
 
static unsigned int cs42l51_read_reg_cache(struct snd_soc_codec *codec,
38
 
                                           unsigned int reg)
39
 
{
40
 
        u8 *cache = codec->reg_cache;
41
 
        if (reg > CS42L51_REG_MAX)
42
 
                return -1;
43
 
        return cache[reg];
44
 
}
45
 
 
46
 
static void cs42l51_write_reg_cache(struct snd_soc_codec *codec,
47
 
                                    u8 reg, u8 value)
48
 
{
49
 
        u8 *cache = codec->reg_cache;
50
 
        if (reg > CS42L51_REG_MAX)
51
 
                return;
52
 
        cache[reg] = value;
53
 
}
54
 
 
55
 
static int cs42l51_write(struct snd_soc_codec *codec, unsigned int reg,
56
 
                         unsigned int value)
57
 
{
58
 
        u8 data[2];
59
 
 
60
 
        reg &= 0x7f;
61
 
        data[0] = reg & 0xff;
62
 
        data[1] = value & 0xff;
63
 
 
64
 
        cs42l51_write_reg_cache(codec, data[0], data[1]);
65
 
        if (codec->hw_write(codec->control_data, data, 2) == 2)
66
 
                return 0;
67
 
        else
68
 
                return -EIO;
69
 
}
70
 
 
71
 
static unsigned int cs42l51_read(struct snd_soc_codec *codec, unsigned int reg)
72
 
{
73
 
        return cs42l51_read_reg_cache(codec, reg);
74
 
}
75
 
 
76
 
static unsigned int cs42l51_read_no_cache(struct snd_soc_codec *codec,
77
 
                                          unsigned int reg)
78
 
{
79
 
        struct i2c_msg msg[2];
80
 
        u8 data[2];
81
 
        struct i2c_client *i2c_client = codec->control_data;
82
 
        int ret;
83
 
 
84
 
        i2c_client = (struct i2c_client *)codec->control_data;
85
 
 
86
 
        data[0] = reg & 0xff;
87
 
        msg[0].addr = i2c_client->addr;
88
 
        msg[0].flags = 0;
89
 
        msg[0].buf = &data[0];
90
 
        msg[0].len = 1;
91
 
 
92
 
        msg[1].addr = i2c_client->addr;
93
 
        msg[1].flags = I2C_M_RD;
94
 
        msg[1].buf = &data[1];
95
 
        msg[1].len = 1;
96
 
 
97
 
        ret = i2c_transfer(i2c_client->adapter, &msg[0], 2);
98
 
        return (ret == 2) ? data[1] : -EIO;
99
 
}
100
 
 
101
 
static void cs42l51_fill_cache(struct snd_soc_codec *codec)
102
 
{
103
 
        u8 *cache = codec->reg_cache;
104
 
        unsigned int reg;
105
 
 
106
 
        for (reg = 1; reg <= CS42L51_REG_MAX; reg++)
107
 
                cache[reg] = cs42l51_read_no_cache(codec, reg);
108
 
 
109
 
}
110
 
 
111
 
 
112
 
static void cs42l51_sync_cache(struct snd_soc_codec *codec)
113
 
{
114
 
        u8 *cache = codec->reg_cache;
115
 
        unsigned int reg;
116
 
 
117
 
        for (reg = 1; reg <= CS42L51_REG_MAX; reg++)
118
 
                cs42l51_write(codec, reg, cache[reg]);
119
 
}
120
 
 
121
 
 
122
 
static void cs42l51_set_bits(struct snd_soc_codec *codec, u32 addr,
123
 
                             u32 start_bit, u32 end_bit, u32 value)
124
 
{
125
 
        u32 mask;
126
 
        u32 new_value;
127
 
        u32 old_value;
128
 
 
129
 
        old_value = cs42l51_read(codec, addr);
130
 
        mask = ((1 << (end_bit + 1 - start_bit)) - 1) << start_bit;
131
 
        new_value = old_value & (~mask);
132
 
        new_value |= (mask & (value << start_bit));
133
 
        cs42l51_write(codec, addr, new_value);
134
 
}
135
 
 
136
 
static u8 cs42l51_volume_mapping[] = {
137
 
        0x19, 0xB2, 0xB7, 0xBD, 0xC3, 0xC9, 0xCF, 0xD5,
138
 
        0xD8, 0xE1, 0xE7, 0xED, 0xF3, 0xF9, 0xFF, 0x00,
139
 
        0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
140
 
        0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10,
141
 
        0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18
142
 
};
143
 
 
144
 
#define CS42L51_NUM_VOLUME_STEPS  ARRAY_SIZE(cs42l51_volume_mapping)
145
 
 
146
 
static u8 cs42l51_reg2vol(u8 reg)
147
 
{
148
 
        u8 i;
149
 
 
150
 
        for (i = 0; i < CS42L51_NUM_VOLUME_STEPS; i++) {
151
 
                if (reg == cs42l51_volume_mapping[i])
152
 
                        return i;
153
 
                if ((cs42l51_volume_mapping[i] >
154
 
                     cs42l51_volume_mapping[CS42L51_NUM_VOLUME_STEPS - 1])
155
 
                    && (reg > cs42l51_volume_mapping[i])
156
 
                    && (reg < cs42l51_volume_mapping[i + 1]))
157
 
                        return i;
158
 
 
159
 
        }
160
 
        return 0;
161
 
}
162
 
 
163
 
static u8 cs42l51_vol2reg(u8 vol)
164
 
{
165
 
        if (vol >= CS42L51_NUM_VOLUME_STEPS)
166
 
                vol = CS42L51_NUM_VOLUME_STEPS - 1;
167
 
        return cs42l51_volume_mapping[vol];
168
 
}
169
 
 
170
 
static int cs42l51_vol_info(struct snd_kcontrol *kcontrol,
171
 
                            struct snd_ctl_elem_info *uinfo)
172
 
{
173
 
        uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
174
 
        uinfo->count = 2;
175
 
        uinfo->value.integer.min = 0;
176
 
        uinfo->value.integer.max = 39;
177
 
 
178
 
        return 0;
179
 
}
180
 
 
181
 
static int cs42l51_vol_get(struct snd_kcontrol *kcontrol,
182
 
                           struct snd_ctl_elem_value *ucontrol)
183
 
{
184
 
        struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
185
 
        u8 reg;
186
 
        u8 vol;
187
 
 
188
 
        reg = snd_soc_read(codec, CS42L51_REG_VOL_OUTA_CTRL);
189
 
        vol = cs42l51_reg2vol(reg);
190
 
        ucontrol->value.integer.value[0] = vol;
191
 
 
192
 
        reg = snd_soc_read(codec, CS42L51_REG_VOL_OUTB_CTRL);
193
 
        vol = cs42l51_reg2vol(reg);
194
 
        ucontrol->value.integer.value[1] = vol;
195
 
        return 0;
196
 
}
197
 
 
198
 
static int cs42l51_vol_set(struct snd_kcontrol *kcontrol,
199
 
                           struct snd_ctl_elem_value *ucontrol)
200
 
{
201
 
        struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
202
 
        u8 reg;
203
 
        u8 vol;
204
 
 
205
 
        vol = (u8) ucontrol->value.integer.value[0];
206
 
        reg = cs42l51_vol2reg(vol);
207
 
        snd_soc_update_bits(codec, CS42L51_REG_VOL_OUTA_CTRL, 0xFF, reg);
208
 
 
209
 
        vol = (u8) ucontrol->value.integer.value[1];
210
 
        reg = cs42l51_vol2reg(vol);
211
 
        snd_soc_update_bits(codec, CS42L51_REG_VOL_OUTB_CTRL, 0xFF, reg);
212
 
 
213
 
        return 0;
214
 
}
215
 
 
216
 
static struct snd_kcontrol_new cs42l51_snd_controls[] = {
217
 
        {
218
 
         .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
219
 
         .name = "Playback DAC Volume",
220
 
         .info = cs42l51_vol_info,
221
 
         .get = cs42l51_vol_get,
222
 
         .put = cs42l51_vol_set},
223
 
};
224
 
 
225
 
/* add non dapm controls */
226
 
static int cs42l51_add_controls(struct snd_soc_codec *codec)
227
 
{
228
 
        int err, i;
229
 
 
230
 
        CS42L51_DEBUG("");
231
 
 
232
 
        for (i = 0; i < ARRAY_SIZE(cs42l51_snd_controls); i++) {
233
 
                err = snd_ctl_add(codec->card,
234
 
                                  snd_soc_cnew(&cs42l51_snd_controls[i], codec,
235
 
                                               NULL));
236
 
 
237
 
                if (err < 0)
238
 
                        return err;
239
 
        }
240
 
        return 0;
241
 
}
242
 
 
243
 
static int cs42l51_startup(struct snd_pcm_substream *stream,
244
 
                                struct snd_soc_dai *dai)
245
 
{
246
 
        CS42L51_DEBUG("");
247
 
        return 0;
248
 
}
249
 
 
250
 
static void cs42l51_shutdown(struct snd_pcm_substream *substream,
251
 
                                struct snd_soc_dai *dai)
252
 
{
253
 
        CS42L51_DEBUG("");
254
 
}
255
 
 
256
 
static int cs42l51_hw_params(struct snd_pcm_substream *substream,
257
 
                                struct snd_pcm_hw_params *hw_params,
258
 
                                struct snd_soc_dai *dai)
259
 
{
260
 
        CS42L51_DEBUG("");
261
 
        return 0;
262
 
}
263
 
 
264
 
static int cs42l51_hw_free(struct snd_pcm_substream *stream,
265
 
                                struct snd_soc_dai *dai)
266
 
{
267
 
        CS42L51_DEBUG("");
268
 
        return 0;
269
 
}
270
 
 
271
 
static int cs42l51_prepare(struct snd_pcm_substream *stream,
272
 
                                struct snd_soc_dai *dai)
273
 
{
274
 
        CS42L51_DEBUG("");
275
 
        return 0;
276
 
}
277
 
 
278
 
static int cs42l51_trigger(struct snd_pcm_substream *stream, int cmd,
279
 
                                struct snd_soc_dai *dai)
280
 
{
281
 
        CS42L51_DEBUG("");
282
 
        return 0;
283
 
}
284
 
 
285
 
static int cs42l51_mute(struct snd_soc_dai *dai, int mute)
286
 
{
287
 
        struct snd_soc_codec *codec = dai->codec;
288
 
 
289
 
        CS42L51_DEBUG("mute=%d", mute);
290
 
 
291
 
        if (mute)
292
 
                cs42l51_set_bits(codec, CS42L51_REG_DAC_OUTPUT_CTRL, 0, 1, 3);
293
 
        else
294
 
                cs42l51_set_bits(codec, CS42L51_REG_DAC_OUTPUT_CTRL, 0, 1, 0);
295
 
 
296
 
        return 0;
297
 
}
298
 
 
299
 
static int cs42l51_set_dai_sysclk(struct snd_soc_dai *codec_dai,
300
 
                                  int clk_id, unsigned int freq, int dir)
301
 
{
302
 
        CS42L51_DEBUG("clk_id=%d freq=%u dir=%d", clk_id, freq, dir);
303
 
        return 0;
304
 
}
305
 
 
306
 
static int cs42l51_set_dai_fmt(struct snd_soc_dai *dai,
307
 
                               unsigned int fmt)
308
 
{
309
 
        struct snd_soc_codec *codec = dai->codec;
310
 
 
311
 
        CS42L51_DEBUG("fmt=%u", fmt);
312
 
 
313
 
        switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
314
 
        case SND_SOC_DAIFMT_LEFT_J:
315
 
                cs42l51_set_bits(codec, CS42L51_REG_IF_CNTRL, 3, 5, 0);
316
 
                break;
317
 
        case SND_SOC_DAIFMT_I2S:
318
 
                cs42l51_set_bits(codec, CS42L51_REG_IF_CNTRL, 3, 5, 1);
319
 
                break;
320
 
        case SND_SOC_DAIFMT_RIGHT_J:
321
 
                cs42l51_set_bits(codec, CS42L51_REG_IF_CNTRL, 3, 5, 2);
322
 
                break;
323
 
        default:
324
 
                return -EINVAL;
325
 
        }
326
 
        return 0;
327
 
}
328
 
 
329
 
 
330
 
static int cs42l51_set_bias_level(struct snd_soc_codec *codec,
331
 
                                 enum snd_soc_bias_level level)
332
 
{
333
 
        CS42L51_DEBUG("bias level transition: %d -> %d",
334
 
                codec->bias_level, level);
335
 
        switch (level) {
336
 
        case SND_SOC_BIAS_ON:
337
 
        case SND_SOC_BIAS_PREPARE:
338
 
                cs42l51_set_bits(codec, CS42L51_REG_POWER_CNTRL, 0, 0, 0);
339
 
                break;
340
 
        case SND_SOC_BIAS_STANDBY:
341
 
        case SND_SOC_BIAS_OFF:
342
 
                cs42l51_set_bits(codec, CS42L51_REG_POWER_CNTRL, 0, 0, 1);
343
 
                break;
344
 
        }
345
 
        codec->bias_level = level;
346
 
        return 0;
347
 
}
348
 
 
349
 
static struct snd_soc_dai_ops cs42l51_dai_ops = {
350
 
                .startup = cs42l51_startup,
351
 
                .shutdown = cs42l51_shutdown,
352
 
                .hw_params = cs42l51_hw_params,
353
 
                .hw_free = cs42l51_hw_free,
354
 
                .prepare = cs42l51_prepare,
355
 
                .trigger = cs42l51_trigger,
356
 
                .digital_mute = cs42l51_mute,
357
 
                .set_sysclk = cs42l51_set_dai_sysclk,
358
 
                .set_fmt = cs42l51_set_dai_fmt,
359
 
};
360
 
 
361
 
 
362
 
struct snd_soc_dai cs42l51_dai = {
363
 
        .name = "CS42L51",
364
 
        .playback = {
365
 
                     .stream_name = "Playback",
366
 
                     .rate_min = 44100,
367
 
                     .rate_max = 96000,
368
 
                     .channels_min = 1,
369
 
                     .channels_max = 2,
370
 
                     .rates = (SNDRV_PCM_RATE_44100 |
371
 
                               SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000),
372
 
                     .formats = (SNDRV_PCM_FMTBIT_S16_LE |
373
 
                                 SNDRV_PCM_FMTBIT_S24_LE |
374
 
                                 SNDRV_PCM_FMTBIT_S32_LE),
375
 
                     },
376
 
        .capture = {
377
 
                    .stream_name = "Capture",
378
 
                    .rate_min = 44100,
379
 
                    .rate_max = 96000,
380
 
                    .channels_min = 1,
381
 
                    .channels_max = 2,
382
 
                    .rates = (SNDRV_PCM_RATE_44100 |
383
 
                              SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000),
384
 
                    .formats = (SNDRV_PCM_FMTBIT_S16_LE |
385
 
                                SNDRV_PCM_FMTBIT_S24_LE |
386
 
                                SNDRV_PCM_FMTBIT_S32_LE),
387
 
                    },
388
 
        /* pcm operations */
389
 
        .ops = &cs42l51_dai_ops,
390
 
};
391
 
EXPORT_SYMBOL_GPL(cs42l51_dai);
392
 
 
393
 
static int cs42l51_init(struct snd_soc_device *socdev)
394
 
{
395
 
        struct snd_soc_codec *codec = socdev->card->codec;
396
 
        u8 reg;
397
 
        int ret;
398
 
 
399
 
        CS42L51_DEBUG("");
400
 
 
401
 
        codec->owner = THIS_MODULE;
402
 
        codec->name = "CS42L51";
403
 
        codec->dai = &cs42l51_dai;
404
 
        codec->set_bias_level = cs42l51_set_bias_level;
405
 
        codec->num_dai = 1;
406
 
        codec->reg_cache_size = CS42L51_CACHE_SIZE;
407
 
        codec->reg_cache = kzalloc(codec->reg_cache_size, GFP_KERNEL);
408
 
        if (!codec->reg_cache)
409
 
                return -ENOMEM;
410
 
 
411
 
        cs42l51_fill_cache(codec);
412
 
 
413
 
        ret = -ENODEV;
414
 
 
415
 
        reg = cs42l51_read(codec, CS42L51_REG_ID);
416
 
        printk(KERN_INFO "cs42l51: chipid/revision = %x\n", reg);
417
 
 
418
 
        /* Set the digital Interface format to I2S-up-to-24-bit */
419
 
        cs42l51_set_bits(codec, CS42L51_REG_IF_CNTRL, 3, 5, 1);
420
 
 
421
 
        /* Set the ADC Mode */
422
 
        cs42l51_set_bits(codec, CS42L51_REG_IF_CNTRL, 2, 2, 1);
423
 
 
424
 
        /* init the chip */
425
 
        /* use signal processor */
426
 
        cs42l51_write(codec, CS42L51_REG_DAC_CTRL, 0x40);
427
 
        /* Unmute PCM-A & PCM-B and set default */
428
 
        cs42l51_write(codec, CS42L51_REG_PCMA_MIXER_VOL_CNTRL, 0x10);
429
 
        cs42l51_write(codec, CS42L51_REG_PCMB_MIXER_VOL_CNTRL, 0x10);
430
 
        /* default for AOUTx */
431
 
        cs42l51_write(codec, CS42L51_REG_VOL_OUTA_CTRL, cs42l51_vol2reg(4));
432
 
        cs42l51_write(codec, CS42L51_REG_VOL_OUTB_CTRL, cs42l51_vol2reg(4));
433
 
        /* swap channels */
434
 
        cs42l51_write(codec, CS42L51_REG_CHANNEL_MIXER, 0xff);
435
 
 
436
 
        /* register pcms */
437
 
        ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
438
 
        if (ret < 0) {
439
 
                pr_err("failed to create pcms");
440
 
                goto pcm_err;
441
 
        }
442
 
        cs42l51_add_controls(codec);
443
 
 
444
 
 
445
 
        ret = snd_soc_init_card(socdev);
446
 
        if (ret < 0) {
447
 
                pr_err("failed to register card\n");
448
 
                goto card_err;
449
 
        }
450
 
        return 0;
451
 
 
452
 
card_err:
453
 
        snd_soc_free_pcms(socdev);
454
 
 
455
 
pcm_err:
456
 
        kfree(codec->reg_cache);
457
 
        return ret;
458
 
}
459
 
 
460
 
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
461
 
 
462
 
static const struct i2c_device_id cs42l51_i2c_table[] = {
463
 
        {"i2s_i2c", 0},
464
 
        {}
465
 
};
466
 
 
467
 
MODULE_DEVICE_TABLE(i2c, cs42l51_i2c_table);
468
 
 
469
 
static struct i2c_driver cs42l51_i2c_driver;
470
 
static struct snd_soc_device *cs42l51_socdev;
471
 
 
472
 
static int cs42l51_i2c_probe(struct i2c_client *client,
473
 
                             const struct i2c_device_id *id)
474
 
{
475
 
        struct snd_soc_device *socdev = cs42l51_socdev;
476
 
        struct snd_soc_codec *codec = socdev->card->codec;
477
 
        struct i2c_adapter *adap = to_i2c_adapter(client->dev.parent);
478
 
        int ret;
479
 
 
480
 
        CS42L51_DEBUG("");
481
 
 
482
 
        if (!i2c_check_functionality(adap, I2C_FUNC_SMBUS_EMUL))
483
 
                return -EIO;
484
 
 
485
 
        i2c_set_clientdata(client, codec);
486
 
        codec->control_data = client;
487
 
 
488
 
        codec->read = cs42l51_read;
489
 
        codec->write = cs42l51_write;
490
 
 
491
 
        ret = cs42l51_init(socdev);
492
 
        if (ret < 0)
493
 
                goto err;
494
 
 
495
 
        return ret;
496
 
 
497
 
err:
498
 
        kfree(codec);
499
 
        return ret;
500
 
}
501
 
 
502
 
static int cs42l51_i2c_remove(struct i2c_client *client)
503
 
{
504
 
        return 0;
505
 
}
506
 
 
507
 
static struct i2c_driver cs42l51_i2c_driver = {
508
 
        .driver = {
509
 
                   .name = "cs42l51",
510
 
                   .owner = THIS_MODULE,
511
 
                   },
512
 
        .probe = cs42l51_i2c_probe,
513
 
        .remove = cs42l51_i2c_remove,
514
 
        .id_table = cs42l51_i2c_table,
515
 
};
516
 
 
517
 
#endif
518
 
 
519
 
static int cs42l51_probe(struct platform_device *pdev)
520
 
{
521
 
        struct snd_soc_device *socdev = platform_get_drvdata(pdev);
522
 
        struct snd_soc_codec *codec;
523
 
        struct cs42l51_priv *cs;
524
 
        struct cs42l51_setup_data *setup;
525
 
        int ret;
526
 
 
527
 
        CS42L51_DEBUG("");
528
 
 
529
 
        ret = -ENOMEM;
530
 
        setup = socdev->codec_data;
531
 
        codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
532
 
        if (codec == NULL)
533
 
                goto out;
534
 
 
535
 
        cs = kzalloc(sizeof(struct cs42l51_priv), GFP_KERNEL);
536
 
        if (cs == NULL) {
537
 
                kfree(codec);
538
 
                goto out;
539
 
        }
540
 
        ret = 0;
541
 
 
542
 
        cs->codec = codec;
543
 
        codec->private_data = cs;
544
 
        socdev->card->codec = codec;
545
 
        mutex_init(&codec->mutex);
546
 
        INIT_LIST_HEAD(&codec->dapm_widgets);
547
 
        INIT_LIST_HEAD(&codec->dapm_paths);
548
 
 
549
 
        cs42l51_socdev = socdev;
550
 
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
551
 
        if (setup && setup->i2c_address) {
552
 
                codec->hw_write = (hw_write_t) i2c_master_send;
553
 
                ret = i2c_add_driver(&cs42l51_i2c_driver);
554
 
                if (ret)
555
 
                        printk(KERN_ERR "can't add i2c driver\n");
556
 
        }
557
 
#endif
558
 
 
559
 
out:
560
 
        return ret;
561
 
}
562
 
 
563
 
/* power down chip */
564
 
static int cs42l51_remove(struct platform_device *pdev)
565
 
{
566
 
        struct snd_soc_device *socdev = platform_get_drvdata(pdev);
567
 
        struct snd_soc_codec *codec = socdev->card->codec;
568
 
 
569
 
        CS42L51_DEBUG("");
570
 
 
571
 
        snd_soc_free_pcms(socdev);
572
 
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
573
 
        i2c_del_driver(&cs42l51_i2c_driver);
574
 
#endif
575
 
        kfree(codec->private_data);
576
 
        kfree(codec);
577
 
 
578
 
        return 0;
579
 
}
580
 
 
581
 
static int cs42l51_suspend(struct platform_device *pdev, pm_message_t state)
582
 
{
583
 
        struct snd_soc_device *socdev = platform_get_drvdata(pdev);
584
 
        struct snd_soc_codec *codec = socdev->card->codec;
585
 
 
586
 
        CS42L51_DEBUG("event=%d", state.event);
587
 
 
588
 
        cs42l51_set_bias_level(codec, SND_SOC_BIAS_OFF);
589
 
 
590
 
        return 0;
591
 
}
592
 
 
593
 
static int cs42l51_resume(struct platform_device *pdev)
594
 
{
595
 
        struct snd_soc_device *socdev = platform_get_drvdata(pdev);
596
 
        struct snd_soc_codec *codec = socdev->card->codec;
597
 
 
598
 
        CS42L51_DEBUG("");
599
 
 
600
 
        cs42l51_sync_cache(codec);
601
 
        cs42l51_set_bias_level(codec, codec->suspend_bias_level);
602
 
        return 0;
603
 
}
604
 
 
605
 
struct snd_soc_codec_device soc_codec_dev_cs42l51 = {
606
 
        .probe = cs42l51_probe,
607
 
        .remove = cs42l51_remove,
608
 
        .suspend = cs42l51_suspend,
609
 
        .resume = cs42l51_resume,
610
 
};
611
 
EXPORT_SYMBOL_GPL(soc_codec_dev_cs42l51);
612
 
 
613
 
static int __init cs42l51_modinit(void)
614
 
{
615
 
        CS42L51_DEBUG("");
616
 
        return snd_soc_register_dai(&cs42l51_dai);
617
 
}
618
 
module_init(cs42l51_modinit);
619
 
 
620
 
static void __exit cs42l51_modexit(void)
621
 
{
622
 
        CS42L51_DEBUG("");
623
 
        snd_soc_unregister_dai(&cs42l51_dai);
624
 
}
625
 
module_exit(cs42l51_modexit);
626
 
 
627
 
MODULE_LICENSE("GPL");
628
 
MODULE_DESCRIPTION("ASoC CS42l51 codec driver");
629
 
MODULE_AUTHOR("Yuval Elmaliah <eyuval@marvell.com>");