diff options
author | Dimitris Papastamos <dp@opensource.wolfsonmicro.com> | 2010-09-22 08:25:47 -0400 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2010-09-23 14:48:11 -0400 |
commit | db49c146a8c0e8d49c0ff029c2496d47660dfb28 (patch) | |
tree | c4012f9a10941e2beaadb8e04ca33e6a61a42c3a /sound/soc/soc-cache.c | |
parent | 3e13f65e3aa51fc7009afc554683a0b182c057f5 (diff) |
ASoC: Delegate to hw specific read for volatile registers
Ensure that reads on volatile registers will correctly delegate
to the bus specific read function.
Signed-off-by: Dimitris Papastamos <dp@opensource.wolfsonmicro.com>
Acked-by: Liam Girdwood <lrg@slimlogic.co.uk>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'sound/soc/soc-cache.c')
-rw-r--r-- | sound/soc/soc-cache.c | 76 |
1 files changed, 50 insertions, 26 deletions
diff --git a/sound/soc/soc-cache.c b/sound/soc/soc-cache.c index 8a3f11cbcb2a..143d2be9eda9 100644 --- a/sound/soc/soc-cache.c +++ b/sound/soc/soc-cache.c | |||
@@ -19,8 +19,15 @@ static unsigned int snd_soc_4_12_read(struct snd_soc_codec *codec, | |||
19 | unsigned int reg) | 19 | unsigned int reg) |
20 | { | 20 | { |
21 | u16 *cache = codec->reg_cache; | 21 | u16 *cache = codec->reg_cache; |
22 | if (reg >= codec->driver->reg_cache_size) | 22 | |
23 | return -1; | 23 | if (reg >= codec->driver->reg_cache_size || |
24 | snd_soc_codec_volatile_register(codec, reg)) { | ||
25 | if (codec->cache_only) | ||
26 | return -1; | ||
27 | |||
28 | return codec->hw_read(codec, reg); | ||
29 | } | ||
30 | |||
24 | return cache[reg]; | 31 | return cache[reg]; |
25 | } | 32 | } |
26 | 33 | ||
@@ -31,13 +38,12 @@ static int snd_soc_4_12_write(struct snd_soc_codec *codec, unsigned int reg, | |||
31 | u8 data[2]; | 38 | u8 data[2]; |
32 | int ret; | 39 | int ret; |
33 | 40 | ||
34 | BUG_ON(codec->driver->volatile_register); | ||
35 | |||
36 | data[0] = (reg << 4) | ((value >> 8) & 0x000f); | 41 | data[0] = (reg << 4) | ((value >> 8) & 0x000f); |
37 | data[1] = value & 0x00ff; | 42 | data[1] = value & 0x00ff; |
38 | 43 | ||
39 | if (reg < codec->driver->reg_cache_size) | 44 | if (!snd_soc_codec_volatile_register(codec, reg) && |
40 | cache[reg] = value; | 45 | reg < codec->driver->reg_cache_size) |
46 | cache[reg] = value; | ||
41 | 47 | ||
42 | if (codec->cache_only) { | 48 | if (codec->cache_only) { |
43 | codec->cache_sync = 1; | 49 | codec->cache_sync = 1; |
@@ -89,8 +95,15 @@ static unsigned int snd_soc_7_9_read(struct snd_soc_codec *codec, | |||
89 | unsigned int reg) | 95 | unsigned int reg) |
90 | { | 96 | { |
91 | u16 *cache = codec->reg_cache; | 97 | u16 *cache = codec->reg_cache; |
92 | if (reg >= codec->driver->reg_cache_size) | 98 | |
93 | return -1; | 99 | if (reg >= codec->driver->reg_cache_size || |
100 | snd_soc_codec_volatile_register(codec, reg)) { | ||
101 | if (codec->cache_only) | ||
102 | return -1; | ||
103 | |||
104 | return codec->hw_read(codec, reg); | ||
105 | } | ||
106 | |||
94 | return cache[reg]; | 107 | return cache[reg]; |
95 | } | 108 | } |
96 | 109 | ||
@@ -101,13 +114,12 @@ static int snd_soc_7_9_write(struct snd_soc_codec *codec, unsigned int reg, | |||
101 | u8 data[2]; | 114 | u8 data[2]; |
102 | int ret; | 115 | int ret; |
103 | 116 | ||
104 | BUG_ON(codec->driver->volatile_register); | ||
105 | |||
106 | data[0] = (reg << 1) | ((value >> 8) & 0x0001); | 117 | data[0] = (reg << 1) | ((value >> 8) & 0x0001); |
107 | data[1] = value & 0x00ff; | 118 | data[1] = value & 0x00ff; |
108 | 119 | ||
109 | if (reg < codec->driver->reg_cache_size) | 120 | if (!snd_soc_codec_volatile_register(codec, reg) && |
110 | cache[reg] = value; | 121 | reg < codec->driver->reg_cache_size) |
122 | cache[reg] = value; | ||
111 | 123 | ||
112 | if (codec->cache_only) { | 124 | if (codec->cache_only) { |
113 | codec->cache_sync = 1; | 125 | codec->cache_sync = 1; |
@@ -161,14 +173,13 @@ static int snd_soc_8_8_write(struct snd_soc_codec *codec, unsigned int reg, | |||
161 | u8 *cache = codec->reg_cache; | 173 | u8 *cache = codec->reg_cache; |
162 | u8 data[2]; | 174 | u8 data[2]; |
163 | 175 | ||
164 | BUG_ON(codec->driver->volatile_register); | ||
165 | |||
166 | reg &= 0xff; | 176 | reg &= 0xff; |
167 | data[0] = reg; | 177 | data[0] = reg; |
168 | data[1] = value & 0xff; | 178 | data[1] = value & 0xff; |
169 | 179 | ||
170 | if (reg < codec->driver->reg_cache_size) | 180 | if (!snd_soc_codec_volatile_register(codec, value) && |
171 | cache[reg] = value; | 181 | reg < codec->driver->reg_cache_size) |
182 | cache[reg] = value; | ||
172 | 183 | ||
173 | if (codec->cache_only) { | 184 | if (codec->cache_only) { |
174 | codec->cache_sync = 1; | 185 | codec->cache_sync = 1; |
@@ -187,9 +198,16 @@ static unsigned int snd_soc_8_8_read(struct snd_soc_codec *codec, | |||
187 | unsigned int reg) | 198 | unsigned int reg) |
188 | { | 199 | { |
189 | u8 *cache = codec->reg_cache; | 200 | u8 *cache = codec->reg_cache; |
201 | |||
190 | reg &= 0xff; | 202 | reg &= 0xff; |
191 | if (reg >= codec->driver->reg_cache_size) | 203 | if (reg >= codec->driver->reg_cache_size || |
192 | return -1; | 204 | snd_soc_codec_volatile_register(codec, reg)) { |
205 | if (codec->cache_only) | ||
206 | return -1; | ||
207 | |||
208 | return codec->hw_read(codec, reg); | ||
209 | } | ||
210 | |||
193 | return cache[reg]; | 211 | return cache[reg]; |
194 | } | 212 | } |
195 | 213 | ||
@@ -344,8 +362,14 @@ static unsigned int snd_soc_16_8_read(struct snd_soc_codec *codec, | |||
344 | u8 *cache = codec->reg_cache; | 362 | u8 *cache = codec->reg_cache; |
345 | 363 | ||
346 | reg &= 0xff; | 364 | reg &= 0xff; |
347 | if (reg >= codec->driver->reg_cache_size) | 365 | if (reg >= codec->driver->reg_cache_size || |
348 | return -1; | 366 | snd_soc_codec_volatile_register(codec, reg)) { |
367 | if (codec->cache_only) | ||
368 | return -1; | ||
369 | |||
370 | return codec->hw_read(codec, reg); | ||
371 | } | ||
372 | |||
349 | return cache[reg]; | 373 | return cache[reg]; |
350 | } | 374 | } |
351 | 375 | ||
@@ -356,15 +380,14 @@ static int snd_soc_16_8_write(struct snd_soc_codec *codec, unsigned int reg, | |||
356 | u8 data[3]; | 380 | u8 data[3]; |
357 | int ret; | 381 | int ret; |
358 | 382 | ||
359 | BUG_ON(codec->driver->volatile_register); | ||
360 | |||
361 | data[0] = (reg >> 8) & 0xff; | 383 | data[0] = (reg >> 8) & 0xff; |
362 | data[1] = reg & 0xff; | 384 | data[1] = reg & 0xff; |
363 | data[2] = value; | 385 | data[2] = value; |
364 | 386 | ||
365 | reg &= 0xff; | 387 | reg &= 0xff; |
366 | if (reg < codec->driver->reg_cache_size) | 388 | if (!snd_soc_codec_volatile_register(codec, reg) && |
367 | cache[reg] = value; | 389 | reg < codec->driver->reg_cache_size) |
390 | cache[reg] = value; | ||
368 | 391 | ||
369 | if (codec->cache_only) { | 392 | if (codec->cache_only) { |
370 | codec->cache_sync = 1; | 393 | codec->cache_sync = 1; |
@@ -475,8 +498,9 @@ static int snd_soc_16_16_write(struct snd_soc_codec *codec, unsigned int reg, | |||
475 | data[2] = (value >> 8) & 0xff; | 498 | data[2] = (value >> 8) & 0xff; |
476 | data[3] = value & 0xff; | 499 | data[3] = value & 0xff; |
477 | 500 | ||
478 | if (reg < codec->driver->reg_cache_size) | 501 | if (!snd_soc_codec_volatile_register(codec, reg) && |
479 | cache[reg] = value; | 502 | reg < codec->driver->reg_cache_size) |
503 | cache[reg] = value; | ||
480 | 504 | ||
481 | if (codec->cache_only) { | 505 | if (codec->cache_only) { |
482 | codec->cache_sync = 1; | 506 | codec->cache_sync = 1; |