aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/adav80x.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/codecs/adav80x.c')
-rw-r--r--sound/soc/codecs/adav80x.c152
1 files changed, 22 insertions, 130 deletions
diff --git a/sound/soc/codecs/adav80x.c b/sound/soc/codecs/adav80x.c
index f78b27a7c461..7470831ba756 100644
--- a/sound/soc/codecs/adav80x.c
+++ b/sound/soc/codecs/adav80x.c
@@ -8,17 +8,15 @@
8 * Licensed under the GPL-2 or later. 8 * Licensed under the GPL-2 or later.
9 */ 9 */
10 10
11#include <linux/init.h>
12#include <linux/module.h> 11#include <linux/module.h>
13#include <linux/kernel.h> 12#include <linux/kernel.h>
14#include <linux/i2c.h> 13#include <linux/regmap.h>
15#include <linux/spi/spi.h>
16#include <linux/slab.h> 14#include <linux/slab.h>
17#include <sound/core.h> 15
18#include <sound/pcm.h> 16#include <sound/pcm.h>
19#include <sound/pcm_params.h> 17#include <sound/pcm_params.h>
20#include <sound/tlv.h>
21#include <sound/soc.h> 18#include <sound/soc.h>
19#include <sound/tlv.h>
22 20
23#include "adav80x.h" 21#include "adav80x.h"
24 22
@@ -541,6 +539,7 @@ static int adav80x_set_sysclk(struct snd_soc_codec *codec,
541 unsigned int freq, int dir) 539 unsigned int freq, int dir)
542{ 540{
543 struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec); 541 struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
542 struct snd_soc_dapm_context *dapm = &codec->dapm;
544 543
545 if (dir == SND_SOC_CLOCK_IN) { 544 if (dir == SND_SOC_CLOCK_IN) {
546 switch (clk_id) { 545 switch (clk_id) {
@@ -573,7 +572,7 @@ static int adav80x_set_sysclk(struct snd_soc_codec *codec,
573 regmap_write(adav80x->regmap, ADAV80X_ICLK_CTRL2, 572 regmap_write(adav80x->regmap, ADAV80X_ICLK_CTRL2,
574 iclk_ctrl2); 573 iclk_ctrl2);
575 574
576 snd_soc_dapm_sync(&codec->dapm); 575 snd_soc_dapm_sync(dapm);
577 } 576 }
578 } else { 577 } else {
579 unsigned int mask; 578 unsigned int mask;
@@ -600,17 +599,21 @@ static int adav80x_set_sysclk(struct snd_soc_codec *codec,
600 adav80x->sysclk_pd[clk_id] = false; 599 adav80x->sysclk_pd[clk_id] = false;
601 } 600 }
602 601
602 snd_soc_dapm_mutex_lock(dapm);
603
603 if (adav80x->sysclk_pd[0]) 604 if (adav80x->sysclk_pd[0])
604 snd_soc_dapm_disable_pin(&codec->dapm, "PLL1"); 605 snd_soc_dapm_disable_pin_unlocked(dapm, "PLL1");
605 else 606 else
606 snd_soc_dapm_force_enable_pin(&codec->dapm, "PLL1"); 607 snd_soc_dapm_force_enable_pin_unlocked(dapm, "PLL1");
607 608
608 if (adav80x->sysclk_pd[1] || adav80x->sysclk_pd[2]) 609 if (adav80x->sysclk_pd[1] || adav80x->sysclk_pd[2])
609 snd_soc_dapm_disable_pin(&codec->dapm, "PLL2"); 610 snd_soc_dapm_disable_pin_unlocked(dapm, "PLL2");
610 else 611 else
611 snd_soc_dapm_force_enable_pin(&codec->dapm, "PLL2"); 612 snd_soc_dapm_force_enable_pin_unlocked(dapm, "PLL2");
612 613
613 snd_soc_dapm_sync(&codec->dapm); 614 snd_soc_dapm_sync_unlocked(dapm);
615
616 snd_soc_dapm_mutex_unlock(dapm);
614 } 617 }
615 618
616 return 0; 619 return 0;
@@ -722,7 +725,7 @@ static int adav80x_dai_startup(struct snd_pcm_substream *substream,
722 struct snd_soc_codec *codec = dai->codec; 725 struct snd_soc_codec *codec = dai->codec;
723 struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec); 726 struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
724 727
725 if (!codec->active || !adav80x->rate) 728 if (!snd_soc_codec_is_active(codec) || !adav80x->rate)
726 return 0; 729 return 0;
727 730
728 return snd_pcm_hw_constraint_minmax(substream->runtime, 731 return snd_pcm_hw_constraint_minmax(substream->runtime,
@@ -735,7 +738,7 @@ static void adav80x_dai_shutdown(struct snd_pcm_substream *substream,
735 struct snd_soc_codec *codec = dai->codec; 738 struct snd_soc_codec *codec = dai->codec;
736 struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec); 739 struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
737 740
738 if (!codec->active) 741 if (!snd_soc_codec_is_active(codec))
739 adav80x->rate = 0; 742 adav80x->rate = 0;
740} 743}
741 744
@@ -864,39 +867,26 @@ static struct snd_soc_codec_driver adav80x_codec_driver = {
864 .num_dapm_routes = ARRAY_SIZE(adav80x_dapm_routes), 867 .num_dapm_routes = ARRAY_SIZE(adav80x_dapm_routes),
865}; 868};
866 869
867static int adav80x_bus_probe(struct device *dev, struct regmap *regmap) 870int adav80x_bus_probe(struct device *dev, struct regmap *regmap)
868{ 871{
869 struct adav80x *adav80x; 872 struct adav80x *adav80x;
870 int ret;
871 873
872 if (IS_ERR(regmap)) 874 if (IS_ERR(regmap))
873 return PTR_ERR(regmap); 875 return PTR_ERR(regmap);
874 876
875 adav80x = kzalloc(sizeof(*adav80x), GFP_KERNEL); 877 adav80x = devm_kzalloc(dev, sizeof(*adav80x), GFP_KERNEL);
876 if (!adav80x) 878 if (!adav80x)
877 return -ENOMEM; 879 return -ENOMEM;
878 880
879
880 dev_set_drvdata(dev, adav80x); 881 dev_set_drvdata(dev, adav80x);
881 adav80x->regmap = regmap; 882 adav80x->regmap = regmap;
882 883
883 ret = snd_soc_register_codec(dev, &adav80x_codec_driver, 884 return snd_soc_register_codec(dev, &adav80x_codec_driver,
884 adav80x_dais, ARRAY_SIZE(adav80x_dais)); 885 adav80x_dais, ARRAY_SIZE(adav80x_dais));
885 if (ret)
886 kfree(adav80x);
887
888 return ret;
889} 886}
887EXPORT_SYMBOL_GPL(adav80x_bus_probe);
890 888
891static int adav80x_bus_remove(struct device *dev) 889const struct regmap_config adav80x_regmap_config = {
892{
893 snd_soc_unregister_codec(dev);
894 kfree(dev_get_drvdata(dev));
895 return 0;
896}
897
898#if defined(CONFIG_SPI_MASTER)
899static const struct regmap_config adav80x_spi_regmap_config = {
900 .val_bits = 8, 890 .val_bits = 8,
901 .pad_bits = 1, 891 .pad_bits = 1,
902 .reg_bits = 7, 892 .reg_bits = 7,
@@ -908,105 +898,7 @@ static const struct regmap_config adav80x_spi_regmap_config = {
908 .reg_defaults = adav80x_reg_defaults, 898 .reg_defaults = adav80x_reg_defaults,
909 .num_reg_defaults = ARRAY_SIZE(adav80x_reg_defaults), 899 .num_reg_defaults = ARRAY_SIZE(adav80x_reg_defaults),
910}; 900};
911 901EXPORT_SYMBOL_GPL(adav80x_regmap_config);
912static const struct spi_device_id adav80x_spi_id[] = {
913 { "adav801", 0 },
914 { }
915};
916MODULE_DEVICE_TABLE(spi, adav80x_spi_id);
917
918static int adav80x_spi_probe(struct spi_device *spi)
919{
920 return adav80x_bus_probe(&spi->dev,
921 devm_regmap_init_spi(spi, &adav80x_spi_regmap_config));
922}
923
924static int adav80x_spi_remove(struct spi_device *spi)
925{
926 return adav80x_bus_remove(&spi->dev);
927}
928
929static struct spi_driver adav80x_spi_driver = {
930 .driver = {
931 .name = "adav801",
932 .owner = THIS_MODULE,
933 },
934 .probe = adav80x_spi_probe,
935 .remove = adav80x_spi_remove,
936 .id_table = adav80x_spi_id,
937};
938#endif
939
940#if IS_ENABLED(CONFIG_I2C)
941static const struct regmap_config adav80x_i2c_regmap_config = {
942 .val_bits = 8,
943 .pad_bits = 1,
944 .reg_bits = 7,
945
946 .max_register = ADAV80X_PLL_OUTE,
947
948 .cache_type = REGCACHE_RBTREE,
949 .reg_defaults = adav80x_reg_defaults,
950 .num_reg_defaults = ARRAY_SIZE(adav80x_reg_defaults),
951};
952
953static const struct i2c_device_id adav80x_i2c_id[] = {
954 { "adav803", 0 },
955 { }
956};
957MODULE_DEVICE_TABLE(i2c, adav80x_i2c_id);
958
959static int adav80x_i2c_probe(struct i2c_client *client,
960 const struct i2c_device_id *id)
961{
962 return adav80x_bus_probe(&client->dev,
963 devm_regmap_init_i2c(client, &adav80x_i2c_regmap_config));
964}
965
966static int adav80x_i2c_remove(struct i2c_client *client)
967{
968 return adav80x_bus_remove(&client->dev);
969}
970
971static struct i2c_driver adav80x_i2c_driver = {
972 .driver = {
973 .name = "adav803",
974 .owner = THIS_MODULE,
975 },
976 .probe = adav80x_i2c_probe,
977 .remove = adav80x_i2c_remove,
978 .id_table = adav80x_i2c_id,
979};
980#endif
981
982static int __init adav80x_init(void)
983{
984 int ret = 0;
985
986#if IS_ENABLED(CONFIG_I2C)
987 ret = i2c_add_driver(&adav80x_i2c_driver);
988 if (ret)
989 return ret;
990#endif
991
992#if defined(CONFIG_SPI_MASTER)
993 ret = spi_register_driver(&adav80x_spi_driver);
994#endif
995
996 return ret;
997}
998module_init(adav80x_init);
999
1000static void __exit adav80x_exit(void)
1001{
1002#if IS_ENABLED(CONFIG_I2C)
1003 i2c_del_driver(&adav80x_i2c_driver);
1004#endif
1005#if defined(CONFIG_SPI_MASTER)
1006 spi_unregister_driver(&adav80x_spi_driver);
1007#endif
1008}
1009module_exit(adav80x_exit);
1010 902
1011MODULE_DESCRIPTION("ASoC ADAV80x driver"); 903MODULE_DESCRIPTION("ASoC ADAV80x driver");
1012MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>"); 904MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");