aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/wm9712.c
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2010-10-25 04:00:30 -0400
committerTakashi Iwai <tiwai@suse.de>2010-10-25 04:00:30 -0400
commitaa5c14d5c0d3e4c587db4a1b220b9c86415c538f (patch)
tree0114637e8be2b38176e7e91e6cea3501b22cb66a /sound/soc/codecs/wm9712.c
parent79fc84c7e0d2fe89c4e82f3a26fd8b0d13c31703 (diff)
parentb11bdb5254ff17cb63e4ae5088b73fdcd2cc2602 (diff)
Merge branch 'topic/asoc' into for-linus
Conflicts: arch/powerpc/platforms/85xx/p1022_ds.c
Diffstat (limited to 'sound/soc/codecs/wm9712.c')
-rw-r--r--sound/soc/codecs/wm9712.c124
1 files changed, 52 insertions, 72 deletions
diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c
index 28790a2ffe8d..d2f224d62744 100644
--- a/sound/soc/codecs/wm9712.c
+++ b/sound/soc/codecs/wm9712.c
@@ -478,8 +478,7 @@ static int ac97_prepare(struct snd_pcm_substream *substream,
478{ 478{
479 struct snd_pcm_runtime *runtime = substream->runtime; 479 struct snd_pcm_runtime *runtime = substream->runtime;
480 struct snd_soc_pcm_runtime *rtd = substream->private_data; 480 struct snd_soc_pcm_runtime *rtd = substream->private_data;
481 struct snd_soc_device *socdev = rtd->socdev; 481 struct snd_soc_codec *codec =rtd->codec;
482 struct snd_soc_codec *codec = socdev->card->codec;
483 int reg; 482 int reg;
484 u16 vra; 483 u16 vra;
485 484
@@ -499,8 +498,7 @@ static int ac97_aux_prepare(struct snd_pcm_substream *substream,
499{ 498{
500 struct snd_pcm_runtime *runtime = substream->runtime; 499 struct snd_pcm_runtime *runtime = substream->runtime;
501 struct snd_soc_pcm_runtime *rtd = substream->private_data; 500 struct snd_soc_pcm_runtime *rtd = substream->private_data;
502 struct snd_soc_device *socdev = rtd->socdev; 501 struct snd_soc_codec *codec = rtd->codec;
503 struct snd_soc_codec *codec = socdev->card->codec;
504 u16 vra, xsle; 502 u16 vra, xsle;
505 503
506 vra = ac97_read(codec, AC97_EXTENDED_STATUS); 504 vra = ac97_read(codec, AC97_EXTENDED_STATUS);
@@ -526,9 +524,9 @@ static struct snd_soc_dai_ops wm9712_dai_ops_aux = {
526 .prepare = ac97_aux_prepare, 524 .prepare = ac97_aux_prepare,
527}; 525};
528 526
529struct snd_soc_dai wm9712_dai[] = { 527static struct snd_soc_dai_driver wm9712_dai[] = {
530{ 528{
531 .name = "AC97 HiFi", 529 .name = "wm9712-hifi",
532 .ac97_control = 1, 530 .ac97_control = 1,
533 .playback = { 531 .playback = {
534 .stream_name = "HiFi Playback", 532 .stream_name = "HiFi Playback",
@@ -545,7 +543,7 @@ struct snd_soc_dai wm9712_dai[] = {
545 .ops = &wm9712_dai_ops_hifi, 543 .ops = &wm9712_dai_ops_hifi,
546}, 544},
547{ 545{
548 .name = "AC97 Aux", 546 .name = "wm9712-aux",
549 .playback = { 547 .playback = {
550 .stream_name = "Aux Playback", 548 .stream_name = "Aux Playback",
551 .channels_min = 1, 549 .channels_min = 1,
@@ -555,7 +553,6 @@ struct snd_soc_dai wm9712_dai[] = {
555 .ops = &wm9712_dai_ops_aux, 553 .ops = &wm9712_dai_ops_aux,
556} 554}
557}; 555};
558EXPORT_SYMBOL_GPL(wm9712_dai);
559 556
560static int wm9712_set_bias_level(struct snd_soc_codec *codec, 557static int wm9712_set_bias_level(struct snd_soc_codec *codec,
561 enum snd_soc_bias_level level) 558 enum snd_soc_bias_level level)
@@ -597,20 +594,15 @@ err:
597 return -EIO; 594 return -EIO;
598} 595}
599 596
600static int wm9712_soc_suspend(struct platform_device *pdev, 597static int wm9712_soc_suspend(struct snd_soc_codec *codec,
601 pm_message_t state) 598 pm_message_t state)
602{ 599{
603 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
604 struct snd_soc_codec *codec = socdev->card->codec;
605
606 wm9712_set_bias_level(codec, SND_SOC_BIAS_OFF); 600 wm9712_set_bias_level(codec, SND_SOC_BIAS_OFF);
607 return 0; 601 return 0;
608} 602}
609 603
610static int wm9712_soc_resume(struct platform_device *pdev) 604static int wm9712_soc_resume(struct snd_soc_codec *codec)
611{ 605{
612 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
613 struct snd_soc_codec *codec = socdev->card->codec;
614 int i, ret; 606 int i, ret;
615 u16 *cache = codec->reg_cache; 607 u16 *cache = codec->reg_cache;
616 608
@@ -635,51 +627,18 @@ static int wm9712_soc_resume(struct platform_device *pdev)
635 return ret; 627 return ret;
636} 628}
637 629
638static int wm9712_soc_probe(struct platform_device *pdev) 630static int wm9712_soc_probe(struct snd_soc_codec *codec)
639{ 631{
640 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
641 struct snd_soc_codec *codec;
642 int ret = 0; 632 int ret = 0;
643 633
644 printk(KERN_INFO "WM9711/WM9712 SoC Audio Codec %s\n", WM9712_VERSION); 634 printk(KERN_INFO "WM9711/WM9712 SoC Audio Codec %s\n", WM9712_VERSION);
645 635
646 socdev->card->codec = kzalloc(sizeof(struct snd_soc_codec),
647 GFP_KERNEL);
648 if (socdev->card->codec == NULL)
649 return -ENOMEM;
650 codec = socdev->card->codec;
651 mutex_init(&codec->mutex);
652
653 codec->reg_cache = kmemdup(wm9712_reg, sizeof(wm9712_reg), GFP_KERNEL);
654
655 if (codec->reg_cache == NULL) {
656 ret = -ENOMEM;
657 goto cache_err;
658 }
659 codec->reg_cache_size = sizeof(wm9712_reg);
660 codec->reg_cache_step = 2;
661
662 codec->name = "WM9712";
663 codec->owner = THIS_MODULE;
664 codec->dai = wm9712_dai;
665 codec->num_dai = ARRAY_SIZE(wm9712_dai);
666 codec->write = ac97_write;
667 codec->read = ac97_read;
668 codec->set_bias_level = wm9712_set_bias_level;
669 INIT_LIST_HEAD(&codec->dapm_widgets);
670 INIT_LIST_HEAD(&codec->dapm_paths);
671
672 ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0); 636 ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0);
673 if (ret < 0) { 637 if (ret < 0) {
674 printk(KERN_ERR "wm9712: failed to register AC97 codec\n"); 638 printk(KERN_ERR "wm9712: failed to register AC97 codec\n");
675 goto codec_err; 639 return ret;
676 } 640 }
677 641
678 /* register pcms */
679 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
680 if (ret < 0)
681 goto pcm_err;
682
683 ret = wm9712_reset(codec, 0); 642 ret = wm9712_reset(codec, 0);
684 if (ret < 0) { 643 if (ret < 0) {
685 printk(KERN_ERR "Failed to reset WM9712: AC97 link error\n"); 644 printk(KERN_ERR "Failed to reset WM9712: AC97 link error\n");
@@ -697,42 +656,63 @@ static int wm9712_soc_probe(struct platform_device *pdev)
697 return 0; 656 return 0;
698 657
699reset_err: 658reset_err:
700 snd_soc_free_pcms(socdev);
701pcm_err:
702 snd_soc_free_ac97_codec(codec); 659 snd_soc_free_ac97_codec(codec);
703
704codec_err:
705 kfree(codec->reg_cache);
706
707cache_err:
708 kfree(socdev->card->codec);
709 socdev->card->codec = NULL;
710 return ret; 660 return ret;
711} 661}
712 662
713static int wm9712_soc_remove(struct platform_device *pdev) 663static int wm9712_soc_remove(struct snd_soc_codec *codec)
714{ 664{
715 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
716 struct snd_soc_codec *codec = socdev->card->codec;
717
718 if (codec == NULL)
719 return 0;
720
721 snd_soc_dapm_free(socdev);
722 snd_soc_free_pcms(socdev);
723 snd_soc_free_ac97_codec(codec); 665 snd_soc_free_ac97_codec(codec);
724 kfree(codec->reg_cache);
725 kfree(codec);
726 return 0; 666 return 0;
727} 667}
728 668
729struct snd_soc_codec_device soc_codec_dev_wm9712 = { 669static struct snd_soc_codec_driver soc_codec_dev_wm9712 = {
730 .probe = wm9712_soc_probe, 670 .probe = wm9712_soc_probe,
731 .remove = wm9712_soc_remove, 671 .remove = wm9712_soc_remove,
732 .suspend = wm9712_soc_suspend, 672 .suspend = wm9712_soc_suspend,
733 .resume = wm9712_soc_resume, 673 .resume = wm9712_soc_resume,
674 .read = ac97_read,
675 .write = ac97_write,
676 .set_bias_level = wm9712_set_bias_level,
677 .reg_cache_size = ARRAY_SIZE(wm9712_reg),
678 .reg_word_size = sizeof(u16),
679 .reg_cache_step = 2,
680 .reg_cache_default = wm9712_reg,
734}; 681};
735EXPORT_SYMBOL_GPL(soc_codec_dev_wm9712); 682
683static __devinit int wm9712_probe(struct platform_device *pdev)
684{
685 return snd_soc_register_codec(&pdev->dev,
686 &soc_codec_dev_wm9712, wm9712_dai, ARRAY_SIZE(wm9712_dai));
687}
688
689static int __devexit wm9712_remove(struct platform_device *pdev)
690{
691 snd_soc_unregister_codec(&pdev->dev);
692 return 0;
693}
694
695static struct platform_driver wm9712_codec_driver = {
696 .driver = {
697 .name = "wm9712-codec",
698 .owner = THIS_MODULE,
699 },
700
701 .probe = wm9712_probe,
702 .remove = __devexit_p(wm9712_remove),
703};
704
705static int __init wm9712_init(void)
706{
707 return platform_driver_register(&wm9712_codec_driver);
708}
709module_init(wm9712_init);
710
711static void __exit wm9712_exit(void)
712{
713 platform_driver_unregister(&wm9712_codec_driver);
714}
715module_exit(wm9712_exit);
736 716
737MODULE_DESCRIPTION("ASoC WM9711/WM9712 driver"); 717MODULE_DESCRIPTION("ASoC WM9711/WM9712 driver");
738MODULE_AUTHOR("Liam Girdwood"); 718MODULE_AUTHOR("Liam Girdwood");