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 | |
| 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>
| -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; |
