aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/wm8580.c
diff options
context:
space:
mode:
authorMark Brown <broonie@opensource.wolfsonmicro.com>2010-08-12 09:40:28 -0400
committerMark Brown <broonie@opensource.wolfsonmicro.com>2010-08-12 09:40:28 -0400
commitcf7af01aa77ec1b17687f5328ce0a598709efd59 (patch)
tree4cc46339721366c7498dacf5ebac01906be273e7 /sound/soc/codecs/wm8580.c
parent6f341d14811550d863ba804ce6ec7757a7145081 (diff)
parent5dcba5d6741d4533e0ef696507f93f2a4c738efb (diff)
Merge branch 'topic/multi-component' of git://git.kernel.org/pub/scm/linux/kernel/git/lrg/asoc-2.6 into for-2.6.37
Diffstat (limited to 'sound/soc/codecs/wm8580.c')
-rw-r--r--sound/soc/codecs/wm8580.c183
1 files changed, 51 insertions, 132 deletions
diff --git a/sound/soc/codecs/wm8580.c b/sound/soc/codecs/wm8580.c
index 1881b16bc248..b1a80e5ff8b5 100644
--- a/sound/soc/codecs/wm8580.c
+++ b/sound/soc/codecs/wm8580.c
@@ -199,7 +199,7 @@ static const char *wm8580_supply_names[WM8580_NUM_SUPPLIES] = {
199 199
200/* codec private data */ 200/* codec private data */
201struct wm8580_priv { 201struct wm8580_priv {
202 struct snd_soc_codec codec; 202 enum snd_soc_control_type control_type;
203 struct regulator_bulk_data supplies[WM8580_NUM_SUPPLIES]; 203 struct regulator_bulk_data supplies[WM8580_NUM_SUPPLIES];
204 u16 reg_cache[WM8580_MAX_REGISTER + 1]; 204 u16 reg_cache[WM8580_MAX_REGISTER + 1];
205 struct pll_state a; 205 struct pll_state a;
@@ -484,9 +484,8 @@ static int wm8580_paif_hw_params(struct snd_pcm_substream *substream,
484 struct snd_soc_dai *dai) 484 struct snd_soc_dai *dai)
485{ 485{
486 struct snd_soc_pcm_runtime *rtd = substream->private_data; 486 struct snd_soc_pcm_runtime *rtd = substream->private_data;
487 struct snd_soc_device *socdev = rtd->socdev; 487 struct snd_soc_codec *codec = rtd->codec;
488 struct snd_soc_codec *codec = socdev->card->codec; 488 u16 paifb = snd_soc_read(codec, WM8580_PAIF3 + dai->driver->id);
489 u16 paifb = snd_soc_read(codec, WM8580_PAIF3 + dai->id);
490 489
491 paifb &= ~WM8580_AIF_LENGTH_MASK; 490 paifb &= ~WM8580_AIF_LENGTH_MASK;
492 /* bit size */ 491 /* bit size */
@@ -506,7 +505,7 @@ static int wm8580_paif_hw_params(struct snd_pcm_substream *substream,
506 return -EINVAL; 505 return -EINVAL;
507 } 506 }
508 507
509 snd_soc_write(codec, WM8580_PAIF3 + dai->id, paifb); 508 snd_soc_write(codec, WM8580_PAIF3 + dai->driver->id, paifb);
510 return 0; 509 return 0;
511} 510}
512 511
@@ -518,8 +517,8 @@ static int wm8580_set_paif_dai_fmt(struct snd_soc_dai *codec_dai,
518 unsigned int aifb; 517 unsigned int aifb;
519 int can_invert_lrclk; 518 int can_invert_lrclk;
520 519
521 aifa = snd_soc_read(codec, WM8580_PAIF1 + codec_dai->id); 520 aifa = snd_soc_read(codec, WM8580_PAIF1 + codec_dai->driver->id);
522 aifb = snd_soc_read(codec, WM8580_PAIF3 + codec_dai->id); 521 aifb = snd_soc_read(codec, WM8580_PAIF3 + codec_dai->driver->id);
523 522
524 aifb &= ~(WM8580_AIF_FMT_MASK | WM8580_AIF_LRP | WM8580_AIF_BCP); 523 aifb &= ~(WM8580_AIF_FMT_MASK | WM8580_AIF_LRP | WM8580_AIF_BCP);
525 524
@@ -585,8 +584,8 @@ static int wm8580_set_paif_dai_fmt(struct snd_soc_dai *codec_dai,
585 return -EINVAL; 584 return -EINVAL;
586 } 585 }
587 586
588 snd_soc_write(codec, WM8580_PAIF1 + codec_dai->id, aifa); 587 snd_soc_write(codec, WM8580_PAIF1 + codec_dai->driver->id, aifa);
589 snd_soc_write(codec, WM8580_PAIF3 + codec_dai->id, aifb); 588 snd_soc_write(codec, WM8580_PAIF3 + codec_dai->driver->id, aifb);
590 589
591 return 0; 590 return 0;
592} 591}
@@ -746,10 +745,10 @@ static struct snd_soc_dai_ops wm8580_dai_ops_capture = {
746 .set_pll = wm8580_set_dai_pll, 745 .set_pll = wm8580_set_dai_pll,
747}; 746};
748 747
749struct snd_soc_dai wm8580_dai[] = { 748static struct snd_soc_dai_driver wm8580_dai[] = {
750 { 749 {
751 .name = "WM8580 PAIFRX", 750 .name = "wm8580-hifi-playback",
752 .id = 0, 751 .id = WM8580_DAI_PAIFRX,
753 .playback = { 752 .playback = {
754 .stream_name = "Playback", 753 .stream_name = "Playback",
755 .channels_min = 1, 754 .channels_min = 1,
@@ -760,8 +759,8 @@ struct snd_soc_dai wm8580_dai[] = {
760 .ops = &wm8580_dai_ops_playback, 759 .ops = &wm8580_dai_ops_playback,
761 }, 760 },
762 { 761 {
763 .name = "WM8580 PAIFTX", 762 .name = "wm8580-hifi-capture",
764 .id = 1, 763 .id = WM8580_DAI_PAIFTX,
765 .capture = { 764 .capture = {
766 .stream_name = "Capture", 765 .stream_name = "Capture",
767 .channels_min = 2, 766 .channels_min = 2,
@@ -772,90 +771,16 @@ struct snd_soc_dai wm8580_dai[] = {
772 .ops = &wm8580_dai_ops_capture, 771 .ops = &wm8580_dai_ops_capture,
773 }, 772 },
774}; 773};
775EXPORT_SYMBOL_GPL(wm8580_dai);
776 774
777static struct snd_soc_codec *wm8580_codec; 775static int wm8580_probe(struct snd_soc_codec *codec)
778
779static int wm8580_probe(struct platform_device *pdev)
780{ 776{
781 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 777 struct wm8580_priv *wm8580 = snd_soc_codec_get_drvdata(codec);
782 struct snd_soc_codec *codec; 778 int ret = 0,i;
783 int ret = 0;
784
785 if (wm8580_codec == NULL) {
786 dev_err(&pdev->dev, "Codec device not registered\n");
787 return -ENODEV;
788 }
789
790 socdev->card->codec = wm8580_codec;
791 codec = wm8580_codec;
792
793 /* register pcms */
794 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
795 if (ret < 0) {
796 dev_err(codec->dev, "failed to create pcms: %d\n", ret);
797 goto pcm_err;
798 }
799
800 snd_soc_add_controls(codec, wm8580_snd_controls,
801 ARRAY_SIZE(wm8580_snd_controls));
802 wm8580_add_widgets(codec);
803
804 return ret;
805
806pcm_err:
807 return ret;
808}
809
810/* power down chip */
811static int wm8580_remove(struct platform_device *pdev)
812{
813 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
814
815 snd_soc_free_pcms(socdev);
816 snd_soc_dapm_free(socdev);
817
818 return 0;
819}
820
821struct snd_soc_codec_device soc_codec_dev_wm8580 = {
822 .probe = wm8580_probe,
823 .remove = wm8580_remove,
824};
825EXPORT_SYMBOL_GPL(soc_codec_dev_wm8580);
826
827static int wm8580_register(struct wm8580_priv *wm8580,
828 enum snd_soc_control_type control)
829{
830 int ret, i;
831 struct snd_soc_codec *codec = &wm8580->codec;
832
833 if (wm8580_codec) {
834 dev_err(codec->dev, "Another WM8580 is registered\n");
835 ret = -EINVAL;
836 goto err;
837 }
838
839 mutex_init(&codec->mutex);
840 INIT_LIST_HEAD(&codec->dapm_widgets);
841 INIT_LIST_HEAD(&codec->dapm_paths);
842
843 snd_soc_codec_set_drvdata(codec, wm8580);
844 codec->name = "WM8580";
845 codec->owner = THIS_MODULE;
846 codec->bias_level = SND_SOC_BIAS_OFF;
847 codec->set_bias_level = wm8580_set_bias_level;
848 codec->dai = wm8580_dai;
849 codec->num_dai = ARRAY_SIZE(wm8580_dai);
850 codec->reg_cache_size = ARRAY_SIZE(wm8580->reg_cache);
851 codec->reg_cache = &wm8580->reg_cache;
852
853 memcpy(codec->reg_cache, wm8580_reg, sizeof(wm8580_reg));
854 779
855 ret = snd_soc_codec_set_cache_io(codec, 7, 9, control); 780 ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8580->control_type);
856 if (ret < 0) { 781 if (ret < 0) {
857 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); 782 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
858 goto err; 783 return ret;
859 } 784 }
860 785
861 for (i = 0; i < ARRAY_SIZE(wm8580->supplies); i++) 786 for (i = 0; i < ARRAY_SIZE(wm8580->supplies); i++)
@@ -865,7 +790,7 @@ static int wm8580_register(struct wm8580_priv *wm8580,
865 wm8580->supplies); 790 wm8580->supplies);
866 if (ret != 0) { 791 if (ret != 0) {
867 dev_err(codec->dev, "Failed to request supplies: %d\n", ret); 792 dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
868 goto err; 793 return ret;
869 } 794 }
870 795
871 ret = regulator_bulk_enable(ARRAY_SIZE(wm8580->supplies), 796 ret = regulator_bulk_enable(ARRAY_SIZE(wm8580->supplies),
@@ -882,74 +807,68 @@ static int wm8580_register(struct wm8580_priv *wm8580,
882 goto err_regulator_enable; 807 goto err_regulator_enable;
883 } 808 }
884 809
885 for (i = 0; i < ARRAY_SIZE(wm8580_dai); i++)
886 wm8580_dai[i].dev = codec->dev;
887
888 wm8580_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 810 wm8580_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
889 811
890 wm8580_codec = codec; 812 snd_soc_add_controls(codec, wm8580_snd_controls,
891 813 ARRAY_SIZE(wm8580_snd_controls));
892 ret = snd_soc_register_codec(codec); 814 wm8580_add_widgets(codec);
893 if (ret != 0) {
894 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
895 goto err_regulator_enable;
896 }
897
898 ret = snd_soc_register_dais(wm8580_dai, ARRAY_SIZE(wm8580_dai));
899 if (ret != 0) {
900 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
901 goto err_codec;
902 }
903 815
904 return 0; 816 return 0;
905 817
906err_codec:
907 snd_soc_unregister_codec(codec);
908err_regulator_enable: 818err_regulator_enable:
909 regulator_bulk_disable(ARRAY_SIZE(wm8580->supplies), wm8580->supplies); 819 regulator_bulk_disable(ARRAY_SIZE(wm8580->supplies), wm8580->supplies);
910err_regulator_get: 820err_regulator_get:
911 regulator_bulk_free(ARRAY_SIZE(wm8580->supplies), wm8580->supplies); 821 regulator_bulk_free(ARRAY_SIZE(wm8580->supplies), wm8580->supplies);
912err:
913 kfree(wm8580);
914 return ret; 822 return ret;
915} 823}
916 824
917static void wm8580_unregister(struct wm8580_priv *wm8580) 825/* power down chip */
826static int wm8580_remove(struct snd_soc_codec *codec)
918{ 827{
919 wm8580_set_bias_level(&wm8580->codec, SND_SOC_BIAS_OFF); 828 struct wm8580_priv *wm8580 = snd_soc_codec_get_drvdata(codec);
920 snd_soc_unregister_dais(wm8580_dai, ARRAY_SIZE(wm8580_dai)); 829
921 snd_soc_unregister_codec(&wm8580->codec); 830 wm8580_set_bias_level(codec, SND_SOC_BIAS_OFF);
831
922 regulator_bulk_disable(ARRAY_SIZE(wm8580->supplies), wm8580->supplies); 832 regulator_bulk_disable(ARRAY_SIZE(wm8580->supplies), wm8580->supplies);
923 regulator_bulk_free(ARRAY_SIZE(wm8580->supplies), wm8580->supplies); 833 regulator_bulk_free(ARRAY_SIZE(wm8580->supplies), wm8580->supplies);
924 kfree(wm8580); 834
925 wm8580_codec = NULL; 835 return 0;
926} 836}
927 837
838static struct snd_soc_codec_driver soc_codec_dev_wm8580 = {
839 .probe = wm8580_probe,
840 .remove = wm8580_remove,
841 .set_bias_level = wm8580_set_bias_level,
842 .reg_cache_size = sizeof(wm8580_reg),
843 .reg_word_size = sizeof(u16),
844 .reg_cache_default = &wm8580_reg,
845};
846
928#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 847#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
929static int wm8580_i2c_probe(struct i2c_client *i2c, 848static int wm8580_i2c_probe(struct i2c_client *i2c,
930 const struct i2c_device_id *id) 849 const struct i2c_device_id *id)
931{ 850{
932 struct wm8580_priv *wm8580; 851 struct wm8580_priv *wm8580;
933 struct snd_soc_codec *codec; 852 int ret;
934 853
935 wm8580 = kzalloc(sizeof(struct wm8580_priv), GFP_KERNEL); 854 wm8580 = kzalloc(sizeof(struct wm8580_priv), GFP_KERNEL);
936 if (wm8580 == NULL) 855 if (wm8580 == NULL)
937 return -ENOMEM; 856 return -ENOMEM;
938 857
939 codec = &wm8580->codec;
940
941 i2c_set_clientdata(i2c, wm8580); 858 i2c_set_clientdata(i2c, wm8580);
942 codec->control_data = i2c; 859 wm8580->control_type = SND_SOC_I2C;
943
944 codec->dev = &i2c->dev;
945 860
946 return wm8580_register(wm8580, SND_SOC_I2C); 861 ret = snd_soc_register_codec(&i2c->dev,
862 &soc_codec_dev_wm8580, wm8580_dai, ARRAY_SIZE(wm8580_dai));
863 if (ret < 0)
864 kfree(wm8580);
865 return ret;
947} 866}
948 867
949static int wm8580_i2c_remove(struct i2c_client *client) 868static int wm8580_i2c_remove(struct i2c_client *client)
950{ 869{
951 struct wm8580_priv *wm8580 = i2c_get_clientdata(client); 870 snd_soc_unregister_codec(&client->dev);
952 wm8580_unregister(wm8580); 871 kfree(i2c_get_clientdata(client));
953 return 0; 872 return 0;
954} 873}
955 874
@@ -961,7 +880,7 @@ MODULE_DEVICE_TABLE(i2c, wm8580_i2c_id);
961 880
962static struct i2c_driver wm8580_i2c_driver = { 881static struct i2c_driver wm8580_i2c_driver = {
963 .driver = { 882 .driver = {
964 .name = "wm8580", 883 .name = "wm8580-codec",
965 .owner = THIS_MODULE, 884 .owner = THIS_MODULE,
966 }, 885 },
967 .probe = wm8580_i2c_probe, 886 .probe = wm8580_i2c_probe,
@@ -972,7 +891,7 @@ static struct i2c_driver wm8580_i2c_driver = {
972 891
973static int __init wm8580_modinit(void) 892static int __init wm8580_modinit(void)
974{ 893{
975 int ret; 894 int ret = 0;
976 895
977#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 896#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
978 ret = i2c_add_driver(&wm8580_i2c_driver); 897 ret = i2c_add_driver(&wm8580_i2c_driver);
@@ -981,7 +900,7 @@ static int __init wm8580_modinit(void)
981 } 900 }
982#endif 901#endif
983 902
984 return 0; 903 return ret;
985} 904}
986module_init(wm8580_modinit); 905module_init(wm8580_modinit);
987 906