aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sound/soc/codecs/wm8750.c295
-rw-r--r--sound/soc/pxa/spitz.c43
-rw-r--r--sound/soc/s3c24xx/jive_wm8750.c5
3 files changed, 175 insertions, 168 deletions
diff --git a/sound/soc/codecs/wm8750.c b/sound/soc/codecs/wm8750.c
index ee084083a49d..4bbc512c0836 100644
--- a/sound/soc/codecs/wm8750.c
+++ b/sound/soc/codecs/wm8750.c
@@ -29,11 +29,6 @@
29 29
30#include "wm8750.h" 30#include "wm8750.h"
31 31
32/* codec private data */
33struct wm8750_priv {
34 unsigned int sysclk;
35};
36
37/* 32/*
38 * wm8750 register cache 33 * wm8750 register cache
39 * We can't read the WM8750 register space when we 34 * We can't read the WM8750 register space when we
@@ -53,6 +48,13 @@ static const u16 wm8750_reg[] = {
53 0x0079, 0x0079, 0x0079, /* 40 */ 48 0x0079, 0x0079, 0x0079, /* 40 */
54}; 49};
55 50
51/* codec private data */
52struct wm8750_priv {
53 unsigned int sysclk;
54 struct snd_soc_codec codec;
55 u16 reg_cache[ARRAY_SIZE(wm8750_reg)];
56};
57
56#define wm8750_reset(c) snd_soc_write(c, WM8750_RESET, 0) 58#define wm8750_reset(c) snd_soc_write(c, WM8750_RESET, 0)
57 59
58/* 60/*
@@ -695,25 +697,90 @@ static int wm8750_resume(struct platform_device *pdev)
695 return 0; 697 return 0;
696} 698}
697 699
700static struct snd_soc_codec *wm8750_codec;
701
702static int wm8750_probe(struct platform_device *pdev)
703{
704 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
705 struct snd_soc_codec *codec;
706 int ret = 0;
707
708 if (!wm8750_codec) {
709 dev_err(&pdev->dev, "WM8750 codec not yet registered\n");
710 return -EINVAL;
711 }
712
713 socdev->card->codec = wm8750_codec;
714 codec = wm8750_codec;
715
716 /* register pcms */
717 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
718 if (ret < 0) {
719 printk(KERN_ERR "wm8750: failed to create pcms\n");
720 goto err;
721 }
722
723 snd_soc_add_controls(codec, wm8750_snd_controls,
724 ARRAY_SIZE(wm8750_snd_controls));
725 wm8750_add_widgets(codec);
726
727 return 0;
728
729err:
730 return ret;
731}
732
733/* power down chip */
734static int wm8750_remove(struct platform_device *pdev)
735{
736 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
737
738 snd_soc_free_pcms(socdev);
739 snd_soc_dapm_free(socdev);
740
741 return 0;
742}
743
744struct snd_soc_codec_device soc_codec_dev_wm8750 = {
745 .probe = wm8750_probe,
746 .remove = wm8750_remove,
747 .suspend = wm8750_suspend,
748 .resume = wm8750_resume,
749};
750EXPORT_SYMBOL_GPL(soc_codec_dev_wm8750);
751
698/* 752/*
699 * initialise the WM8750 driver 753 * initialise the WM8750 driver
700 * register the mixer and dsp interfaces with the kernel 754 * register the mixer and dsp interfaces with the kernel
701 */ 755 */
702static int wm8750_init(struct snd_soc_device *socdev, 756static int wm8750_register(struct wm8750_priv *wm8750,
703 enum snd_soc_control_type control) 757 enum snd_soc_control_type control)
704{ 758{
705 struct snd_soc_codec *codec = socdev->card->codec; 759 struct snd_soc_codec *codec = &wm8750->codec;
706 int reg, ret = 0; 760 int reg, ret = 0;
707 761
762 if (wm8750_codec) {
763 dev_err(codec->dev, "Multiple WM8750 devices not supported\n");
764 ret = -EINVAL;
765 goto err;
766 }
767
768 mutex_init(&codec->mutex);
769 INIT_LIST_HEAD(&codec->dapm_widgets);
770 INIT_LIST_HEAD(&codec->dapm_paths);
771
708 codec->name = "WM8750"; 772 codec->name = "WM8750";
709 codec->owner = THIS_MODULE; 773 codec->owner = THIS_MODULE;
774 codec->bias_level = SND_SOC_BIAS_STANDBY;
710 codec->set_bias_level = wm8750_set_bias_level; 775 codec->set_bias_level = wm8750_set_bias_level;
711 codec->dai = &wm8750_dai; 776 codec->dai = &wm8750_dai;
712 codec->num_dai = 1; 777 codec->num_dai = 1;
713 codec->reg_cache_size = ARRAY_SIZE(wm8750_reg); 778 codec->private_data = wm8750;
714 codec->reg_cache = kmemdup(wm8750_reg, sizeof(wm8750_reg), GFP_KERNEL); 779 codec->reg_cache_size = ARRAY_SIZE(wm8750->reg_cache) + 1;
715 if (codec->reg_cache == NULL) 780 codec->reg_cache = &wm8750->reg_cache;
716 return -ENOMEM; 781 codec->private_data = wm8750;
782
783 memcpy(codec->reg_cache, wm8750_reg, sizeof(wm8750->reg_cache));
717 784
718 ret = snd_soc_codec_set_cache_io(codec, 7, 9, control); 785 ret = snd_soc_codec_set_cache_io(codec, 7, 9, control);
719 if (ret < 0) { 786 if (ret < 0) {
@@ -727,13 +794,6 @@ static int wm8750_init(struct snd_soc_device *socdev,
727 goto err; 794 goto err;
728 } 795 }
729 796
730 /* register pcms */
731 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
732 if (ret < 0) {
733 printk(KERN_ERR "wm8750: failed to create pcms\n");
734 goto err;
735 }
736
737 /* charge output caps */ 797 /* charge output caps */
738 wm8750_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 798 wm8750_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
739 799
@@ -755,19 +815,37 @@ static int wm8750_init(struct snd_soc_device *socdev,
755 reg = snd_soc_read(codec, WM8750_RINVOL); 815 reg = snd_soc_read(codec, WM8750_RINVOL);
756 snd_soc_write(codec, WM8750_RINVOL, reg | 0x0100); 816 snd_soc_write(codec, WM8750_RINVOL, reg | 0x0100);
757 817
758 snd_soc_add_controls(codec, wm8750_snd_controls, 818 wm8750_codec = codec;
759 ARRAY_SIZE(wm8750_snd_controls));
760 wm8750_add_widgets(codec);
761 return ret;
762 819
820 ret = snd_soc_register_codec(codec);
821 if (ret != 0) {
822 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
823 goto err;
824 }
825
826 ret = snd_soc_register_dais(&wm8750_dai, 1);
827 if (ret != 0) {
828 dev_err(codec->dev, "Failed to register DAIs: %d\n", ret);
829 goto err_codec;
830 }
831
832 return 0;
833
834err_codec:
835 snd_soc_unregister_codec(codec);
763err: 836err:
764 kfree(codec->reg_cache); 837 kfree(wm8750);
765 return ret; 838 return ret;
766} 839}
767 840
768/* If the i2c layer weren't so broken, we could pass this kind of data 841static void wm8750_unregister(struct wm8750_priv *wm8750)
769 around */ 842{
770static struct snd_soc_device *wm8750_socdev; 843 wm8750_set_bias_level(&wm8750->codec, SND_SOC_BIAS_OFF);
844 snd_soc_unregister_dais(&wm8750_dai, 1);
845 snd_soc_unregister_codec(&wm8750->codec);
846 kfree(wm8750);
847 wm8750_codec = NULL;
848}
771 849
772#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 850#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
773 851
@@ -781,24 +859,26 @@ static struct snd_soc_device *wm8750_socdev;
781static int wm8750_i2c_probe(struct i2c_client *i2c, 859static int wm8750_i2c_probe(struct i2c_client *i2c,
782 const struct i2c_device_id *id) 860 const struct i2c_device_id *id)
783{ 861{
784 struct snd_soc_device *socdev = wm8750_socdev; 862 struct snd_soc_codec *codec;
785 struct snd_soc_codec *codec = socdev->card->codec; 863 struct wm8750_priv *wm8750;
786 int ret;
787 864
788 i2c_set_clientdata(i2c, codec); 865 wm8750 = kzalloc(sizeof(struct wm8750_priv), GFP_KERNEL);
866 if (wm8750 == NULL)
867 return -ENOMEM;
868
869 codec = &wm8750->codec;
789 codec->control_data = i2c; 870 codec->control_data = i2c;
871 i2c_set_clientdata(i2c, wm8750);
790 872
791 ret = wm8750_init(socdev, SND_SOC_I2C); 873 codec->dev = &i2c->dev;
792 if (ret < 0)
793 pr_err("failed to initialise WM8750\n");
794 874
795 return ret; 875 return wm8750_register(wm8750, SND_SOC_I2C);
796} 876}
797 877
798static int wm8750_i2c_remove(struct i2c_client *client) 878static int wm8750_i2c_remove(struct i2c_client *client)
799{ 879{
800 struct snd_soc_codec *codec = i2c_get_clientdata(client); 880 struct wm8750_priv *wm8750 = i2c_get_clientdata(client);
801 kfree(codec->reg_cache); 881 wm8750_unregister(wm8750);
802 return 0; 882 return 0;
803} 883}
804 884
@@ -817,66 +897,31 @@ static struct i2c_driver wm8750_i2c_driver = {
817 .remove = wm8750_i2c_remove, 897 .remove = wm8750_i2c_remove,
818 .id_table = wm8750_i2c_id, 898 .id_table = wm8750_i2c_id,
819}; 899};
820
821static int wm8750_add_i2c_device(struct platform_device *pdev,
822 const struct wm8750_setup_data *setup)
823{
824 struct i2c_board_info info;
825 struct i2c_adapter *adapter;
826 struct i2c_client *client;
827 int ret;
828
829 ret = i2c_add_driver(&wm8750_i2c_driver);
830 if (ret != 0) {
831 dev_err(&pdev->dev, "can't add i2c driver\n");
832 return ret;
833 }
834
835 memset(&info, 0, sizeof(struct i2c_board_info));
836 info.addr = setup->i2c_address;
837 strlcpy(info.type, "wm8750", I2C_NAME_SIZE);
838
839 adapter = i2c_get_adapter(setup->i2c_bus);
840 if (!adapter) {
841 dev_err(&pdev->dev, "can't get i2c adapter %d\n",
842 setup->i2c_bus);
843 goto err_driver;
844 }
845
846 client = i2c_new_device(adapter, &info);
847 i2c_put_adapter(adapter);
848 if (!client) {
849 dev_err(&pdev->dev, "can't add i2c device at 0x%x\n",
850 (unsigned int)info.addr);
851 goto err_driver;
852 }
853
854 return 0;
855
856err_driver:
857 i2c_del_driver(&wm8750_i2c_driver);
858 return -ENODEV;
859}
860#endif 900#endif
861 901
862#if defined(CONFIG_SPI_MASTER) 902#if defined(CONFIG_SPI_MASTER)
863static int __devinit wm8750_spi_probe(struct spi_device *spi) 903static int __devinit wm8750_spi_probe(struct spi_device *spi)
864{ 904{
865 struct snd_soc_device *socdev = wm8750_socdev; 905 struct snd_soc_codec *codec;
866 struct snd_soc_codec *codec = socdev->card->codec; 906 struct wm8750_priv *wm8750;
867 int ret;
868 907
908 wm8750 = kzalloc(sizeof(struct wm8750_priv), GFP_KERNEL);
909 if (wm8750 == NULL)
910 return -ENOMEM;
911
912 codec = &wm8750->codec;
869 codec->control_data = spi; 913 codec->control_data = spi;
914 codec->dev = &spi->dev;
870 915
871 ret = wm8750_init(socdev, SND_SOC_SPI); 916 dev_set_drvdata(&spi->dev, wm8750);
872 if (ret < 0)
873 dev_err(&spi->dev, "failed to initialise WM8750\n");
874 917
875 return ret; 918 return wm8750_register(wm8750, SND_SOC_SPI);
876} 919}
877 920
878static int __devexit wm8750_spi_remove(struct spi_device *spi) 921static int __devexit wm8750_spi_remove(struct spi_device *spi)
879{ 922{
923 struct wm8750_priv *wm8750 = dev_get_drvdata(&spi->dev);
924 wm8750_unregister(wm8750);
880 return 0; 925 return 0;
881} 926}
882 927
@@ -891,93 +936,31 @@ static struct spi_driver wm8750_spi_driver = {
891}; 936};
892#endif 937#endif
893 938
894static int wm8750_probe(struct platform_device *pdev) 939static int __init wm8750_modinit(void)
895{ 940{
896 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
897 struct wm8750_setup_data *setup = socdev->codec_data;
898 struct snd_soc_codec *codec;
899 struct wm8750_priv *wm8750;
900 int ret; 941 int ret;
901
902 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
903 if (codec == NULL)
904 return -ENOMEM;
905
906 wm8750 = kzalloc(sizeof(struct wm8750_priv), GFP_KERNEL);
907 if (wm8750 == NULL) {
908 kfree(codec);
909 return -ENOMEM;
910 }
911
912 codec->private_data = wm8750;
913 socdev->card->codec = codec;
914 mutex_init(&codec->mutex);
915 INIT_LIST_HEAD(&codec->dapm_widgets);
916 INIT_LIST_HEAD(&codec->dapm_paths);
917 wm8750_socdev = socdev;
918
919 ret = -ENODEV;
920
921#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 942#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
922 if (setup->i2c_address) { 943 ret = i2c_add_driver(&wm8750_i2c_driver);
923 ret = wm8750_add_i2c_device(pdev, setup); 944 if (ret != 0)
924 } 945 pr_err("Failed to register WM8750 I2C driver: %d\n", ret);
925#endif 946#endif
926#if defined(CONFIG_SPI_MASTER) 947#if defined(CONFIG_SPI_MASTER)
927 if (setup->spi) { 948 ret = spi_register_driver(&wm8750_spi_driver);
928 ret = spi_register_driver(&wm8750_spi_driver); 949 if (ret != 0)
929 if (ret != 0) 950 pr_err("Failed to register WM8750 SPI driver: %d\n", ret);
930 printk(KERN_ERR "can't add spi driver");
931 }
932#endif 951#endif
933 952 return 0;
934 if (ret != 0) {
935 kfree(codec->private_data);
936 kfree(codec);
937 }
938 return ret;
939} 953}
954module_init(wm8750_modinit);
940 955
941/* power down chip */ 956static void __exit wm8750_exit(void)
942static int wm8750_remove(struct platform_device *pdev)
943{ 957{
944 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
945 struct snd_soc_codec *codec = socdev->card->codec;
946
947 if (codec->control_data)
948 wm8750_set_bias_level(codec, SND_SOC_BIAS_OFF);
949 snd_soc_free_pcms(socdev);
950 snd_soc_dapm_free(socdev);
951#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 958#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
952 i2c_unregister_device(codec->control_data);
953 i2c_del_driver(&wm8750_i2c_driver); 959 i2c_del_driver(&wm8750_i2c_driver);
954#endif 960#endif
955#if defined(CONFIG_SPI_MASTER) 961#if defined(CONFIG_SPI_MASTER)
956 spi_unregister_driver(&wm8750_spi_driver); 962 spi_unregister_driver(&wm8750_spi_driver);
957#endif 963#endif
958 kfree(codec->private_data);
959 kfree(codec);
960
961 return 0;
962}
963
964struct snd_soc_codec_device soc_codec_dev_wm8750 = {
965 .probe = wm8750_probe,
966 .remove = wm8750_remove,
967 .suspend = wm8750_suspend,
968 .resume = wm8750_resume,
969};
970EXPORT_SYMBOL_GPL(soc_codec_dev_wm8750);
971
972static int __init wm8750_modinit(void)
973{
974 return snd_soc_register_dai(&wm8750_dai);
975}
976module_init(wm8750_modinit);
977
978static void __exit wm8750_exit(void)
979{
980 snd_soc_unregister_dai(&wm8750_dai);
981} 964}
982module_exit(wm8750_exit); 965module_exit(wm8750_exit);
983 966
diff --git a/sound/soc/pxa/spitz.c b/sound/soc/pxa/spitz.c
index c4cd2acaacb4..1941a357e8c4 100644
--- a/sound/soc/pxa/spitz.c
+++ b/sound/soc/pxa/spitz.c
@@ -322,19 +322,44 @@ static struct snd_soc_card snd_soc_spitz = {
322 .num_links = 1, 322 .num_links = 1,
323}; 323};
324 324
325/* spitz audio private data */
326static struct wm8750_setup_data spitz_wm8750_setup = {
327 .i2c_bus = 0,
328 .i2c_address = 0x1b,
329};
330
331/* spitz audio subsystem */ 325/* spitz audio subsystem */
332static struct snd_soc_device spitz_snd_devdata = { 326static struct snd_soc_device spitz_snd_devdata = {
333 .card = &snd_soc_spitz, 327 .card = &snd_soc_spitz,
334 .codec_dev = &soc_codec_dev_wm8750, 328 .codec_dev = &soc_codec_dev_wm8750,
335 .codec_data = &spitz_wm8750_setup,
336}; 329};
337 330
331/*
332 * FIXME: This is a temporary bodge to avoid cross-tree merge issues.
333 * New drivers should register the wm8750 I2C device in the machine
334 * setup code (under arch/arm for ARM systems).
335 */
336static int wm8750_i2c_register(void)
337{
338 struct i2c_board_info info;
339 struct i2c_adapter *adapter;
340 struct i2c_client *client;
341
342 memset(&info, 0, sizeof(struct i2c_board_info));
343 info.addr = 0x1b;
344 strlcpy(info.type, "wm8750", I2C_NAME_SIZE);
345
346 adapter = i2c_get_adapter(0);
347 if (!adapter) {
348 printk(KERN_ERR "can't get i2c adapter 0\n");
349 return -ENODEV;
350 }
351
352 client = i2c_new_device(adapter, &info);
353 i2c_put_adapter(adapter);
354 if (!client) {
355 printk(KERN_ERR "can't add i2c device at 0x%x\n",
356 (unsigned int)info.addr);
357 return -ENODEV;
358 }
359
360 return 0;
361}
362
338static struct platform_device *spitz_snd_device; 363static struct platform_device *spitz_snd_device;
339 364
340static int __init spitz_init(void) 365static int __init spitz_init(void)
@@ -344,6 +369,10 @@ static int __init spitz_init(void)
344 if (!(machine_is_spitz() || machine_is_borzoi() || machine_is_akita())) 369 if (!(machine_is_spitz() || machine_is_borzoi() || machine_is_akita()))
345 return -ENODEV; 370 return -ENODEV;
346 371
372 ret = wm8750_i2c_setup();
373 if (ret != 0)
374 return ret;
375
347 spitz_snd_device = platform_device_alloc("soc-audio", -1); 376 spitz_snd_device = platform_device_alloc("soc-audio", -1);
348 if (!spitz_snd_device) 377 if (!spitz_snd_device)
349 return -ENOMEM; 378 return -ENOMEM;
diff --git a/sound/soc/s3c24xx/jive_wm8750.c b/sound/soc/s3c24xx/jive_wm8750.c
index 59dc2c6b56d9..97d8ff3196be 100644
--- a/sound/soc/s3c24xx/jive_wm8750.c
+++ b/sound/soc/s3c24xx/jive_wm8750.c
@@ -152,15 +152,10 @@ static struct snd_soc_card snd_soc_machine_jive = {
152 .num_links = 1, 152 .num_links = 1,
153}; 153};
154 154
155/* jive audio private data */
156static struct wm8750_setup_data jive_wm8750_setup = {
157};
158
159/* jive audio subsystem */ 155/* jive audio subsystem */
160static struct snd_soc_device jive_snd_devdata = { 156static struct snd_soc_device jive_snd_devdata = {
161 .card = &snd_soc_machine_jive, 157 .card = &snd_soc_machine_jive,
162 .codec_dev = &soc_codec_dev_wm8750, 158 .codec_dev = &soc_codec_dev_wm8750,
163 .codec_data = &jive_wm8750_setup,
164}; 159};
165 160
166static struct platform_device *jive_snd_device; 161static struct platform_device *jive_snd_device;