aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/sound/soc.h19
-rw-r--r--include/trace/events/asoc.h25
-rw-r--r--sound/soc/soc-cache.c152
-rw-r--r--sound/soc/soc-core.c4
4 files changed, 12 insertions, 188 deletions
diff --git a/include/sound/soc.h b/include/sound/soc.h
index 7ba7130037a0..fadcb351f3e1 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -409,13 +409,9 @@ int devm_snd_soc_register_component(struct device *dev,
409 const struct snd_soc_component_driver *cmpnt_drv, 409 const struct snd_soc_component_driver *cmpnt_drv,
410 struct snd_soc_dai_driver *dai_drv, int num_dai); 410 struct snd_soc_dai_driver *dai_drv, int num_dai);
411void snd_soc_unregister_component(struct device *dev); 411void snd_soc_unregister_component(struct device *dev);
412int snd_soc_cache_sync(struct snd_soc_codec *codec);
413int snd_soc_cache_init(struct snd_soc_codec *codec); 412int snd_soc_cache_init(struct snd_soc_codec *codec);
414int snd_soc_cache_exit(struct snd_soc_codec *codec); 413int snd_soc_cache_exit(struct snd_soc_codec *codec);
415int snd_soc_cache_write(struct snd_soc_codec *codec, 414
416 unsigned int reg, unsigned int value);
417int snd_soc_cache_read(struct snd_soc_codec *codec,
418 unsigned int reg, unsigned int *value);
419int snd_soc_platform_read(struct snd_soc_platform *platform, 415int snd_soc_platform_read(struct snd_soc_platform *platform,
420 unsigned int reg); 416 unsigned int reg);
421int snd_soc_platform_write(struct snd_soc_platform *platform, 417int snd_soc_platform_write(struct snd_soc_platform *platform,
@@ -791,13 +787,11 @@ struct snd_soc_codec {
791 unsigned int ac97_registered:1; /* Codec has been AC97 registered */ 787 unsigned int ac97_registered:1; /* Codec has been AC97 registered */
792 unsigned int ac97_created:1; /* Codec has been created by SoC */ 788 unsigned int ac97_created:1; /* Codec has been created by SoC */
793 unsigned int cache_init:1; /* codec cache has been initialized */ 789 unsigned int cache_init:1; /* codec cache has been initialized */
794 u32 cache_sync; /* Cache needs to be synced to hardware */
795 790
796 /* codec IO */ 791 /* codec IO */
797 void *control_data; /* codec control (i2c/3wire) data */ 792 void *control_data; /* codec control (i2c/3wire) data */
798 hw_write_t hw_write; 793 hw_write_t hw_write;
799 void *reg_cache; 794 void *reg_cache;
800 struct mutex cache_rw_mutex;
801 795
802 /* component */ 796 /* component */
803 struct snd_soc_component component; 797 struct snd_soc_component component;
@@ -1264,6 +1258,17 @@ unsigned int snd_soc_read(struct snd_soc_codec *codec, unsigned int reg);
1264int snd_soc_write(struct snd_soc_codec *codec, unsigned int reg, 1258int snd_soc_write(struct snd_soc_codec *codec, unsigned int reg,
1265 unsigned int val); 1259 unsigned int val);
1266 1260
1261/**
1262 * snd_soc_cache_sync() - Sync the register cache with the hardware
1263 * @codec: CODEC to sync
1264 *
1265 * Note: This function will call regcache_sync()
1266 */
1267static inline int snd_soc_cache_sync(struct snd_soc_codec *codec)
1268{
1269 return regcache_sync(codec->component.regmap);
1270}
1271
1267/* component IO */ 1272/* component IO */
1268int snd_soc_component_read(struct snd_soc_component *component, 1273int snd_soc_component_read(struct snd_soc_component *component,
1269 unsigned int reg, unsigned int *val); 1274 unsigned int reg, unsigned int *val);
diff --git a/include/trace/events/asoc.h b/include/trace/events/asoc.h
index b04ee7e5a466..88cf39d96d0f 100644
--- a/include/trace/events/asoc.h
+++ b/include/trace/events/asoc.h
@@ -288,31 +288,6 @@ TRACE_EVENT(snd_soc_jack_notify,
288 TP_printk("jack=%s %x", __get_str(name), (int)__entry->val) 288 TP_printk("jack=%s %x", __get_str(name), (int)__entry->val)
289); 289);
290 290
291TRACE_EVENT(snd_soc_cache_sync,
292
293 TP_PROTO(struct snd_soc_codec *codec, const char *type,
294 const char *status),
295
296 TP_ARGS(codec, type, status),
297
298 TP_STRUCT__entry(
299 __string( name, codec->component.name)
300 __string( status, status )
301 __string( type, type )
302 __field( int, id )
303 ),
304
305 TP_fast_assign(
306 __assign_str(name, codec->component.name);
307 __assign_str(status, status);
308 __assign_str(type, type);
309 __entry->id = codec->component.id;
310 ),
311
312 TP_printk("codec=%s.%d type=%s status=%s", __get_str(name),
313 (int)__entry->id, __get_str(type), __get_str(status))
314);
315
316#endif /* _TRACE_ASOC_H */ 291#endif /* _TRACE_ASOC_H */
317 292
318/* This part must be outside protection */ 293/* This part must be outside protection */
diff --git a/sound/soc/soc-cache.c b/sound/soc/soc-cache.c
index 6dab81799b9a..07f43356f963 100644
--- a/sound/soc/soc-cache.c
+++ b/sound/soc/soc-cache.c
@@ -15,56 +15,6 @@
15#include <linux/export.h> 15#include <linux/export.h>
16#include <linux/slab.h> 16#include <linux/slab.h>
17 17
18#include <trace/events/asoc.h>
19
20static bool snd_soc_set_cache_val(void *base, unsigned int idx,
21 unsigned int val, unsigned int word_size)
22{
23 switch (word_size) {
24 case 1: {
25 u8 *cache = base;
26 if (cache[idx] == val)
27 return true;
28 cache[idx] = val;
29 break;
30 }
31 case 2: {
32 u16 *cache = base;
33 if (cache[idx] == val)
34 return true;
35 cache[idx] = val;
36 break;
37 }
38 default:
39 WARN(1, "Invalid word_size %d\n", word_size);
40 break;
41 }
42 return false;
43}
44
45static unsigned int snd_soc_get_cache_val(const void *base, unsigned int idx,
46 unsigned int word_size)
47{
48 if (!base)
49 return -1;
50
51 switch (word_size) {
52 case 1: {
53 const u8 *cache = base;
54 return cache[idx];
55 }
56 case 2: {
57 const u16 *cache = base;
58 return cache[idx];
59 }
60 default:
61 WARN(1, "Invalid word_size %d\n", word_size);
62 break;
63 }
64 /* unreachable */
65 return -1;
66}
67
68int snd_soc_cache_init(struct snd_soc_codec *codec) 18int snd_soc_cache_init(struct snd_soc_codec *codec)
69{ 19{
70 const struct snd_soc_codec_driver *codec_drv = codec->driver; 20 const struct snd_soc_codec_driver *codec_drv = codec->driver;
@@ -75,8 +25,6 @@ int snd_soc_cache_init(struct snd_soc_codec *codec)
75 if (!reg_size) 25 if (!reg_size)
76 return 0; 26 return 0;
77 27
78 mutex_init(&codec->cache_rw_mutex);
79
80 dev_dbg(codec->dev, "ASoC: Initializing cache for %s codec\n", 28 dev_dbg(codec->dev, "ASoC: Initializing cache for %s codec\n",
81 codec->component.name); 29 codec->component.name);
82 30
@@ -103,103 +51,3 @@ int snd_soc_cache_exit(struct snd_soc_codec *codec)
103 codec->reg_cache = NULL; 51 codec->reg_cache = NULL;
104 return 0; 52 return 0;
105} 53}
106
107/**
108 * snd_soc_cache_read: Fetch the value of a given register from the cache.
109 *
110 * @codec: CODEC to configure.
111 * @reg: The register index.
112 * @value: The value to be returned.
113 */
114int snd_soc_cache_read(struct snd_soc_codec *codec,
115 unsigned int reg, unsigned int *value)
116{
117 if (!value)
118 return -EINVAL;
119
120 mutex_lock(&codec->cache_rw_mutex);
121 if (!ZERO_OR_NULL_PTR(codec->reg_cache))
122 *value = snd_soc_get_cache_val(codec->reg_cache, reg,
123 codec->driver->reg_word_size);
124 mutex_unlock(&codec->cache_rw_mutex);
125
126 return 0;
127}
128EXPORT_SYMBOL_GPL(snd_soc_cache_read);
129
130/**
131 * snd_soc_cache_write: Set the value of a given register in the cache.
132 *
133 * @codec: CODEC to configure.
134 * @reg: The register index.
135 * @value: The new register value.
136 */
137int snd_soc_cache_write(struct snd_soc_codec *codec,
138 unsigned int reg, unsigned int value)
139{
140 mutex_lock(&codec->cache_rw_mutex);
141 if (!ZERO_OR_NULL_PTR(codec->reg_cache))
142 snd_soc_set_cache_val(codec->reg_cache, reg, value,
143 codec->driver->reg_word_size);
144 mutex_unlock(&codec->cache_rw_mutex);
145
146 return 0;
147}
148EXPORT_SYMBOL_GPL(snd_soc_cache_write);
149
150static int snd_soc_flat_cache_sync(struct snd_soc_codec *codec)
151{
152 int i;
153 int ret;
154 const struct snd_soc_codec_driver *codec_drv;
155 unsigned int val;
156
157 codec_drv = codec->driver;
158 for (i = 0; i < codec_drv->reg_cache_size; ++i) {
159 ret = snd_soc_cache_read(codec, i, &val);
160 if (ret)
161 return ret;
162 if (codec_drv->reg_cache_default)
163 if (snd_soc_get_cache_val(codec_drv->reg_cache_default,
164 i, codec_drv->reg_word_size) == val)
165 continue;
166
167 ret = snd_soc_write(codec, i, val);
168 if (ret)
169 return ret;
170 dev_dbg(codec->dev, "ASoC: Synced register %#x, value = %#x\n",
171 i, val);
172 }
173 return 0;
174}
175
176/**
177 * snd_soc_cache_sync: Sync the register cache with the hardware.
178 *
179 * @codec: CODEC to configure.
180 *
181 * Any registers that should not be synced should be marked as
182 * volatile. In general drivers can choose not to use the provided
183 * syncing functionality if they so require.
184 */
185int snd_soc_cache_sync(struct snd_soc_codec *codec)
186{
187 const char *name = "flat";
188 int ret;
189
190 if (codec->component.regmap)
191 return regcache_sync(codec->component.regmap);
192
193 if (!codec->cache_sync)
194 return 0;
195
196 dev_dbg(codec->dev, "ASoC: Syncing cache for %s codec\n",
197 codec->component.name);
198 trace_snd_soc_cache_sync(codec, name, "start");
199 ret = snd_soc_flat_cache_sync(codec);
200 if (!ret)
201 codec->cache_sync = 0;
202 trace_snd_soc_cache_sync(codec, name, "end");
203 return ret;
204}
205EXPORT_SYMBOL_GPL(snd_soc_cache_sync);
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 4c8f8a23a0e9..4e0e32bb9910 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -309,9 +309,6 @@ static void soc_init_codec_debugfs(struct snd_soc_component *component)
309{ 309{
310 struct snd_soc_codec *codec = snd_soc_component_to_codec(component); 310 struct snd_soc_codec *codec = snd_soc_component_to_codec(component);
311 311
312 debugfs_create_bool("cache_sync", 0444, codec->component.debugfs_root,
313 &codec->cache_sync);
314
315 codec->debugfs_reg = debugfs_create_file("codec_reg", 0644, 312 codec->debugfs_reg = debugfs_create_file("codec_reg", 0644,
316 codec->component.debugfs_root, 313 codec->component.debugfs_root,
317 codec, &codec_reg_fops); 314 codec, &codec_reg_fops);
@@ -656,7 +653,6 @@ int snd_soc_suspend(struct device *dev)
656 if (codec->driver->suspend) 653 if (codec->driver->suspend)
657 codec->driver->suspend(codec); 654 codec->driver->suspend(codec);
658 codec->suspended = 1; 655 codec->suspended = 1;
659 codec->cache_sync = 1;
660 if (codec->component.regmap) 656 if (codec->component.regmap)
661 regcache_mark_dirty(codec->component.regmap); 657 regcache_mark_dirty(codec->component.regmap);
662 /* deactivate pins to sleep state */ 658 /* deactivate pins to sleep state */