~ubuntu-branches/ubuntu/precise/linux-lowlatency/precise

« back to all changes in this revision

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

  • Committer: Package Import Robot
  • Author(s): Alessio Igor Bogani
  • Date: 2011-10-26 11:13:05 UTC
  • Revision ID: package-import@ubuntu.com-20111026111305-tz023xykf0i6eosh
Tags: upstream-3.2.0
ImportĀ upstreamĀ versionĀ 3.2.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * ak4642.c  --  AK4642/AK4643 ALSA Soc Audio driver
 
3
 *
 
4
 * Copyright (C) 2009 Renesas Solutions Corp.
 
5
 * Kuninori Morimoto <morimoto.kuninori@renesas.com>
 
6
 *
 
7
 * Based on wm8731.c by Richard Purdie
 
8
 * Based on ak4535.c by Richard Purdie
 
9
 * Based on wm8753.c by Liam Girdwood
 
10
 *
 
11
 * This program is free software; you can redistribute it and/or modify
 
12
 * it under the terms of the GNU General Public License version 2 as
 
13
 * published by the Free Software Foundation.
 
14
 */
 
15
 
 
16
/* ** CAUTION **
 
17
 *
 
18
 * This is very simple driver.
 
19
 * It can use headphone output / stereo input only
 
20
 *
 
21
 * AK4642 is not tested.
 
22
 * AK4643 is tested.
 
23
 */
 
24
 
 
25
#include <linux/delay.h>
 
26
#include <linux/i2c.h>
 
27
#include <linux/platform_device.h>
 
28
#include <linux/slab.h>
 
29
#include <linux/module.h>
 
30
#include <sound/soc.h>
 
31
#include <sound/initval.h>
 
32
#include <sound/tlv.h>
 
33
 
 
34
#define AK4642_VERSION "0.0.1"
 
35
 
 
36
#define PW_MGMT1        0x00
 
37
#define PW_MGMT2        0x01
 
38
#define SG_SL1          0x02
 
39
#define SG_SL2          0x03
 
40
#define MD_CTL1         0x04
 
41
#define MD_CTL2         0x05
 
42
#define TIMER           0x06
 
43
#define ALC_CTL1        0x07
 
44
#define ALC_CTL2        0x08
 
45
#define L_IVC           0x09
 
46
#define L_DVC           0x0a
 
47
#define ALC_CTL3        0x0b
 
48
#define R_IVC           0x0c
 
49
#define R_DVC           0x0d
 
50
#define MD_CTL3         0x0e
 
51
#define MD_CTL4         0x0f
 
52
#define PW_MGMT3        0x10
 
53
#define DF_S            0x11
 
54
#define FIL3_0          0x12
 
55
#define FIL3_1          0x13
 
56
#define FIL3_2          0x14
 
57
#define FIL3_3          0x15
 
58
#define EQ_0            0x16
 
59
#define EQ_1            0x17
 
60
#define EQ_2            0x18
 
61
#define EQ_3            0x19
 
62
#define EQ_4            0x1a
 
63
#define EQ_5            0x1b
 
64
#define FIL1_0          0x1c
 
65
#define FIL1_1          0x1d
 
66
#define FIL1_2          0x1e
 
67
#define FIL1_3          0x1f
 
68
#define PW_MGMT4        0x20
 
69
#define MD_CTL5         0x21
 
70
#define LO_MS           0x22
 
71
#define HP_MS           0x23
 
72
#define SPK_MS          0x24
 
73
 
 
74
#define AK4642_CACHEREGNUM      0x25
 
75
 
 
76
/* PW_MGMT1*/
 
77
#define PMVCM           (1 << 6) /* VCOM Power Management */
 
78
#define PMMIN           (1 << 5) /* MIN Input Power Management */
 
79
#define PMDAC           (1 << 2) /* DAC Power Management */
 
80
#define PMADL           (1 << 0) /* MIC Amp Lch and ADC Lch Power Management */
 
81
 
 
82
/* PW_MGMT2 */
 
83
#define HPMTN           (1 << 6)
 
84
#define PMHPL           (1 << 5)
 
85
#define PMHPR           (1 << 4)
 
86
#define MS              (1 << 3) /* master/slave select */
 
87
#define MCKO            (1 << 1)
 
88
#define PMPLL           (1 << 0)
 
89
 
 
90
#define PMHP_MASK       (PMHPL | PMHPR)
 
91
#define PMHP            PMHP_MASK
 
92
 
 
93
/* PW_MGMT3 */
 
