aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/ak4671.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/codecs/ak4671.c')
-rw-r--r--sound/soc/codecs/ak4671.c141
1 files changed, 30 insertions, 111 deletions
diff --git a/sound/soc/codecs/ak4671.c b/sound/soc/codecs/ak4671.c
index 87566932a3b1..239f0562003c 100644
--- a/sound/soc/codecs/ak4671.c
+++ b/sound/soc/codecs/ak4671.c
@@ -23,11 +23,11 @@
23 23
24#include "ak4671.h" 24#include "ak4671.h"
25 25
26static struct snd_soc_codec *ak4671_codec;
27 26
28/* codec private data */ 27/* codec private data */
29struct ak4671_priv { 28struct ak4671_priv {
30 struct snd_soc_codec codec; 29 enum snd_soc_control_type control_type;
30 void *control_data;
31 u8 reg_cache[AK4671_CACHEREGNUM]; 31 u8 reg_cache[AK4671_CACHEREGNUM];
32}; 32};
33 33
@@ -619,8 +619,8 @@ static struct snd_soc_dai_ops ak4671_dai_ops = {
619 .set_fmt = ak4671_set_dai_fmt, 619 .set_fmt = ak4671_set_dai_fmt,
620}; 620};
621 621
622struct snd_soc_dai ak4671_dai = { 622static struct snd_soc_dai_driver ak4671_dai = {
623 .name = "AK4671", 623 .name = "ak4671-hifi",
624 .playback = { 624 .playback = {
625 .stream_name = "Playback", 625 .stream_name = "Playback",
626 .channels_min = 1, 626 .channels_min = 1,
@@ -635,27 +635,19 @@ struct snd_soc_dai ak4671_dai = {
635 .formats = AK4671_FORMATS,}, 635 .formats = AK4671_FORMATS,},
636 .ops = &ak4671_dai_ops, 636 .ops = &ak4671_dai_ops,
637}; 637};
638EXPORT_SYMBOL_GPL(ak4671_dai);
639 638
640static int ak4671_probe(struct platform_device *pdev) 639static int ak4671_probe(struct snd_soc_codec *codec)
641{ 640{
642 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 641 struct ak4671_priv *ak4671 = snd_soc_codec_get_drvdata(codec);
643 struct snd_soc_codec *codec; 642 int ret;
644 int ret = 0;
645
646 if (ak4671_codec == NULL) {
647 dev_err(&pdev->dev, "Codec device not registered\n");
648 return -ENODEV;
649 }
650 643
651 socdev->card->codec = ak4671_codec; 644 codec->hw_write = (hw_write_t)i2c_master_send;
652 codec = ak4671_codec; 645 codec->bias_level = SND_SOC_BIAS_OFF;
653 646
654 /* register pcms */ 647 ret = snd_soc_codec_set_cache_io(codec, 8, 8, ak4671->control_type);
655 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
656 if (ret < 0) { 648 if (ret < 0) {
657 dev_err(codec->dev, "failed to create pcms: %d\n", ret); 649 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
658 goto pcm_err; 650 return ret;
659 } 651 }
660 652
661 snd_soc_add_controls(codec, ak4671_snd_controls, 653 snd_soc_add_controls(codec, ak4671_snd_controls,
@@ -665,121 +657,48 @@ static int ak4671_probe(struct platform_device *pdev)
665 ak4671_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 657 ak4671_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
666 658
667 return ret; 659 return ret;
668
669pcm_err:
670 return ret;
671} 660}
672 661
673static int ak4671_remove(struct platform_device *pdev) 662static int ak4671_remove(struct snd_soc_codec *codec)
674{ 663{
675 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 664 ak4671_set_bias_level(codec, SND_SOC_BIAS_OFF);
676
677 snd_soc_free_pcms(socdev);
678 snd_soc_dapm_free(socdev);
679
680 return 0; 665 return 0;
681} 666}
682 667
683struct snd_soc_codec_device soc_codec_dev_ak4671 = { 668static struct snd_soc_codec_driver soc_codec_dev_ak4671 = {
684 .probe = ak4671_probe, 669 .probe = ak4671_probe,
685 .remove = ak4671_remove, 670 .remove = ak4671_remove,
671 .set_bias_level = ak4671_set_bias_level,
672 .reg_cache_size = AK4671_CACHEREGNUM,
673 .reg_word_size = sizeof(u8),
674 .reg_cache_default = ak4671_reg,
686}; 675};
687EXPORT_SYMBOL_GPL(soc_codec_dev_ak4671);
688
689static int ak4671_register(struct ak4671_priv *ak4671,
690 enum snd_soc_control_type control)
691{
692 int ret;
693 struct snd_soc_codec *codec = &ak4671->codec;
694
695 if (ak4671_codec) {
696 dev_err(codec->dev, "Another AK4671 is registered\n");
697 ret = -EINVAL;
698 goto err;
699 }
700
701 mutex_init(&codec->mutex);
702 INIT_LIST_HEAD(&codec->dapm_widgets);
703 INIT_LIST_HEAD(&codec->dapm_paths);
704
705 snd_soc_codec_set_drvdata(codec, ak4671);
706 codec->name = "AK4671";
707 codec->owner = THIS_MODULE;
708 codec->bias_level = SND_SOC_BIAS_OFF;
709 codec->set_bias_level = ak4671_set_bias_level;
710 codec->dai = &ak4671_dai;
711 codec->num_dai = 1;
712 codec->reg_cache_size = AK4671_CACHEREGNUM;
713 codec->reg_cache = &ak4671->reg_cache;
714
715 memcpy(codec->reg_cache, ak4671_reg, sizeof(ak4671_reg));
716
717 ret = snd_soc_codec_set_cache_io(codec, 8, 8, control);
718 if (ret < 0) {
719 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
720 goto err;
721 }
722
723 ak4671_dai.dev = codec->dev;
724 ak4671_codec = codec;
725
726 ret = snd_soc_register_codec(codec);
727 if (ret != 0) {
728 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
729 goto err;
730 }
731
732 ret = snd_soc_register_dai(&ak4671_dai);
733 if (ret != 0) {
734 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
735 goto err_codec;
736 }
737
738 return 0;
739
740err_codec:
741 snd_soc_unregister_codec(codec);
742err:
743 kfree(ak4671);
744 return ret;
745}
746
747static void ak4671_unregister(struct ak4671_priv *ak4671)
748{
749 ak4671_set_bias_level(&ak4671->codec, SND_SOC_BIAS_OFF);
750 snd_soc_unregister_dai(&ak4671_dai);
751 snd_soc_unregister_codec(&ak4671->codec);
752 kfree(ak4671);
753 ak4671_codec = NULL;
754}
755 676
756static int __devinit ak4671_i2c_probe(struct i2c_client *client, 677static int __devinit ak4671_i2c_probe(struct i2c_client *client,
757 const struct i2c_device_id *id) 678 const struct i2c_device_id *id)
758{ 679{
759 struct ak4671_priv *ak4671; 680 struct ak4671_priv *ak4671;
760 struct snd_soc_codec *codec; 681 int ret;
761 682
762 ak4671 = kzalloc(sizeof(struct ak4671_priv), GFP_KERNEL); 683 ak4671 = kzalloc(sizeof(struct ak4671_priv), GFP_KERNEL);
763 if (ak4671 == NULL) 684 if (ak4671 == NULL)
764 return -ENOMEM; 685 return -ENOMEM;
765 686
766 codec = &ak4671->codec;
767 codec->hw_write = (hw_write_t)i2c_master_send;
768
769 i2c_set_clientdata(client, ak4671); 687 i2c_set_clientdata(client, ak4671);
770 codec->control_data = client; 688 ak4671->control_data = client;
771 689 ak4671->control_type = SND_SOC_I2C;
772 codec->dev = &client->dev;
773 690
774 return ak4671_register(ak4671, SND_SOC_I2C); 691 ret = snd_soc_register_codec(&client->dev,
692 &soc_codec_dev_ak4671, &ak4671_dai, 1);
693 if (ret < 0)
694 kfree(ak4671);
695 return ret;
775} 696}
776 697
777static __devexit int ak4671_i2c_remove(struct i2c_client *client) 698static __devexit int ak4671_i2c_remove(struct i2c_client *client)
778{ 699{
779 struct ak4671_priv *ak4671 = i2c_get_clientdata(client); 700 snd_soc_unregister_codec(&client->dev);
780 701 kfree(i2c_get_clientdata(client));
781 ak4671_unregister(ak4671);
782
783 return 0; 702 return 0;
784} 703}
785 704
@@ -791,7 +710,7 @@ MODULE_DEVICE_TABLE(i2c, ak4671_i2c_id);
791 710
792static struct i2c_driver ak4671_i2c_driver = { 711static struct i2c_driver ak4671_i2c_driver = {
793 .driver = { 712 .driver = {
794 .name = "ak4671", 713 .name = "ak4671-codec",
795 .owner = THIS_MODULE, 714 .owner = THIS_MODULE,
796 }, 715 },
797 .probe = ak4671_i2c_probe, 716 .probe = ak4671_i2c_probe,