~ubuntu-branches/debian/wheezy/linux-2.6/wheezy

« back to all changes in this revision

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

  • Committer: Bazaar Package Importer
  • Author(s): Ben Hutchings, Ben Hutchings, Aurelien Jarno, Martin Michlmayr
  • Date: 2011-04-06 13:53:30 UTC
  • mfrom: (43.1.5 sid)
  • Revision ID: james.westby@ubuntu.com-20110406135330-wjufxhd0tvn3zx4z
Tags: 2.6.38-3
[ Ben Hutchings ]
* [ppc64] Add to linux-tools package architectures (Closes: #620124)
* [amd64] Save cr4 to mmu_cr4_features at boot time (Closes: #620284)
* appletalk: Fix bugs introduced when removing use of BKL
* ALSA: Fix yet another race in disconnection
* cciss: Fix lost command issue
* ath9k: Fix kernel panic in AR2427
* ses: Avoid kernel panic when lun 0 is not mapped
* PCI/ACPI: Report ASPM support to BIOS if not disabled from command line

[ Aurelien Jarno ]
* rtlwifi: fix build when PCI is not enabled.

[ Martin Michlmayr ]
* rtlwifi: Eliminate udelay calls with too large values (Closes: #620204)

Show diffs side-by-side

added added

removed removed

Lines of Context:
19
19
#include <linux/i2c.h>
20
20
#include <linux/platform_device.h>
21
21
#include <linux/regulator/consumer.h>
 
22
#include <linux/slab.h>
22
23
#include <sound/core.h>
23
24
#include <sound/pcm.h>
24
25
#include <sound/pcm_params.h>
25
26
#include <sound/soc.h>
26
 
#include <sound/soc-dapm.h>
27
27
#include <sound/initval.h>
28
28
#include <sound/tlv.h>
29
29
 
30
30
#include "wm8523.h"
31
31
 
32
 
static struct snd_soc_codec *wm8523_codec;
33
 
struct snd_soc_codec_device soc_codec_dev_wm8523;
34
 
 
35
32
#define WM8523_NUM_SUPPLIES 2
36
33
static const char *wm8523_supply_names[WM8523_NUM_SUPPLIES] = {
37
34
        "AVDD",
42
39
 
43
40
/* codec private data */
44
41
struct wm8523_priv {
45
 
        struct snd_soc_codec codec;
46
 
        u16 reg_cache[WM8523_REGISTER_COUNT];
 
42
        enum snd_soc_control_type control_type;
47
43
        struct regulator_bulk_data supplies[WM8523_NUM_SUPPLIES];
48
44
        unsigned int sysclk;
49
45
        unsigned int rate_constraint_list[WM8523_NUM_RATES];
112
108
 
113
109
static int wm8523_add_widgets(struct snd_soc_codec *codec)
114
110
{
115
 
        snd_soc_dapm_new_controls(codec, wm8523_dapm_widgets,
 
111
        struct snd_soc_dapm_context *dapm = &codec->dapm;
 
112
 
 
113
        snd_soc_dapm_new_controls(dapm, wm8523_dapm_widgets,
116
114
                                  ARRAY_SIZE(wm8523_dapm_widgets));
117
 
 
118
 
        snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
119
 
 
120
 
        snd_soc_dapm_new_widgets(codec);
 
115
        snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon));
 
116
 
121
117
        return 0;
122
118
}
123
119
 
138
134
                          struct snd_soc_dai *dai)
139
135
{
140
136
        struct snd_soc_codec *codec = dai->codec;
141
 
        struct wm8523_priv *wm8523 = codec->private_data;
 
137
        struct wm8523_priv *wm8523 = snd_soc_codec_get_drvdata(codec);
142
138
 
143
139
        /* The set of sample rates that can be supported depends on the
144
140
         * MCLK supplied to the CODEC - enforce this.
149
145
                return -EINVAL;
150
146
        }
151
147
 
152
 
        return 0;
153
148
        snd_pcm_hw_constraint_list(substream->runtime, 0,
154
149
                                   SNDRV_PCM_HW_PARAM_RATE,
155
150
                                   &wm8523->rate_constraint);
162
157
                            struct snd_soc_dai *dai)
163
158
{
164
159
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
165
 
        struct snd_soc_device *socdev = rtd->socdev;
166
 
        struct snd_soc_codec *codec = socdev->card->codec;
167
 
        struct wm8523_priv *wm8523 = codec->private_data;
 
160
        struct snd_soc_codec *codec = rtd->codec;
 
161
        struct wm8523_priv *wm8523 = snd_soc_codec_get_drvdata(codec);
168
162
        int i;
169
163
        u16 aifctrl1 = snd_soc_read(codec, WM8523_AIF_CTRL1);
170
164
        u16 aifctrl2 = snd_soc_read(codec, WM8523_AIF_CTRL2);
211
205
                int clk_id, unsigned int freq, int dir)
212
206
{
213
207
        struct snd_soc_codec *codec = codec_dai->codec;
214
 
        struct wm8523_priv *wm8523 = codec->private_data;
 
208
        struct wm8523_priv *wm8523 = snd_soc_codec_get_drvdata(codec);
215
209
        unsigned int val;
216
210
        int i;
217
211
 
318
312
static int wm8523_set_bias_level(struct snd_soc_codec *codec,
319
313
                                 enum snd_soc_bias_level level)
320
314
{
321
 
        struct wm8523_priv *wm8523 = codec->private_data;
 
315
        struct wm8523_priv *wm8523 = snd_soc_codec_get_drvdata(codec);
 
316
        u16 *reg_cache = codec->reg_cache;
322
317
        int ret, i;
323
318
 
324
319
        switch (level) {
332
327
                break;
333
328
 
334
329
        case SND_SOC_BIAS_STANDBY:
335
 
                if (codec->bias_level == SND_SOC_BIAS_OFF) {
 
330
                if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
336
331
                        ret = regulator_bulk_enable(ARRAY_SIZE(wm8523->supplies),
337
332
                                                    wm8523->supplies);
338
333
                        if (ret != 0) {
349
344
                        /* Sync back default/cached values */
350
345
                        for (i = WM8523_AIF_CTRL1;
351
346
                             i < WM8523_MAX_REGISTER; i++)
352
 
                                snd_soc_write(codec, i, wm8523->reg_cache[i]);
 
347
                                snd_soc_write(codec, i, reg_cache[i]);
353
348
 
354
349
 
355
350
                        msleep(100);
371
366
                                       wm8523->supplies);
372
367
                break;
373
368
        }
374
 
        codec->bias_level = level;
 
369
        codec->dapm.bias_level = level;
375
370
        return 0;
376
371
}
377
372
 
387
382
        .set_fmt        = wm8523_set_dai_fmt,
388
383
};
389
384
 
