Commit 0cd257bf9b9b0cbb4fa1a5c988a232506997867c

Authored by Mark Brown
1 parent e84f246376

ASoC: alc5623: Convert to direct regmap API usage

Convert to directly use the regmap API, allowing us to eliminate the last
user of the ASoC level I/O implementations (there are still open coded
I/O implementations in drivers), avoiding duplicating code in regmap.

We no longer cache the entire CODEC register map on probe since the more
advanced cache infrastructure in regmap is able to fill the cache on
demand.

Signed-off-by: Mark Brown <broonie@linaro.org>

Showing 1 changed file with 49 additions and 38 deletions Side-by-side Diff

sound/soc/codecs/alc5623.c
... ... @@ -21,6 +21,7 @@
21 21 #include <linux/delay.h>
22 22 #include <linux/pm.h>
23 23 #include <linux/i2c.h>
  24 +#include <linux/regmap.h>
24 25 #include <linux/slab.h>
25 26 #include <sound/core.h>
26 27 #include <sound/pcm.h>
27 28  
28 29  
... ... @@ -38,26 +39,13 @@
38 39  
39 40 /* codec private data */
40 41 struct alc5623_priv {
41   - enum snd_soc_control_type control_type;
  42 + struct regmap *regmap;
42 43 u8 id;
43 44 unsigned int sysclk;
44   - u16 reg_cache[ALC5623_VENDOR_ID2+2];
45 45 unsigned int add_ctrl;
46 46 unsigned int jack_det_ctrl;
47 47 };
48 48  
49   -static void alc5623_fill_cache(struct snd_soc_codec *codec)
50   -{
51   - int i, step = codec->driver->reg_cache_step;
52   - u16 *cache = codec->reg_cache;
53   -
54   - /* not really efficient ... */
55   - codec->cache_bypass = 1;
56   - for (i = 0 ; i < codec->driver->reg_cache_size ; i += step)
57   - cache[i] = snd_soc_read(codec, i);
58   - codec->cache_bypass = 0;
59   -}
60   -
61 49 static inline int alc5623_reset(struct snd_soc_codec *codec)
62 50 {
63 51 return snd_soc_write(codec, ALC5623_RESET, 0);
64 52  
65 53  
66 54  
... ... @@ -875,18 +863,28 @@
875 863  
876 864 static int alc5623_suspend(struct snd_soc_codec *codec)
877 865 {
  866 + struct alc5623_priv *alc5623 = snd_soc_codec_get_drvdata(codec);
  867 +
878 868 alc5623_set_bias_level(codec, SND_SOC_BIAS_OFF);
  869 + regcache_cache_only(alc5623->regmap, true);
  870 +
879 871 return 0;
880 872 }
881 873  
882 874 static int alc5623_resume(struct snd_soc_codec *codec)
883 875 {
884   - int i, step = codec->driver->reg_cache_step;
885   - u16 *cache = codec->reg_cache;
  876 + struct alc5623_priv *alc5623 = snd_soc_codec_get_drvdata(codec);
  877 + int ret;
886 878  
887 879 /* Sync reg_cache with the hardware */
888   - for (i = 2 ; i < codec->driver->reg_cache_size ; i += step)
889   - snd_soc_write(codec, i, cache[i]);
  880 + regcache_cache_only(alc5623->regmap, false);
  881 + ret = regcache_sync(alc5623->regmap);
  882 + if (ret != 0) {
  883 + dev_err(codec->dev, "Failed to sync register cache: %d\n",
  884 + ret);
  885 + regcache_cache_only(alc5623->regmap, true);
  886 + return ret;
  887 + }
890 888  
891 889 alc5623_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
892 890  
893 891  
... ... @@ -906,14 +904,14 @@
906 904 struct snd_soc_dapm_context *dapm = &codec->dapm;
907 905 int ret;
908 906  
909   - ret = snd_soc_codec_set_cache_io(codec, 8, 16, alc5623->control_type);
  907 + codec->control_data = alc5623->regmap;
  908 + ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_REGMAP);
910 909 if (ret < 0) {
911 910 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
912 911 return ret;
913 912 }
914 913  
915 914 alc5623_reset(codec);
916   - alc5623_fill_cache(codec);
917 915  
918 916 /* power on device */
919 917 alc5623_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
920 918  
... ... @@ -986,11 +984,17 @@
986 984 .suspend = alc5623_suspend,
987 985 .resume = alc5623_resume,
988 986 .set_bias_level = alc5623_set_bias_level,
989   - .reg_cache_size = ALC5623_VENDOR_ID2+2,
990   - .reg_word_size = sizeof(u16),
991   - .reg_cache_step = 2,
992 987 };
993 988  
  989 +static const struct regmap_config alc5623_regmap = {
  990 + .reg_bits = 8,
  991 + .val_bits = 16,
  992 + .reg_stride = 2,
  993 +
  994 + .max_register = ALC5623_VENDOR_ID2,
  995 + .cache_type = REGCACHE_RBTREE,
  996 +};
  997 +