94
#define PMADR           (1 << 0) /* MIC L / ADC R Power Management */
 
95
 
 
96
/* SG_SL1 */
 
97
#define MINS            (1 << 6) /* Switch from MIN to Speaker */
 
98
#define DACL            (1 << 4) /* Switch from DAC to Stereo or Receiver */
 
99
#define PMMP            (1 << 2) /* MPWR pin Power Management */
 
100
#define MGAIN0          (1 << 0) /* MIC amp gain*/
 
101
 
 
102
/* TIMER */
 
103
#define ZTM(param)      ((param & 0x3) << 4) /* ALC Zoro Crossing TimeOut */
 
104
#define WTM(param)      (((param & 0x4) << 4) | ((param & 0x3) << 2))
 
105
 
 
106
/* ALC_CTL1 */
 
107
#define ALC             (1 << 5) /* ALC Enable */
 
108
#define LMTH0           (1 << 0) /* ALC Limiter / Recovery Level */
 
109
 
 
110
/* MD_CTL1 */
 
111
#define PLL3            (1 << 7)
 
112
#define PLL2            (1 << 6)
 
113
#define PLL1            (1 << 5)
 
114
#define PLL0            (1 << 4)
 
115
#define PLL_MASK        (PLL3 | PLL2 | PLL1 | PLL0)
 
116
 
 
117
#define BCKO_MASK       (1 << 3)
 
118
#define BCKO_64         BCKO_MASK
 
119
 
 
120
#define DIF_MASK        (3 << 0)
 
121
#define DSP             (0 << 0)
 
122
#define RIGHT_J         (1 << 0)
 
123
#define LEFT_J          (2 << 0)
 
124
#define I2S             (3 << 0)
 
125
 
 
126
/* MD_CTL2 */
 
127
#define FS0             (1 << 0)
 
128
#define FS1             (1 << 1)
 
129
#define FS2             (1 << 2)
 
130
#define FS3             (1 << 5)
 
131
#define FS_MASK         (FS0 | FS1 | FS2 | FS3)
 
132
 
 
133
/* MD_CTL3 */
 
134
#define BST1            (1 << 3)
 
135
 
 
136
/* MD_CTL4 */
 
137
#define DACH            (1 << 0)
 
138
 
 
139
/*
 
140
 * Playback Volume (table 39)
 
141
 *
 
142
 * max : 0x00 : +12.0 dB
 
143
 *       ( 0.5 dB step )
 
144
 * min : 0xFE : -115.0 dB
 
145
 * mute: 0xFF
 
146
 */
 
147
static const DECLARE_TLV_DB_SCALE(out_tlv, -11500, 50, 1);
 
148
 
 
149
static const struct snd_kcontrol_new ak4642_snd_controls[] = {
 
150
 
 
151
        SOC_DOUBLE_R_TLV("Digital Playback Volume", L_DVC, R_DVC,
 
152
                         0, 0xFF, 1, out_tlv),
 
153
};
 
154
 
 
155
 
 
156
/* codec private data */
 
157
struct ak4642_priv {
 
158
        unsigned int sysclk;
 
159
        enum snd_soc_control_type control_type;
 
160
};
 
161
 
 
162
/*
 
163
 * ak4642 register cache
 
164
 */
 
165
static const u8 ak4642_reg[AK4642_CACHEREGNUM] = {
 
166
        0x00, 0x00, 0x01, 0x00,
 
167
        0x02, 0x00, 0x00, 0x00,
 
168
        0xe1, 0xe1, 0x18, 0x00,
 
169
        0xe1, 0x18, 0x11, 0x08,
 
170
        0x00, 0x00, 0x00, 0x00,
 
171
        0x00, 0x00, 0x00, 0x00,
 
172
        0x00, 0x00, 0x00, 0x00,
 
173
        0x00, 0x00, 0x00, 0x00,
 
174
        0x00, 0x00, 0x00, 0x00,
 
175
        0x00,
 
176
};
 
177
 
 
178
static int ak4642_dai_startup(struct snd_pcm_substream *substream,
 
179
                              struct snd_soc_dai *dai)
 
