aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/sound/wm8960.txt31
-rw-r--r--sound/soc/codecs/wm8955.c33
-rw-r--r--sound/soc/codecs/wm8960.c113
-rw-r--r--sound/soc/codecs/wm8961.c34
-rw-r--r--sound/soc/codecs/wm8962.c3
-rw-r--r--sound/soc/codecs/wm8974.c25
6 files changed, 94 insertions, 145 deletions
diff --git a/Documentation/devicetree/bindings/sound/wm8960.txt b/Documentation/devicetree/bindings/sound/wm8960.txt
new file mode 100644
index 000000000000..2deb8a3da9c5
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/wm8960.txt
@@ -0,0 +1,31 @@
1WM8960 audio CODEC
2
3This device supports I2C only.
4
5Required properties:
6
7 - compatible : "wlf,wm8960"
8
9 - reg : the I2C address of the device.
10
11Optional properties:
12 - wlf,shared-lrclk: This is a boolean property. If present, the LRCM bit of
13 R24 (Additional control 2) gets set, indicating that ADCLRC and DACLRC pins
14 will be disabled only when ADC (Left and Right) and DAC (Left and Right)
15 are disabled.
16 When wm8960 works on synchronize mode and DACLRC pin is used to supply
17 frame clock, it will no frame clock for captrue unless enable DAC to enable
18 DACLRC pin. If shared-lrclk is present, no need to enable DAC for captrue.
19
20 - wlf,capless: This is a boolean property. If present, OUT3 pin will be
21 enabled and disabled together with HP_L and HP_R pins in response to jack
22 detect events.
23
24Example:
25
26codec: wm8960@1a {
27 compatible = "wlf,wm8960";
28 reg = <0x1a>;
29
30 wlf,shared-lrclk;
31};
diff --git a/sound/soc/codecs/wm8955.c b/sound/soc/codecs/wm8955.c
index 09d91d9dc4ee..1173f7fef5a7 100644
--- a/sound/soc/codecs/wm8955.c
+++ b/sound/soc/codecs/wm8955.c
@@ -866,29 +866,6 @@ static struct snd_soc_dai_driver wm8955_dai = {
866 .ops = &wm8955_dai_ops, 866 .ops = &wm8955_dai_ops,
867}; 867};
868 868
869#ifdef CONFIG_PM
870static int wm8955_suspend(struct snd_soc_codec *codec)
871{
872 struct wm8955_priv *wm8955 = snd_soc_codec_get_drvdata(codec);
873
874 wm8955_set_bias_level(codec, SND_SOC_BIAS_OFF);
875
876 regcache_mark_dirty(wm8955->regmap);
877
878 return 0;
879}
880
881static int wm8955_resume(struct snd_soc_codec *codec)
882{
883 wm8955_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
884
885 return 0;
886}
887#else
888#define wm8955_suspend NULL
889#define wm8955_resume NULL
890#endif
891
892static int wm8955_probe(struct snd_soc_codec *codec) 869static int wm8955_probe(struct snd_soc_codec *codec)
893{ 870{
894 struct wm8955_priv *wm8955 = snd_soc_codec_get_drvdata(codec); 871 struct wm8955_priv *wm8955 = snd_soc_codec_get_drvdata(codec);
@@ -964,18 +941,10 @@ err_enable:
964 return ret; 941 return ret;
965} 942}
966 943
967static int wm8955_remove(struct snd_soc_codec *codec)
968{
969 wm8955_set_bias_level(codec, SND_SOC_BIAS_OFF);
970 return 0;
971}
972
973static struct snd_soc_codec_driver soc_codec_dev_wm8955 = { 944static struct snd_soc_codec_driver soc_codec_dev_wm8955 = {
974 .probe = wm8955_probe, 945 .probe = wm8955_probe,
975 .remove = wm8955_remove,
976 .suspend = wm8955_suspend,
977 .resume = wm8955_resume,
978 .set_bias_level = wm8955_set_bias_level, 946 .set_bias_level = wm8955_set_bias_level,
947 .suspend_bias_off = true,
979 948
980 .controls = wm8955_snd_controls, 949 .controls = wm8955_snd_controls,
981 .num_controls = ARRAY_SIZE(wm8955_snd_controls), 950 .num_controls = ARRAY_SIZE(wm8955_snd_controls),
diff --git a/sound/soc/codecs/wm8960.c b/sound/soc/codecs/wm8960.c
index 4dc4e85116cd..031a1ae71d94 100644
--- a/sound/soc/codecs/wm8960.c
+++ b/sound/soc/codecs/wm8960.c
@@ -125,9 +125,10 @@ struct wm8960_priv {
125 struct snd_soc_dapm_widget *out3; 125 struct snd_soc_dapm_widget *out3;
126 bool deemph; 126 bool deemph;
127 int playback_fs; 127 int playback_fs;
128 struct wm8960_data pdata;
128}; 129};
129 130
130#define wm8960_reset(c) snd_soc_write(c, WM8960_RESET, 0) 131#define wm8960_reset(c) regmap_write(c, WM8960_RESET, 0)
131 132
132/* enumerated controls */ 133/* enumerated controls */
133static const char *wm8960_polarity[] = {"No Inversion", "Left Inverted", 134static const char *wm8960_polarity[] = {"No Inversion", "Left Inverted",
@@ -440,8 +441,8 @@ static const struct snd_soc_dapm_route audio_paths_capless[] = {
440 441
441static int wm8960_add_widgets(struct snd_soc_codec *codec) 442static int wm8960_add_widgets(struct snd_soc_codec *codec)
442{ 443{
443 struct wm8960_data *pdata = codec->dev->platform_data;
444 struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec); 444 struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
445 struct wm8960_data *pdata = &wm8960->pdata;
445 struct snd_soc_dapm_context *dapm = &codec->dapm; 446 struct snd_soc_dapm_context *dapm = &codec->dapm;
446 struct snd_soc_dapm_widget *w; 447 struct snd_soc_dapm_widget *w;
447 448
@@ -942,56 +943,15 @@ static struct snd_soc_dai_driver wm8960_dai = {
942 .symmetric_rates = 1, 943 .symmetric_rates = 1,
943}; 944};
944 945
945static int wm8960_suspend(struct snd_soc_codec *codec)
946{
947 struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
948
949 wm8960->set_bias_level(codec, SND_SOC_BIAS_OFF);
950 return 0;
951}
952
953static int wm8960_resume(struct snd_soc_codec *codec)
954{
955 struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
956
957 wm8960->set_bias_level(codec, SND_SOC_BIAS_STANDBY);
958 return 0;
959}
960
961static int wm8960_probe(struct snd_soc_codec *codec) 946static int wm8960_probe(struct snd_soc_codec *codec)
962{ 947{
963 struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec); 948 struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
964 struct wm8960_data *pdata = dev_get_platdata(codec->dev); 949 struct wm8960_data *pdata = &wm8960->pdata;
965 int ret;
966
967 wm8960->set_bias_level = wm8960_set_bias_level_out3;
968
969 if (!pdata) {
970 dev_warn(codec->dev, "No platform data supplied\n");
971 } else {
972 if (pdata->capless)
973 wm8960->set_bias_level = wm8960_set_bias_level_capless;
974 }
975
976 ret = wm8960_reset(codec);
977 if (ret < 0) {
978 dev_err(codec->dev, "Failed to issue reset\n");
979 return ret;
980 }
981
982 wm8960->set_bias_level(codec, SND_SOC_BIAS_STANDBY);
983 950
984 /* Latch the update bits */ 951 if (pdata->capless)
985 snd_soc_update_bits(codec, WM8960_LINVOL, 0x100, 0x100); 952 wm8960->set_bias_level = wm8960_set_bias_level_capless;
986 snd_soc_update_bits(codec, WM8960_RINVOL, 0x100, 0x100); 953 else
987 snd_soc_update_bits(codec, WM8960_LADC, 0x100, 0x100); 954 wm8960->set_bias_level = wm8960_set_bias_level_out3;
988 snd_soc_update_bits(codec, WM8960_RADC, 0x100, 0x100);
989 snd_soc_update_bits(codec, WM8960_LDAC, 0x100, 0x100);
990 snd_soc_update_bits(codec, WM8960_RDAC, 0x100, 0x100);
991 snd_soc_update_bits(codec, WM8960_LOUT1, 0x100, 0x100);
992 snd_soc_update_bits(codec, WM8960_ROUT1, 0x100, 0x100);
993 snd_soc_update_bits(codec, WM8960_LOUT2, 0x100, 0x100);
994 snd_soc_update_bits(codec, WM8960_ROUT2, 0x100, 0x100);
995 955
996 snd_soc_add_codec_controls(codec, wm8960_snd_controls, 956 snd_soc_add_codec_controls(codec, wm8960_snd_controls,
997 ARRAY_SIZE(wm8960_snd_controls)); 957 ARRAY_SIZE(wm8960_snd_controls));
@@ -1000,21 +960,10 @@ static int wm8960_probe(struct snd_soc_codec *codec)
1000 return 0; 960 return 0;
1001} 961}
1002 962
1003/* power down chip */
1004static int wm8960_remove(struct snd_soc_codec *codec)
1005{
1006 struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
1007
1008 wm8960->set_bias_level(codec, SND_SOC_BIAS_OFF);
1009 return 0;
1010}
1011
1012static struct snd_soc_codec_driver soc_codec_dev_wm8960 = { 963static struct snd_soc_codec_driver soc_codec_dev_wm8960 = {
1013 .probe = wm8960_probe, 964 .probe = wm8960_probe,
1014 .remove = wm8960_remove,
1015 .suspend = wm8960_suspend,
1016 .resume = wm8960_resume,
1017 .set_bias_level = wm8960_set_bias_level, 965 .set_bias_level = wm8960_set_bias_level,
966 .suspend_bias_off = true,
1018}; 967};
1019 968
1020static const struct regmap_config wm8960_regmap = { 969static const struct regmap_config wm8960_regmap = {
@@ -1029,6 +978,18 @@ static const struct regmap_config wm8960_regmap = {
1029 .volatile_reg = wm8960_volatile, 978 .volatile_reg = wm8960_volatile,
1030}; 979};
1031 980
981static void wm8960_set_pdata_from_of(struct i2c_client *i2c,
982 struct wm8960_data *pdata)
983{
984 const struct device_node *np = i2c->dev.of_node;
985
986 if (of_property_read_bool(np, "wlf,capless"))
987 pdata->capless = true;
988
989 if (of_property_read_bool(np, "wlf,shared-lrclk"))
990 pdata->shared_lrclk = true;
991}
992
1032static int wm8960_i2c_probe(struct i2c_client *i2c, 993static int wm8960_i2c_probe(struct i2c_client *i2c,
1033 const struct i2c_device_id *id) 994 const struct i2c_device_id *id)
1034{ 995{
@@ -1045,7 +1006,18 @@ static int wm8960_i2c_probe(struct i2c_client *i2c,
1045 if (IS_ERR(wm8960->regmap)) 1006 if (IS_ERR(wm8960->regmap))
1046 return PTR_ERR(wm8960->regmap); 1007 return PTR_ERR(wm8960->regmap);
1047 1008
1048 if (pdata && pdata->shared_lrclk) { 1009 if (pdata)
1010 memcpy(&wm8960->pdata, pdata, sizeof(struct wm8960_data));
1011 else if (i2c->dev.of_node)
1012 wm8960_set_pdata_from_of(i2c, &wm8960->pdata);
1013
1014 ret = wm8960_reset(wm8960->regmap);
1015 if (ret != 0) {
1016 dev_err(&i2c->dev, "Failed to issue reset\n");
1017 return ret;
1018 }
1019
1020 if (wm8960->pdata.shared_lrclk) {
1049 ret = regmap_update_bits(wm8960->regmap, WM8960_ADDCTL2, 1021 ret = regmap_update_bits(wm8960->regmap, WM8960_ADDCTL2,
1050 0x4, 0x4); 1022 0x4, 0x4);
1051 if (ret != 0) { 1023 if (ret != 0) {
@@ -1055,6 +1027,18 @@ static int wm8960_i2c_probe(struct i2c_client *i2c,
1055 } 1027 }
1056 } 1028 }
1057 1029
1030 /* Latch the update bits */
1031 regmap_update_bits(wm8960->regmap, WM8960_LINVOL, 0x100, 0x100);
1032 regmap_update_bits(wm8960->regmap, WM8960_RINVOL, 0x100, 0x100);
1033 regmap_update_bits(wm8960->regmap, WM8960_LADC, 0x100, 0x100);
1034 regmap_update_bits(wm8960->regmap, WM8960_RADC, 0x100, 0x100);
1035 regmap_update_bits(wm8960->regmap, WM8960_LDAC, 0x100, 0x100);
1036 regmap_update_bits(wm8960->regmap, WM8960_RDAC, 0x100, 0x100);
1037 regmap_update_bits(wm8960->regmap, WM8960_LOUT1, 0x100, 0x100);
1038 regmap_update_bits(wm8960->regmap, WM8960_ROUT1, 0x100, 0x100);
1039 regmap_update_bits(wm8960->regmap, WM8960_LOUT2, 0x100, 0x100);
1040 regmap_update_bits(wm8960->regmap, WM8960_ROUT2, 0x100, 0x100);
1041
1058 i2c_set_clientdata(i2c, wm8960); 1042 i2c_set_clientdata(i2c, wm8960);
1059 1043
1060 ret = snd_soc_register_codec(&i2c->dev, 1044 ret = snd_soc_register_codec(&i2c->dev,
@@ -1075,10 +1059,17 @@ static const struct i2c_device_id wm8960_i2c_id[] = {
1075}; 1059};
1076MODULE_DEVICE_TABLE(i2c, wm8960_i2c_id); 1060MODULE_DEVICE_TABLE(i2c, wm8960_i2c_id);
1077 1061
1062static const struct of_device_id wm8960_of_match[] = {
1063 { .compatible = "wlf,wm8960", },
1064 { }
1065};
1066MODULE_DEVICE_TABLE(of, wm8960_of_match);
1067
1078static struct i2c_driver wm8960_i2c_driver = { 1068static struct i2c_driver wm8960_i2c_driver = {
1079 .driver = { 1069 .driver = {
1080 .name = "wm8960", 1070 .name = "wm8960",
1081 .owner = THIS_MODULE, 1071 .owner = THIS_MODULE,
1072 .of_match_table = wm8960_of_match,
1082 }, 1073 },
1083 .probe = wm8960_i2c_probe, 1074 .probe = wm8960_i2c_probe,
1084 .remove = wm8960_i2c_remove, 1075 .remove = wm8960_i2c_remove,
diff --git a/sound/soc/codecs/wm8961.c b/sound/soc/codecs/wm8961.c
index 41d23e920ad5..eeffd05384b4 100644
--- a/sound/soc/codecs/wm8961.c
+++ b/sound/soc/codecs/wm8961.c
@@ -835,7 +835,6 @@ static struct snd_soc_dai_driver wm8961_dai = {
835 835
836static int wm8961_probe(struct snd_soc_codec *codec) 836static int wm8961_probe(struct snd_soc_codec *codec)
837{ 837{
838 struct snd_soc_dapm_context *dapm = &codec->dapm;
839 u16 reg; 838 u16 reg;
840 839
841 /* Enable class W */ 840 /* Enable class W */
@@ -871,50 +870,33 @@ static int wm8961_probe(struct snd_soc_codec *codec)
871 reg &= ~WM8961_MANUAL_MODE; 870 reg &= ~WM8961_MANUAL_MODE;
872 snd_soc_write(codec, WM8961_CLOCKING_3, reg); 871 snd_soc_write(codec, WM8961_CLOCKING_3, reg);
873 872
874 wm8961_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
875
876 snd_soc_add_codec_controls(codec, wm8961_snd_controls,
877 ARRAY_SIZE(wm8961_snd_controls));
878 snd_soc_dapm_new_controls(dapm, wm8961_dapm_widgets,
879 ARRAY_SIZE(wm8961_dapm_widgets));
880 snd_soc_dapm_add_routes(dapm, audio_paths, ARRAY_SIZE(audio_paths));
881
882 return 0;
883}
884
885static int wm8961_remove(struct snd_soc_codec *codec)
886{
887 wm8961_set_bias_level(codec, SND_SOC_BIAS_OFF);
888 return 0; 873 return 0;
889} 874}
890 875
891#ifdef CONFIG_PM 876#ifdef CONFIG_PM
892static int wm8961_suspend(struct snd_soc_codec *codec)
893{
894 wm8961_set_bias_level(codec, SND_SOC_BIAS_OFF);
895
896 return 0;
897}
898 877
899static int wm8961_resume(struct snd_soc_codec *codec) 878static int wm8961_resume(struct snd_soc_codec *codec)
900{ 879{
901 snd_soc_cache_sync(codec); 880 snd_soc_cache_sync(codec);
902 881
903 wm8961_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
904
905 return 0; 882 return 0;
906} 883}
907#else 884#else
908#define wm8961_suspend NULL
909#define wm8961_resume NULL 885#define wm8961_resume NULL
910#endif 886#endif
911 887
912static struct snd_soc_codec_driver soc_codec_dev_wm8961 = { 888static struct snd_soc_codec_driver soc_codec_dev_wm8961 = {
913 .probe = wm8961_probe, 889 .probe = wm8961_probe,
914 .remove = wm8961_remove,
915 .suspend = wm8961_suspend,
916 .resume = wm8961_resume, 890 .resume = wm8961_resume,
917 .set_bias_level = wm8961_set_bias_level, 891 .set_bias_level = wm8961_set_bias_level,
892 .suspend_bias_off = true,
893
894 .controls = wm8961_snd_controls,
895 .num_controls = ARRAY_SIZE(wm8961_snd_controls),
896 .dapm_widgets = wm8961_dapm_widgets,
897 .num_dapm_widgets = ARRAY_SIZE(wm8961_dapm_widgets),
898 .dapm_routes = audio_paths,
899 .num_dapm_routes = ARRAY_SIZE(audio_paths),
918}; 900};
919 901
920static const struct regmap_config wm8961_regmap = { 902static const struct regmap_config wm8961_regmap = {
diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c
index 61ca4a7cb6ea..1534d88a66e9 100644
--- a/sound/soc/codecs/wm8962.c
+++ b/sound/soc/codecs/wm8962.c
@@ -3554,8 +3554,7 @@ static int wm8962_i2c_probe(struct i2c_client *i2c,
3554 unsigned int reg; 3554 unsigned int reg;
3555 int ret, i, irq_pol, trigger; 3555 int ret, i, irq_pol, trigger;
3556 3556
3557 wm8962 = devm_kzalloc(&i2c->dev, sizeof(struct wm8962_priv), 3557 wm8962 = devm_kzalloc(&i2c->dev, sizeof(*wm8962), GFP_KERNEL);
3558 GFP_KERNEL);
3559 if (wm8962 == NULL) 3558 if (wm8962 == NULL)
3560 return -ENOMEM; 3559 return -ENOMEM;
3561 3560
diff --git a/sound/soc/codecs/wm8974.c b/sound/soc/codecs/wm8974.c
index 682e9eda1019..ff0e4646b934 100644
--- a/sound/soc/codecs/wm8974.c
+++ b/sound/soc/codecs/wm8974.c
@@ -568,18 +568,6 @@ static struct snd_soc_dai_driver wm8974_dai = {
568 .symmetric_rates = 1, 568 .symmetric_rates = 1,
569}; 569};
570 570
571static int wm8974_suspend(struct snd_soc_codec *codec)
572{
573 wm8974_set_bias_level(codec, SND_SOC_BIAS_OFF);
574 return 0;
575}
576
577static int wm8974_resume(struct snd_soc_codec *codec)
578{
579 wm8974_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
580 return 0;
581}
582
583static const struct regmap_config wm8974_regmap = { 571static const struct regmap_config wm8974_regmap = {
584 .reg_bits = 7, 572 .reg_bits = 7,
585 .val_bits = 9, 573 .val_bits = 9,
@@ -599,24 +587,13 @@ static int wm8974_probe(struct snd_soc_codec *codec)
599 return ret; 587 return ret;
600 } 588 }
601 589
602 wm8974_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
603
604 return ret;
605}
606
607/* power down chip */
608static int wm8974_remove(struct snd_soc_codec *codec)
609{
610 wm8974_set_bias_level(codec, SND_SOC_BIAS_OFF);
611 return 0; 590 return 0;
612} 591}
613 592
614static struct snd_soc_codec_driver soc_codec_dev_wm8974 = { 593static struct snd_soc_codec_driver soc_codec_dev_wm8974 = {
615 .probe = wm8974_probe, 594 .probe = wm8974_probe,
616 .remove = wm8974_remove,
617 .suspend = wm8974_suspend,
618 .resume = wm8974_resume,
619 .set_bias_level = wm8974_set_bias_level, 595 .set_bias_level = wm8974_set_bias_level,
596 .suspend_bias_off = true,
620 597
621 .controls = wm8974_snd_controls, 598 .controls = wm8974_snd_controls,
622 .num_controls = ARRAY_SIZE(wm8974_snd_controls), 599 .num_controls = ARRAY_SIZE(wm8974_snd_controls),