390
 
struct snd_soc_dai wm8523_dai = {
391
 
        .name = "WM8523",
 
385
static struct snd_soc_dai_driver wm8523_dai = {
 
386
        .name = "wm8523-hifi",
392
387
        .playback = {
393
388
                .stream_name = "Playback",
394
389
                .channels_min = 2,  /* Mono modes not yet supported */
398
393
        },
399
394
        .ops = &wm8523_dai_ops,
400
395
};
401
 
EXPORT_SYMBOL_GPL(wm8523_dai);
402
396
 
403
397
#ifdef CONFIG_PM
404
 
static int wm8523_suspend(struct platform_device *pdev, pm_message_t state)
 
398
static int wm8523_suspend(struct snd_soc_codec *codec, pm_message_t state)
405
399
{
406
 
        struct snd_soc_device *socdev = platform_get_drvdata(pdev);
407
 
        struct snd_soc_codec *codec = socdev->card->codec;
408
 
 
409
400
        wm8523_set_bias_level(codec, SND_SOC_BIAS_OFF);
410
401
        return 0;
411
402
}
412
403
 
413
 
static int wm8523_resume(struct platform_device *pdev)
 
404
static int wm8523_resume(struct snd_soc_codec *codec)
414
405
{
415
 
        struct snd_soc_device *socdev = platform_get_drvdata(pdev);
416
 
        struct snd_soc_codec *codec = socdev->card->codec;
417
 
 
418
406
        wm8523_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
419
 
 
420
407
        return 0;
421
408
}
422
409
#else
424
411
#define wm8523_resume NULL
425
412
#endif
426
413
 
427
 
static int wm8523_probe(struct platform_device *pdev)
428
 
{
429
 
        struct snd_soc_device *socdev = platform_get_drvdata(pdev);
430
 
        struct snd_soc_codec *codec;
431
 
        int ret = 0;
432
 
 
433
 
        if (wm8523_codec == NULL) {
434
 
                dev_err(&pdev->dev, "Codec device not registered\n");
435
 
                return -ENODEV;
436
 
        }
437
 
 
438
 
        socdev->card->codec = wm8523_codec;
439
 
        codec = wm8523_codec;
440
 
 
441
 
        /* register pcms */
442
 
        ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
443
 
        if (ret < 0) {
444
 
                dev_err(codec->dev, "failed to create pcms: %d\n", ret);
445
 
                goto pcm_err;
446
 
        }
447
 
 
448
 
        snd_soc_add_controls(codec, wm8523_snd_controls,
449
 
                             ARRAY_SIZE(wm8523_snd_controls));
450
 
        wm8523_add_widgets(codec);
451
 
        ret = snd_soc_init_card(socdev);
452
 
        if (ret < 0) {
453
 
                dev_err(codec->dev, "failed to register card: %d\n", ret);
454
 
                goto card_err;
455
 
        }
456
 
 
457
 
        return ret;
458
 
 
459
 
card_err:
460
 
        snd_soc_free_pcms(socdev);
461
 
        snd_soc_dapm_free(socdev);
462
 
pcm_err:
463
 
        return ret;
464
 
}
465
 
 
466
 
static int wm8523_remove(struct platform_device *pdev)
467
 
{
468
 
        struct snd_soc_device *socdev = platform_get_drvdata(pdev);
469
 
 
470
 
        snd_soc_free_pcms(socdev);
471
 
        snd_soc_dapm_free(socdev);
472
 
 
473
 
        return 0;
474
 
}
475
 
 
476
 
struct snd_soc_codec_device soc_codec_dev_wm8523 = {
477
 