180
{
 
181
        int is_play = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
 
182
        struct snd_soc_codec *codec = dai->codec;
 
183
 
 
184
        if (is_play) {
 
185
                /*
 
186
                 * start headphone output
 
187
                 *
 
188
                 * PLL, Master Mode
 
189
                 * Audio I/F Format :MSB justified (ADC & DAC)
 
190
                 * Bass Boost Level : Middle
 
191
                 *
 
192
                 * This operation came from example code of
 
193
                 * "ASAHI KASEI AK4642" (japanese) manual p97.
 
194
                 */
 
195
                snd_soc_update_bits(codec, MD_CTL4, DACH, DACH);
 
196
                snd_soc_update_bits(codec, MD_CTL3, BST1, BST1);
 
197
                snd_soc_write(codec, L_IVC, 0x91); /* volume */
 
198
                snd_soc_write(codec, R_IVC, 0x91); /* volume */
 
199
                snd_soc_update_bits(codec, PW_MGMT1, PMVCM | PMMIN | PMDAC,
 
200
                                                     PMVCM | PMMIN | PMDAC);
 
201
                snd_soc_update_bits(codec, PW_MGMT2, PMHP_MASK, PMHP);
 
202
                snd_soc_update_bits(codec, PW_MGMT2, HPMTN,     HPMTN);
 
203
        } else {
 
204
                /*
 
205
                 * start stereo input
 
206
                 *
 
207
                 * PLL Master Mode
 
208
                 * Audio I/F Format:MSB justified (ADC & DAC)
 
209
                 * Pre MIC AMP:+20dB
 
210
                 * MIC Power On
 
211
                 * ALC setting:Refer to Table 35
 
212
                 * ALC bit=ā€œ1ā€
 
213
                 *
 
214
                 * This operation came from example code of
 
215
                 * "ASAHI KASEI AK4642" (japanese) manual p94.
 
216
                 */
 
217
                snd_soc_write(codec, SG_SL1, PMMP | MGAIN0);
 
218
                snd_soc_write(codec, TIMER, ZTM(0x3) | WTM(0x3));
 
219
                snd_soc_write(codec, ALC_CTL1, ALC | LMTH0);
 
220
                snd_soc_update_bits(codec, PW_MGMT1, PMVCM | PMADL,
 
221
                                                     PMVCM | PMADL);
 
222
                snd_soc_update_bits(codec, PW_MGMT3, PMADR, PMADR);
 
223
        }
 
224
 
 
225
        return 0;
 
226
}
 
227
 
 
228
static void ak4642_dai_shutdown(struct snd_pcm_substream *substream,
 
229
                               struct snd_soc_dai *dai)
 
230
{
 
231
        int is_play = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
 
232
        struct snd_soc_codec *codec = dai->codec;
 
233
 
 
234
        if (is_play) {
 
235
                /* stop headphone output */
 
236
                snd_soc_update_bits(codec, PW_MGMT2, HPMTN,     0);
 
237
                snd_soc_update_bits(codec, PW_MGMT2, PMHP_MASK, 0);
 
238
                snd_soc_update_bits(codec, PW_MGMT1, PMMIN | PMDAC, 0);
 
239
                snd_soc_update_bits(codec, MD_CTL3, BST1, 0);
 
240
                snd_soc_update_bits(codec, MD_CTL4, DACH, 0);
 
241
        } else {
 
242
                /* stop stereo input */
 
243
                snd_soc_update_bits(codec, PW_MGMT1, PMADL, 0);
 
244
                snd_soc_update_bits(codec, PW_MGMT3, PMADR, 0);
 
245
                snd_soc_update_bits(codec, ALC_CTL1, ALC, 0);
 
246
        }
 
247
}
 
248
 
 
249
static int ak4642_dai_set_sysclk(struct snd_soc_dai *codec_dai,
 
250
        int clk_id, unsigned int freq, int dir)
 
251
{
 
252
        struct snd_soc_codec *codec = codec_dai->codec;
 
253
        u8 pll;
 
254
 
 
255
        switch (freq) {
 
256
        case 11289600:
 
257
                pll = PLL2;
 
258
                break;
 
259
        case 12288000:
 
260
                pll = PLL2 | PLL0;
 
261
                break;
 
262
        case 12000000:
 
263
                pll = PLL2 | PLL1;
 
264
                break;
 
265
        case 24000000:
 
266
                pll = PLL2 | PLL1 | PLL0;
 
267
                break;
 
268
        case 13500000:
 
269
                pll = PLL3 | PLL2;
 
270
                break;
 
271
        case 27000000:
 
272
                pll = PLL3 | PLL2 | PLL0;
 
273
                break;
 
274
        default:
 
275
                return -EINVAL;
 
276
        }
 
277
        snd_soc_update_bits(codec, MD_CTL1, PLL_MASK, pll);
 
278
 
 
279
        return 0;
 
280
}
 
