aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/wm8750.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/codecs/wm8750.c')
-rw-r--r--sound/soc/codecs/wm8750.c347
1 files changed, 147 insertions, 200 deletions
diff --git a/sound/soc/codecs/wm8750.c b/sound/soc/codecs/wm8750.c
index 2916ed4d3844..9407e193fcc3 100644
--- a/sound/soc/codecs/wm8750.c
+++ b/sound/soc/codecs/wm8750.c
@@ -30,13 +30,6 @@
30 30
31#include "wm8750.h" 31#include "wm8750.h"
32 32
33#define WM8750_VERSION "0.12"
34
35/* codec private data */
36struct wm8750_priv {
37 unsigned int sysclk;
38};
39
40/* 33/*
41 * wm8750 register cache 34 * wm8750 register cache
42 * We can't read the WM8750 register space when we 35 * We can't read the WM8750 register space when we
@@ -56,6 +49,13 @@ static const u16 wm8750_reg[] = {
56 0x0079, 0x0079, 0x0079, /* 40 */ 49 0x0079, 0x0079, 0x0079, /* 40 */
57}; 50};
58 51
52/* codec private data */
53struct wm8750_priv {
54 unsigned int sysclk;
55 struct snd_soc_codec codec;
56 u16 reg_cache[ARRAY_SIZE(wm8750_reg)];
57};
58
59#define wm8750_reset(c) snd_soc_write(c, WM8750_RESET, 0) 59#define wm8750_reset(c) snd_soc_write(c, WM8750_RESET, 0)
60 60
61/* 61/*
@@ -483,7 +483,7 @@ static int wm8750_set_dai_sysclk(struct snd_soc_dai *codec_dai,
483 int clk_id, unsigned int freq, int dir) 483 int clk_id, unsigned int freq, int dir)
484{ 484{
485 struct snd_soc_codec *codec = codec_dai->codec; 485 struct snd_soc_codec *codec = codec_dai->codec;
486 struct wm8750_priv *wm8750 = codec->private_data; 486 struct wm8750_priv *wm8750 = snd_soc_codec_get_drvdata(codec);
487 487
488 switch (freq) { 488 switch (freq) {
489 case 11289600: 489 case 11289600:
@@ -562,7 +562,7 @@ static int wm8750_pcm_hw_params(struct snd_pcm_substream *substream,
562 struct snd_soc_pcm_runtime *rtd = substream->private_data; 562 struct snd_soc_pcm_runtime *rtd = substream->private_data;
563 struct snd_soc_device *socdev = rtd->socdev; 563 struct snd_soc_device *socdev = rtd->socdev;
564 struct snd_soc_codec *codec = socdev->card->codec; 564 struct snd_soc_codec *codec = socdev->card->codec;
565 struct wm8750_priv *wm8750 = codec->private_data; 565 struct wm8750_priv *wm8750 = snd_soc_codec_get_drvdata(codec);
566 u16 iface = snd_soc_read(codec, WM8750_IFACE) & 0x1f3; 566 u16 iface = snd_soc_read(codec, WM8750_IFACE) & 0x1f3;
567 u16 srate = snd_soc_read(codec, WM8750_SRATE) & 0x1c0; 567 u16 srate = snd_soc_read(codec, WM8750_SRATE) & 0x1c0;
568 int coeff = get_coeff(wm8750->sysclk, params_rate(params)); 568 int coeff = get_coeff(wm8750->sysclk, params_rate(params));
@@ -614,10 +614,16 @@ static int wm8750_set_bias_level(struct snd_soc_codec *codec,
614 snd_soc_write(codec, WM8750_PWR1, pwr_reg | 0x00c0); 614 snd_soc_write(codec, WM8750_PWR1, pwr_reg | 0x00c0);
615 break; 615 break;
616 case SND_SOC_BIAS_PREPARE: 616 case SND_SOC_BIAS_PREPARE:
617 /* set vmid to 5k for quick power up */
618 snd_soc_write(codec, WM8750_PWR1, pwr_reg | 0x01c1);
619 break; 617 break;
620 case SND_SOC_BIAS_STANDBY: 618 case SND_SOC_BIAS_STANDBY:
619 if (codec->bias_level == SND_SOC_BIAS_OFF) {
620 /* Set VMID to 5k */
621 snd_soc_write(codec, WM8750_PWR1, pwr_reg | 0x01c1);
622
623 /* ...and ramp */
624 msleep(1000);
625 }
626
621 /* mute dac and set vmid to 500k, enable VREF */ 627 /* mute dac and set vmid to 500k, enable VREF */
622 snd_soc_write(codec, WM8750_PWR1, pwr_reg | 0x0141); 628 snd_soc_write(codec, WM8750_PWR1, pwr_reg | 0x0141);
623 break; 629 break;
@@ -661,13 +667,6 @@ struct snd_soc_dai wm8750_dai = {
661}; 667};
662EXPORT_SYMBOL_GPL(wm8750_dai); 668EXPORT_SYMBOL_GPL(wm8750_dai);
663 669
664static void wm8750_work(struct work_struct *work)
665{
666 struct snd_soc_codec *codec =
667 container_of(work, struct snd_soc_codec, delayed_work.work);
668 wm8750_set_bias_level(codec, codec->bias_level);
669}
670
671static int wm8750_suspend(struct platform_device *pdev, pm_message_t state) 670static int wm8750_suspend(struct platform_device *pdev, pm_message_t state)
672{ 671{
673 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 672 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
@@ -696,36 +695,92 @@ static int wm8750_resume(struct platform_device *pdev)
696 695
697 wm8750_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 696 wm8750_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
698 697
699 /* charge wm8750 caps */ 698 return 0;
700 if (codec->suspend_bias_level == SND_SOC_BIAS_ON) { 699}
701 wm8750_set_bias_level(codec, SND_SOC_BIAS_PREPARE); 700
702 codec->bias_level = SND_SOC_BIAS_ON; 701static struct snd_soc_codec *wm8750_codec;
703 schedule_delayed_work(&codec->delayed_work, 702
704 msecs_to_jiffies(1000)); 703static int wm8750_probe(struct platform_device *pdev)
704{
705 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
706 struct snd_soc_codec *codec;
707 int ret = 0;
708
709 if (!wm8750_codec) {
710 dev_err(&pdev->dev, "WM8750 codec not yet registered\n");
711 return -EINVAL;
712 }
713
714 socdev->card->codec = wm8750_codec;
715 codec = wm8750_codec;
716
717 /* register pcms */
718 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
719 if (ret < 0) {
720 printk(KERN_ERR "wm8750: failed to create pcms\n");
721 goto err;
705 } 722 }
706 723
724 snd_soc_add_controls(codec, wm8750_snd_controls,
725 ARRAY_SIZE(wm8750_snd_controls));
726 wm8750_add_widgets(codec);
727
728 return 0;
729
730err:
731 return ret;
732}
733
734/* power down chip */
735static int wm8750_remove(struct platform_device *pdev)
736{
737 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
738
739 snd_soc_free_pcms(socdev);
740 snd_soc_dapm_free(socdev);
741
707 return 0; 742 return 0;
708} 743}
709 744
745struct snd_soc_codec_device soc_codec_dev_wm8750 = {
746 .probe = wm8750_probe,
747 .remove = wm8750_remove,
748 .suspend = wm8750_suspend,
749 .resume = wm8750_resume,
750};
751EXPORT_SYMBOL_GPL(soc_codec_dev_wm8750);
752
710/* 753/*
711 * initialise the WM8750 driver 754 * initialise the WM8750 driver
712 * register the mixer and dsp interfaces with the kernel 755 * register the mixer and dsp interfaces with the kernel
713 */ 756 */
714static int wm8750_init(struct snd_soc_device *socdev, 757static int wm8750_register(struct wm8750_priv *wm8750,
715 enum snd_soc_control_type control) 758 enum snd_soc_control_type control)
716{ 759{
717 struct snd_soc_codec *codec = socdev->card->codec; 760 struct snd_soc_codec *codec = &wm8750->codec;
718 int reg, ret = 0; 761 int reg, ret = 0;
719 762
763 if (wm8750_codec) {
764 dev_err(codec->dev, "Multiple WM8750 devices not supported\n");
765 ret = -EINVAL;
766 goto err;
767 }
768
769 mutex_init(&codec->mutex);
770 INIT_LIST_HEAD(&codec->dapm_widgets);
771 INIT_LIST_HEAD(&codec->dapm_paths);
772
720 codec->name = "WM8750"; 773 codec->name = "WM8750";
721 codec->owner = THIS_MODULE; 774 codec->owner = THIS_MODULE;
775 codec->bias_level = SND_SOC_BIAS_STANDBY;
722 codec->set_bias_level = wm8750_set_bias_level; 776 codec->set_bias_level = wm8750_set_bias_level;
723 codec->dai = &wm8750_dai; 777 codec->dai = &wm8750_dai;
724 codec->num_dai = 1; 778 codec->num_dai = 1;
725 codec->reg_cache_size = ARRAY_SIZE(wm8750_reg); 779 codec->reg_cache_size = ARRAY_SIZE(wm8750->reg_cache) + 1;
726 codec->reg_cache = kmemdup(wm8750_reg, sizeof(wm8750_reg), GFP_KERNEL); 780 codec->reg_cache = &wm8750->reg_cache;
727 if (codec->reg_cache == NULL) 781 snd_soc_codec_set_drvdata(codec, wm8750);
728 return -ENOMEM; 782
783 memcpy(codec->reg_cache, wm8750_reg, sizeof(wm8750->reg_cache));
729 784
730 ret = snd_soc_codec_set_cache_io(codec, 7, 9, control); 785 ret = snd_soc_codec_set_cache_io(codec, 7, 9, control);
731 if (ret < 0) { 786 if (ret < 0) {
@@ -739,17 +794,8 @@ static int wm8750_init(struct snd_soc_device *socdev,
739 goto err; 794 goto err;
740 } 795 }
741 796
742 /* register pcms */
743 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
744 if (ret < 0) {
745 printk(KERN_ERR "wm8750: failed to create pcms\n");
746 goto err;
747 }
748
749 /* charge output caps */ 797 /* charge output caps */
750 wm8750_set_bias_level(codec, SND_SOC_BIAS_PREPARE); 798 wm8750_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
751 codec->bias_level = SND_SOC_BIAS_STANDBY;
752 schedule_delayed_work(&codec->delayed_work, msecs_to_jiffies(1000));
753 799
754 /* set the update bits */ 800 /* set the update bits */
755 reg = snd_soc_read(codec, WM8750_LDAC); 801 reg = snd_soc_read(codec, WM8750_LDAC);
@@ -769,19 +815,37 @@ static int wm8750_init(struct snd_soc_device *socdev,
769 reg = snd_soc_read(codec, WM8750_RINVOL); 815 reg = snd_soc_read(codec, WM8750_RINVOL);
770 snd_soc_write(codec, WM8750_RINVOL, reg | 0x0100); 816 snd_soc_write(codec, WM8750_RINVOL, reg | 0x0100);
771 817
772 snd_soc_add_controls(codec, wm8750_snd_controls, 818 wm8750_codec = codec;
773 ARRAY_SIZE(wm8750_snd_controls));
774 wm8750_add_widgets(codec);
775 return ret;
776 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);
777err: 836err:
778 kfree(codec->reg_cache); 837 kfree(wm8750);
779 return ret; 838 return ret;
780} 839}
781 840
782/* If the i2c layer weren't so broken, we could pass this kind of data 841static void wm8750_unregister(struct wm8750_priv *wm8750)
783 around */ 842{
784static 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}
785 849
786#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 850#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
787 851
@@ -795,24 +859,26 @@ static struct snd_soc_device *wm8750_socdev;
795static int wm8750_i2c_probe(struct i2c_client *i2c, 859static int wm8750_i2c_probe(struct i2c_client *i2c,
796 const struct i2c_device_id *id) 860 const struct i2c_device_id *id)
797{ 861{
798 struct snd_soc_device *socdev = wm8750_socdev; 862 struct snd_soc_codec *codec;
799 struct snd_soc_codec *codec = socdev->card->codec; 863 struct wm8750_priv *wm8750;
800 int ret; 864
865 wm8750 = kzalloc(sizeof(struct wm8750_priv), GFP_KERNEL);
866 if (wm8750 == NULL)
867 return -ENOMEM;
801 868
802 i2c_set_clientdata(i2c, codec); 869 codec = &wm8750->codec;
803 codec->control_data = i2c; 870 codec->control_data = i2c;
871 i2c_set_clientdata(i2c, wm8750);
804 872
805 ret = wm8750_init(socdev, SND_SOC_I2C); 873 codec->dev = &i2c->dev;
806 if (ret < 0)
807 pr_err("failed to initialise WM8750\n");
808 874
809 return ret; 875 return wm8750_register(wm8750, SND_SOC_I2C);
810} 876}
811 877
812static int wm8750_i2c_remove(struct i2c_client *client) 878static int wm8750_i2c_remove(struct i2c_client *client)
813{ 879{
814 struct snd_soc_codec *codec = i2c_get_clientdata(client); 880 struct wm8750_priv *wm8750 = i2c_get_clientdata(client);
815 kfree(codec->reg_cache); 881 wm8750_unregister(wm8750);
816 return 0; 882 return 0;
817} 883}
818 884
@@ -831,66 +897,31 @@ static struct i2c_driver wm8750_i2c_driver = {
831 .remove = wm8750_i2c_remove, 897 .remove = wm8750_i2c_remove,
832 .id_table = wm8750_i2c_id, 898 .id_table = wm8750_i2c_id,
833}; 899};
834
835static int wm8750_add_i2c_device(struct platform_device *pdev,
836 const struct wm8750_setup_data *setup)
837{
838 struct i2c_board_info info;
839 struct i2c_adapter *adapter;
840 struct i2c_client *client;
841 int ret;
842
843 ret = i2c_add_driver(&wm8750_i2c_driver);
844 if (ret != 0) {
845 dev_err(&pdev->dev, "can't add i2c driver\n");
846 return ret;
847 }
848
849 memset(&info, 0, sizeof(struct i2c_board_info));
850 info.addr = setup->i2c_address;
851 strlcpy(info.type, "wm8750", I2C_NAME_SIZE);
852
853 adapter = i2c_get_adapter(setup->i2c_bus);
854 if (!adapter) {
855 dev_err(&pdev->dev, "can't get i2c adapter %d\n",
856 setup->i2c_bus);
857 goto err_driver;
858 }
859
860 client = i2c_new_device(adapter, &info);
861 i2c_put_adapter(adapter);
862 if (!client) {
863 dev_err(&pdev->dev, "can't add i2c device at 0x%x\n",
864 (unsigned int)info.addr);
865 goto err_driver;
866 }
867
868 return 0;
869
870err_driver:
871 i2c_del_driver(&wm8750_i2c_driver);
872 return -ENODEV;
873}
874#endif 900#endif
875 901
876#if defined(CONFIG_SPI_MASTER) 902#if defined(CONFIG_SPI_MASTER)
877static int __devinit wm8750_spi_probe(struct spi_device *spi) 903static int __devinit wm8750_spi_probe(struct spi_device *spi)
878{ 904{
879 struct snd_soc_device *socdev = wm8750_socdev; 905 struct snd_soc_codec *codec;
880 struct snd_soc_codec *codec = socdev->card->codec; 906 struct wm8750_priv *wm8750;
881 int ret; 907
908 wm8750 = kzalloc(sizeof(struct wm8750_priv), GFP_KERNEL);
909 if (wm8750 == NULL)
910 return -ENOMEM;
882 911
912 codec = &wm8750->codec;
883 codec->control_data = spi; 913 codec->control_data = spi;
914 codec->dev = &spi->dev;
884 915
885 ret = wm8750_init(socdev, SND_SOC_SPI); 916 dev_set_drvdata(&spi->dev, wm8750);
886 if (ret < 0)
887 dev_err(&spi->dev, "failed to initialise WM8750\n");
888 917
889 return ret; 918 return wm8750_register(wm8750, SND_SOC_SPI);
890} 919}
891 920
892static int __devexit wm8750_spi_remove(struct spi_device *spi) 921static int __devexit wm8750_spi_remove(struct spi_device *spi)
893{ 922{
923 struct wm8750_priv *wm8750 = dev_get_drvdata(&spi->dev);
924 wm8750_unregister(wm8750);
894 return 0; 925 return 0;
895} 926}
896 927
@@ -905,115 +936,31 @@ static struct spi_driver wm8750_spi_driver = {
905}; 936};
906#endif 937#endif
907 938
908static int wm8750_probe(struct platform_device *pdev) 939static int __init wm8750_modinit(void)
909{ 940{
910 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
911 struct wm8750_setup_data *setup = socdev->codec_data;
912 struct snd_soc_codec *codec;
913 struct wm8750_priv *wm8750;
914 int ret; 941 int ret;
915
916 pr_info("WM8750 Audio Codec %s", WM8750_VERSION);
917 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
918 if (codec == NULL)
919 return -ENOMEM;
920
921 wm8750 = kzalloc(sizeof(struct wm8750_priv), GFP_KERNEL);
922 if (wm8750 == NULL) {
923 kfree(codec);
924 return -ENOMEM;
925 }
926
927 codec->private_data = wm8750;
928 socdev->card->codec = codec;
929 mutex_init(&codec->mutex);
930 INIT_LIST_HEAD(&codec->dapm_widgets);
931 INIT_LIST_HEAD(&codec->dapm_paths);
932 wm8750_socdev = socdev;
933 INIT_DELAYED_WORK(&codec->delayed_work, wm8750_work);
934
935 ret = -ENODEV;
936
937#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 942#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
938 if (setup->i2c_address) { 943 ret = i2c_add_driver(&wm8750_i2c_driver);
939 ret = wm8750_add_i2c_device(pdev, setup); 944 if (ret != 0)
940 } 945 pr_err("Failed to register WM8750 I2C driver: %d\n", ret);
941#endif 946#endif
942#if defined(CONFIG_SPI_MASTER) 947#if defined(CONFIG_SPI_MASTER)
943 if (setup->spi) { 948 ret = spi_register_driver(&wm8750_spi_driver);
944 ret = spi_register_driver(&wm8750_spi_driver); 949 if (ret != 0)
945 if (ret != 0) 950 pr_err("Failed to register WM8750 SPI driver: %d\n", ret);
946 printk(KERN_ERR "can't add spi driver");
947 }
948#endif 951#endif
949 952 return 0;
950 if (ret != 0) {
951 kfree(codec->private_data);
952 kfree(codec);
953 }
954 return ret;
955}
956
957/*
958 * This function forces any delayed work to be queued and run.
959 */
960static int run_delayed_work(struct delayed_work *dwork)
961{
962 int ret;
963
964 /* cancel any work waiting to be queued. */
965 ret = cancel_delayed_work(dwork);
966
967 /* if there was any work waiting then we run it now and
968 * wait for it's completion */
969 if (ret) {
970 schedule_delayed_work(dwork, 0);
971 flush_scheduled_work();
972 }
973 return ret;
974} 953}
954module_init(wm8750_modinit);
975 955
976/* power down chip */ 956static void __exit wm8750_exit(void)
977static int wm8750_remove(struct platform_device *pdev)
978{ 957{
979 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
980 struct snd_soc_codec *codec = socdev->card->codec;
981
982 if (codec->control_data)
983 wm8750_set_bias_level(codec, SND_SOC_BIAS_OFF);
984 run_delayed_work(&codec->delayed_work);
985 snd_soc_free_pcms(socdev);
986 snd_soc_dapm_free(socdev);
987#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 958#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
988 i2c_unregister_device(codec->control_data);
989 i2c_del_driver(&wm8750_i2c_driver); 959 i2c_del_driver(&wm8750_i2c_driver);
990#endif 960#endif
991#if defined(CONFIG_SPI_MASTER) 961#if defined(CONFIG_SPI_MASTER)
992 spi_unregister_driver(&wm8750_spi_driver); 962 spi_unregister_driver(&wm8750_spi_driver);
993#endif 963#endif
994 kfree(codec->private_data);
995 kfree(codec);
996
997 return 0;
998}
999
1000struct snd_soc_codec_device soc_codec_dev_wm8750 = {
1001 .probe = wm8750_probe,
1002 .remove = wm8750_remove,
1003 .suspend = wm8750_suspend,
1004 .resume = wm8750_resume,
1005};
1006EXPORT_SYMBOL_GPL(soc_codec_dev_wm8750);
1007
1008static int __init wm8750_modinit(void)
1009{
1010 return snd_soc_register_dai(&wm8750_dai);
1011}
1012module_init(wm8750_modinit);
1013
1014static void __exit wm8750_exit(void)
1015{
1016 snd_soc_unregister_dai(&wm8750_dai);
1017} 964}
1018module_exit(wm8750_exit); 965module_exit(wm8750_exit);
1019 966