994 998 /*
995 999 * ALC5623 2 wire address is determined by A1 pin
996 1000 * state during powerup.
997 1001  
998 1002  
999 1003  
... ... @@ -1002,19 +1006,32 @@
1002 1006 {
1003 1007 struct alc5623_platform_data *pdata;
1004 1008 struct alc5623_priv *alc5623;
1005   - int ret, vid1, vid2;
  1009 + unsigned int vid1, vid2;
  1010 + int ret;
1006 1011  
1007   - vid1 = i2c_smbus_read_word_data(client, ALC5623_VENDOR_ID1);
1008   - if (vid1 < 0) {
1009   - dev_err(&client->dev, "failed to read I2C\n");
1010   - return -EIO;
  1012 + alc5623 = devm_kzalloc(&client->dev, sizeof(struct alc5623_priv),
  1013 + GFP_KERNEL);
  1014 + if (alc5623 == NULL)
  1015 + return -ENOMEM;
  1016 +
  1017 + alc5623->regmap = devm_regmap_init_i2c(client, &alc5623_regmap);
  1018 + if (IS_ERR(alc5623->regmap)) {
  1019 + ret = PTR_ERR(alc5623->regmap);
  1020 + dev_err(&client->dev, "Failed to initialise I/O: %d\n", ret);
  1021 + return ret;
1011 1022 }
  1023 +
  1024 + ret = regmap_read(alc5623->regmap, ALC5623_VENDOR_ID1, &vid1);
  1025 + if (ret < 0) {
  1026 + dev_err(&client->dev, "failed to read vendor ID1: %d\n", ret);
  1027 + return ret;
  1028 + }
1012 1029 vid1 = ((vid1 & 0xff) << 8) | (vid1 >> 8);
1013 1030  
1014   - vid2 = i2c_smbus_read_byte_data(client, ALC5623_VENDOR_ID2);
1015   - if (vid2 < 0) {
1016   - dev_err(&client->dev, "failed to read I2C\n");
1017   - return -EIO;
  1031 + ret = regmap_read(alc5623->regmap, ALC5623_VENDOR_ID2, &vid2);
  1032 + if (ret < 0) {
  1033 + dev_err(&client->dev, "failed to read vendor ID2: %d\n", ret);
  1034 + return ret;
1018 1035 }
1019 1036  
1020 1037 if ((vid1 != 0x10ec) || (vid2 != id->driver_data)) {
... ... @@ -1027,11 +1044,6 @@
1027 1044  
1028 1045 dev_dbg(&client->dev, "Found codec id : alc56%02x\n", vid2);
1029 1046  
1030   - alc5623 = devm_kzalloc(&client->dev, sizeof(struct alc5623_priv),
1031   - GFP_KERNEL);
1032   - if (alc5623 == NULL)
1033   - return -ENOMEM;
1034   -
1035 1047 pdata = client->dev.platform_data;
1036 1048 if (pdata) {
1037 1049 alc5623->add_ctrl = pdata->add_ctrl;
... ... @@ -1054,7 +1066,6 @@
1054 1066 }
1055 1067  
1056 1068 i2c_set_clientdata(client, alc5623);
1057   - alc5623->control_type = SND_SOC_I2C;
1058 1069  
1059 1070 ret = snd_soc_register_codec(&client->dev,
1060 1071 &soc_codec_device_alc5623, &alc5623_dai, 1);