281
 
 
282
static int ak4642_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 
283
{
 
284
        struct snd_soc_codec *codec = dai->codec;
 
285
        u8 data;
 
286
        u8 bcko;
 
287
 
 
288
        data = MCKO | PMPLL; /* use MCKO */
 
289
        bcko = 0;
 
290
 
 
291
        /* set master/slave audio interface */
 
292
        switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
 
293
        case SND_SOC_DAIFMT_CBM_CFM:
 
294
                data |= MS;
 
295
                bcko = BCKO_64;
 
296
                break;
 
297
        case SND_SOC_DAIFMT_CBS_CFS:
 
298
                break;
 
299
        default:
 
300
                return -EINVAL;
 
301
        }
 
302
        snd_soc_update_bits(codec, PW_MGMT2, MS | MCKO | PMPLL, data);
 
303
        snd_soc_update_bits(codec, MD_CTL1, BCKO_MASK, bcko);
 
304
 
 
305
        /* format type */
 
306
        data = 0;
 
307
        switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
 
308
        case SND_SOC_DAIFMT_LEFT_J:
 
309
                data = LEFT_J;
 
310
                break;
 
311
        case SND_SOC_DAIFMT_I2S:
 
312
                data = I2S;
 
313
                break;
 
314
        /* FIXME
 
315
         * Please add RIGHT_J / DSP support here
 
316
         */
 
317
        default:
 
318
                return -EINVAL;
 
319
                break;
 
320
        }
 
321
        snd_soc_update_bits(codec, MD_CTL1, DIF_MASK, data);
 
322
 
 
323
        return 0;
 
324
}
 
325
 
 
326
static int ak4642_dai_hw_params(struct snd_pcm_substream *substream,
 
327
                                struct snd_pcm_hw_params *params,
 
328
                                struct snd_soc_dai *dai)
 
329
{
 
330
        struct snd_soc_codec *codec = dai->codec;
 
331
        u8 rate;
 
332
 
 
333
        switch (params_rate(params)) {
 
334
        case 7350:
 
335
                rate = FS2;
 
336
                break;
 
337
        case 8000:
 
338
                rate = 0;
 
339
                break;
 
340
        case 11025:
 
341
                rate = FS2 | FS0;
 
342
                break;
 
343
        case 12000:
 
344
                rate = FS0;
 
345
                break;
 
346
        case 14700:
 
347
                rate = FS2 | FS1;
 
348
                break;
 
349
        case 16000:
 
350
                rate = FS1;
 
351
                break;
 
352
        case 22050:
 
353
                rate = FS2 | FS1 | FS0;
 
354
                break;
 
355
        case 24000:
 
356
                rate = FS1 | FS0;
 
357
                break;
 
358
        case 29400:
 
359
                rate = FS3 | FS2 | FS1;
 
360
                break;
 
361
        case 32000:
 
362
                rate = FS3 | FS1;
 
363
                break;
 
364
        case 44100:
 
365
                rate = FS3 | FS2 | FS1 | FS0;
 
366
                break;
 
367
        case 48000:
 
368
                rate = FS3 | FS1 | FS0;
 
369
                break;
 
370
        default:
 
371
                return -EINVAL;
 
372
                break;
 
373
        }
 
374
        snd_soc_update_bits(codec, MD_CTL2, FS_MASK, rate);
 
375
 
 
376
        return 0;
 
377
}
 
378
 
 
379
static struct snd_soc_dai_ops ak4642_dai_ops = {
 
380
        .startup        = ak4642_dai_startup,
 
381
        .shutdown       = ak4642_dai_shutdown,
 
382
        .set_sysclk     = ak4642_dai_set_sysclk,
 
383
        .set_fmt        = ak4642_dai_set_fmt,
 
384
        .hw_params      = ak4642_dai_hw_params,
 
385
};
 
386
 
 
387
static struct snd_soc_dai_driver ak4642_dai = {
 
388
        .name = "ak4642-hifi",
 
389
        .playback = {
 
390
                .stream_name = "Playback",
 
391
                .channels_min = 1,
 
392
                .channels_max = 2,
 
393
                .rates = SNDRV_PCM_RATE_8000_48000,
 
394
                .formats = SNDRV_PCM_FMTBIT_S16_LE },
 
395
        .capture = {
 
396
                .stream_name = "Capture",
 
397
                .channels_min = 1,
 
398
                .channels_max = 2,
 
399
                .rates = SNDRV_PCM_RATE_8000_48000,
 
400
                .formats = SNDRV_PCM_FMTBIT_S16_LE },
 
401
        .ops = &ak4642_dai_ops,
 
402
        .symmetric_rates = 1,
 
403
};
 