        .probe =        wm8523_probe,
478
 
        .remove =       wm8523_remove,
479
 
        .suspend =      wm8523_suspend,
480
 
        .resume =       wm8523_resume,
481
 
};
482
 
EXPORT_SYMBOL_GPL(soc_codec_dev_wm8523);
483
 
 
484
 
static int wm8523_register(struct wm8523_priv *wm8523,
485
 
                           enum snd_soc_control_type control)
486
 
{
487
 
        int ret;
488
 
        struct snd_soc_codec *codec = &wm8523->codec;
489
 
        int i;
490
 
 
491
 
        if (wm8523_codec) {
492
 
                dev_err(codec->dev, "Another WM8523 is registered\n");
493
 
                return -EINVAL;
494
 
        }
495
 
 
496
 
        mutex_init(&codec->mutex);
497
 
        INIT_LIST_HEAD(&codec->dapm_widgets);
498
 
        INIT_LIST_HEAD(&codec->dapm_paths);
499
 
 
500
 
        codec->private_data = wm8523;
501
 
        codec->name = "WM8523";
502
 
        codec->owner = THIS_MODULE;
503
 
        codec->bias_level = SND_SOC_BIAS_OFF;
504
 
        codec->set_bias_level = wm8523_set_bias_level;
505
 
        codec->dai = &wm8523_dai;
506
 
        codec->num_dai = 1;
507
 
        codec->reg_cache_size = WM8523_REGISTER_COUNT;
508
 
        codec->reg_cache = &wm8523->reg_cache;
509
 
        codec->volatile_register = wm8523_volatile_register;
510
 
 
 
414
static int wm8523_probe(struct snd_soc_codec *codec)
 
415
{
 
416
        struct wm8523_priv *wm8523 = snd_soc_codec_get_drvdata(codec);
 
417
        u16 *reg_cache = codec->reg_cache;
 
418
        int ret, i;
 
419
 
 
420
        codec->hw_write = (hw_write_t)i2c_master_send;
511
421
        wm8523->rate_constraint.list = &wm8523->rate_constraint_list[0];
512
422
        wm8523->rate_constraint.count =
513
423
                ARRAY_SIZE(wm8523->rate_constraint_list);
514
424
 
515
 
        memcpy(codec->reg_cache, wm8523_reg, sizeof(wm8523_reg));
516
 
 
517
 
        ret = snd_soc_codec_set_cache_io(codec, 8, 16, control);
 
425
        ret = snd_soc_codec_set_cache_io(codec, 8, 16, wm8523->control_type);
518
426
        if (ret != 0) {
519
427
                dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
520
 
                goto err;
 
428
                return ret;
521
429
        }
522
430
 
523
431
        for (i = 0; i < ARRAY_SIZE(wm8523->supplies); i++)
527
435
                                 wm8523->supplies);
528
436
        if (ret != 0) {
529
437
                dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
530
 
                goto err;
 
438
                return ret;
531
439
        }
532
440
 
533
441
        ret = regulator_bulk_enable(ARRAY_SIZE(wm8523->supplies),
562
470
                goto err_enable;
563
471
        }
564
472
 
565
 
        wm8523_dai.dev = codec->dev;
566
 
 
567
473
        /* Change some default settings - latch VU and enable ZC */
568
 
        wm8523->reg_cache[WM8523_DAC_GAINR] |= WM8523_DACR_VU;
569
 
        wm8523->reg_cache[WM8523_DAC_CTRL3] |= WM8523_ZC;
 
474
        reg_cache[WM8523_DAC_GAINR] |= WM8523_DACR_VU;
 
475
        reg_cache[WM8523_DAC_CTRL3] |= WM8523_ZC;
570
476
 
571
477
        wm8523_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
572
478
 
573
479
        /* Bias level configuration will have done an extra enable */
574
480
        regulator_bulk_disable(ARRAY_SIZE(wm8523->supplies), wm8523->supplies);
575
481
 
576
 
        wm8523_codec = codec;
577
 
 
578
 
        ret = snd_soc_register_codec(codec);
579
 
        if (ret != 0) {
580
 
                dev_err(codec->dev, "Failed to register codec: %d\n", ret);
581
 
                return ret;
582
 
        }
583
 
 
584
 
        ret = snd_soc_register_dai(&wm8523_dai);
585
 
        if (ret != 0) {
586
 
                dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
587
 
                snd_soc_unregister_codec(codec);
588
 
                return ret;
589
 
        }
 
482
        snd_soc_add_controls(codec, wm8523_snd_controls,
 
483
                             ARRAY_SIZE(wm8523_snd_controls));
 
484
        wm8523_add_widgets(codec);
590
485
 
591
486
        return 0;
592
487
 
594
489
        regulator_bulk_disable(ARRAY_SIZE(wm8523->supplies), wm8523->supplies);
595
490
err_get:
596
491
        regulator_bulk_free(ARRAY_SIZE(wm8523->supplies), wm8523->supplies);
597
 
err:
598
 
        kfree(wm8523);
 
492
 
599
493
        return ret;
600
494
}
601
495
 
602
 
static void wm8523_unregister(struct wm8523_priv *wm8523)
 
496
static int wm8523_remove(struct snd_soc_codec *codec)
603
497
{
604
 
        wm8523_set_bias_level(&wm8523->codec, SND_SOC_BIAS_OFF);
 
498
        struct wm8523_priv *wm8523 = snd_soc_codec_get_drvdata(codec);
 
499
 
 
500
        wm8523_set_bias_level(codec, SND_SOC_BIAS_OFF);
605
501
        regulator_bulk_free(ARRAY_SIZE(wm8523->supplies), wm8523->supplies);
606
 
        snd_soc_unregister_dai(&wm8523_dai);
607
 
        snd_soc_unregister_codec(&wm8523->codec);
608
 
        kfree(wm8523);
609
 
        wm8523_codec = NULL;
 
502
        return 0;
610
503
}
611
504
 
 
505
static struct snd_soc_codec_driver soc_codec_dev_wm8523 = {
 
506
        .probe =        wm8523_probe,
 
507
        .remove =       wm8523_remove,
 
508
        .suspend =      wm8523_suspend,
 
509
        .resume =       wm8523_resume,
 
510
        .set_bias_level = wm8523_set_bias_level,
 
511
        .reg_cache_size = WM8523_REGISTER_COUNT,
 
512
        .reg_word_size = sizeof(u16),
 
513
        .reg_cache_default = wm8523_reg,
 
514
        .volatile_register = wm8523_volatile_register,
 
515
};
 
516
 
612
517
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
613
518
static __devinit int wm8523_i2c_probe(struct i2c_client *i2c,
614
519
                                      const struct i2c_device_id *id)
615
520
{
616
521
        struct wm8523_priv *wm8523;
617
 
        struct snd_soc_codec *codec;
 
522
        int ret;
618
523
 
619
524
        wm8523 = kzalloc(sizeof(struct wm8523_priv), GFP_KERNEL);
620
525
        if (wm8523 == NULL)
621
526
                return -ENOMEM;
622
527
 
623
 
        codec = &wm8523->codec;
624
 
        codec->hw_write = (hw_write_t)i2c_master_send;
625
 
 
626
528
        i2c_set_clientdata(i2c, wm8523);
627
 
        codec->control_data = i2c;
628
 
 
629
 
        codec->dev = &i2c->dev;
630
 
 
631
 
        return wm8523_register(wm8523, SND_SOC_I2C);
 
529
        wm8523->control_type = SND_SOC_I2C;
 
530
 
 
531
        ret =  snd_soc_register_codec(&i2c->dev,
 
532
                        &soc_codec_dev_wm8523, &wm8523_dai, 1);
 
533
        if (ret < 0)
 
534
                kfree(wm8523);
 
535
        return ret;
 
536
 
632
537
}
633
538
 
634
539
static __devexit int wm8523_i2c_remove(struct i2c_client *client)
635
540
{
636
 
        struct wm8523_priv *wm8523 = i2c_get_clientdata(client);
637
 
        wm8523_unregister(wm8523);
 
541
        snd_soc_unregister_codec(&client->dev);
 
542
        kfree(i2c_get_clientdata(client));
638
543
        return 0;
639
544
}
640
545
 
641
 
#ifdef CONFIG_PM
642
 
static int wm8523_i2c_suspend(struct i2c_client *i2c, pm_message_t msg)
643
 
{
644
 
        return snd_soc_suspend_device(&i2c->dev);
645
 
}
646
 
 
647
 
static int wm8523_i2c_resume(struct i2c_client *i2c)
648
 
{
649
 
        return snd_soc_resume_device(&i2c->dev);
650
 
}
651
 
#else
652
 
#define wm8523_i2c_suspend NULL
653
 
#define wm8523_i2c_resume NULL
654
 
#endif
655
 
 
656
546
static const struct i2c_device_id wm8523_i2c_id[] = {
657
547
        { "wm8523", 0 },
658
548
        { }
661
551
 
662
552
static struct i2c_driver wm8523_i2c_driver = {
663
553
        .driver = {
664
 
                .name = "WM8523",
 
554
                .name = "wm8523-codec",
665
555
                .owner = THIS_MODULE,
666
556
        },
667
557
        .probe =    wm8523_i2c_probe,
668
558
        .remove =   __devexit_p(wm8523_i2c_remove),
669
 
        .suspend =  wm8523_i2c_suspend,
670
 
        .resume =   wm8523_i2c_resume,
671
559
        .id_table = wm8523_i2c_id,
672
560
};
673
561
#endif