404
 
 
405
static int ak4642_resume(struct snd_soc_codec *codec)
 
406
{
 
407
        snd_soc_cache_sync(codec);
 
408
        return 0;
 
409
}
 
410
 
 
411
 
 
412
static int ak4642_probe(struct snd_soc_codec *codec)
 
413
{
 
414
        struct ak4642_priv *ak4642 = snd_soc_codec_get_drvdata(codec);
 
415
        int ret;
 
416
 
 
417
        dev_info(codec->dev, "AK4642 Audio Codec %s", AK4642_VERSION);
 
418
 
 
419
        ret = snd_soc_codec_set_cache_io(codec, 8, 8, ak4642->control_type);
 
420
        if (ret < 0) {
 
421
                dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
 
422
                return ret;
 
423
        }
 
424
 
 
425
        snd_soc_add_controls(codec, ak4642_snd_controls,
 
426
                             ARRAY_SIZE(ak4642_snd_controls));
 
427
 
 
428
        return 0;
 
429
}
 
430
 
 
431
static struct snd_soc_codec_driver soc_codec_dev_ak4642 = {
 
432
        .probe                  = ak4642_probe,
 
433
        .resume                 = ak4642_resume,
 
434
        .reg_cache_size         = ARRAY_SIZE(ak4642_reg),
 
435
        .reg_word_size          = sizeof(u8),
 
436
        .reg_cache_default      = ak4642_reg,
 
437
};
 
438
 
 
439
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
 
440
static __devinit int ak4642_i2c_probe(struct i2c_client *i2c,
 
441
                                      const struct i2c_device_id *id)
 
442
{
 
443
        struct ak4642_priv *ak4642;
 
444
        int ret;
 
445
 
 
446
        ak4642 = kzalloc(sizeof(struct ak4642_priv), GFP_KERNEL);
 
447
        if (!ak4642)
 
448
                return -ENOMEM;
 
449
 
 
450
        i2c_set_clientdata(i2c, ak4642);
 
451
        ak4642->control_type = SND_SOC_I2C;
 
452
 
 
453
        ret =  snd_soc_register_codec(&i2c->dev,
 
454
                        &soc_codec_dev_ak4642, &ak4642_dai, 1);
 
455
        if (ret < 0)
 
456
                kfree(ak4642);
 
457
        return ret;
 
458
}
 
459
 
 
460
static __devexit int ak4642_i2c_remove(struct i2c_client *client)
 
461
{
 
462
        snd_soc_unregister_codec(&client->dev);
 
463
        kfree(i2c_get_clientdata(client));
 
464
        return 0;
 
465
}
 
466
 
 
467
static const struct i2c_device_id ak4642_i2c_id[] = {
 
468
        { "ak4642", 0 },
 
469
        { "ak4643", 0 },
 
470
        { }
 
471
};
 
472
MODULE_DEVICE_TABLE(i2c, ak4642_i2c_id);
 
473
 
 
474
static struct i2c_driver ak4642_i2c_driver = {
 
475
        .driver = {
 
476
                .name = "ak4642-codec",
 
477
                .owner = THIS_MODULE,
 
478
        },
 
479
        .probe          = ak4642_i2c_probe,
 
480
        .remove         = __devexit_p(ak4642_i2c_remove),
 
481
        .id_table       = ak4642_i2c_id,
 
482
};
 
483
#endif
 
484
 
 
485
static int __init ak4642_modinit(void)
 
486
{
 
487
        int ret = 0;
 
488
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
 
489
        ret = i2c_add_driver(&ak4642_i2c_driver);
 
490
#endif
 
491
        return ret;
 
492
 
 
493
}
 
494
module_init(ak4642_modinit);
 
495
 
 
496
static void __exit ak4642_exit(void)
 
497
{
 
498
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
 
499
        i2c_del_driver(&ak4642_i2c_driver);
 
500
#endif
 
501
 
 
502
}
 
503
module_exit(ak4642_exit);
 
504
 
 
505
MODULE_DESCRIPTION("Soc AK4642 driver");
 
506
MODULE_AUTHOR("Kuninori Morimoto <morimoto.kuninori@renesas.com>");
 
507
MODULE_LICENSE("GPL");