Skip to content

Commit

Permalink
ASoC: soc-cache: Clean up the cache manipulation code
Browse files Browse the repository at this point in the history
Use Takashi's clean up code to make the cache manipulation code more
readable.

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>
  • Loading branch information
Dimitris Papastamos authored and Mark Brown committed Jan 11, 2011
1 parent 0378b6a commit 1321e88
Showing 1 changed file with 82 additions and 148 deletions.
230 changes: 82 additions & 148 deletions sound/soc/soc-cache.c
Original file line number Diff line number Diff line change
Expand Up @@ -761,6 +761,49 @@ int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec,
}
EXPORT_SYMBOL_GPL(snd_soc_codec_set_cache_io);

static bool snd_soc_set_cache_val(void *base, unsigned int idx,
unsigned int val, unsigned int word_size)
{
switch (word_size) {
case 1: {
u8 *cache = base;
if (cache[idx] == val)
return true;
cache[idx] = val;
break;
}
case 2: {
u16 *cache = base;
if (cache[idx] == val)
return true;
cache[idx] = val;
break;
}
default:
BUG();
}
return false;
}

static unsigned int snd_soc_get_cache_val(const void *base, unsigned int idx,
unsigned int word_size)
{
switch (word_size) {
case 1: {
const u8 *cache = base;
return cache[idx];
}
case 2: {
const u16 *cache = base;
return cache[idx];
}
default:
BUG();
}
/* unreachable */
return -1;
}

struct snd_soc_rbtree_node {
struct rb_node node;
unsigned int reg;
Expand Down Expand Up @@ -924,7 +967,12 @@ static int snd_soc_rbtree_cache_exit(struct snd_soc_codec *codec)

static int snd_soc_rbtree_cache_init(struct snd_soc_codec *codec)
{
struct snd_soc_rbtree_node *rbtree_node;
struct snd_soc_rbtree_ctx *rbtree_ctx;
unsigned int val;
unsigned int word_size;
int i;
int ret;

codec->reg_cache = kmalloc(sizeof *rbtree_ctx, GFP_KERNEL);
if (!codec->reg_cache)
Expand All @@ -936,53 +984,25 @@ static int snd_soc_rbtree_cache_init(struct snd_soc_codec *codec)
if (!codec->reg_def_copy)
return 0;

/*
* populate the rbtree with the initialized registers. All other
* registers will be inserted into the tree when they are first written.
*
* The reasoning behind this, is that we need to step through and
* dereference the cache in u8/u16 increments without sacrificing
* portability. This could also be done using memcpy() but that would
* be slightly more cryptic.
*/
#define snd_soc_rbtree_populate(cache) \
({ \
int ret, i; \
struct snd_soc_rbtree_node *rbtree_node; \
\
ret = 0; \
cache = codec->reg_def_copy; \
for (i = 0; i < codec->driver->reg_cache_size; ++i) { \
if (!cache[i]) \
continue; \
rbtree_node = kzalloc(sizeof *rbtree_node, GFP_KERNEL); \
if (!rbtree_node) { \
ret = -ENOMEM; \
snd_soc_cache_exit(codec); \
break; \
} \
rbtree_node->reg = i; \
rbtree_node->value = cache[i]; \
rbtree_node->defval = cache[i]; \
snd_soc_rbtree_insert(&rbtree_ctx->root, \
rbtree_node); \
} \
ret; \
})

switch (codec->driver->reg_word_size) {
case 1: {
const u8 *cache;

return snd_soc_rbtree_populate(cache);
}
case 2: {
const u16 *cache;

return snd_soc_rbtree_populate(cache);
}
default:
BUG();
/*
* populate the rbtree with the initialized registers. All other
* registers will be inserted when they are first modified.
*/
word_size = codec->driver->reg_word_size;
for (i = 0; i < codec->driver->reg_cache_size; ++i) {
val = snd_soc_get_cache_val(codec->reg_def_copy, i, word_size);
if (!val)
continue;
rbtree_node = kzalloc(sizeof *rbtree_node, GFP_KERNEL);
if (!rbtree_node) {
ret = -ENOMEM;
snd_soc_cache_exit(codec);
break;
}
rbtree_node->reg = i;
rbtree_node->value = val;
rbtree_node->defval = val;
snd_soc_rbtree_insert(&rbtree_ctx->root, rbtree_node);
}

return 0;
Expand Down Expand Up @@ -1165,29 +1185,10 @@ static int snd_soc_lzo_cache_write(struct snd_soc_codec *codec,
}

/* write the new value to the cache */
switch (codec->driver->reg_word_size) {
case 1: {
u8 *cache;
cache = lzo_block->dst;
if (cache[blkpos] == value) {
kfree(lzo_block->dst);
goto out;
}
cache[blkpos] = value;
}
break;
case 2: {
u16 *cache;
cache = lzo_block->dst;
if (cache[blkpos] == value) {
kfree(lzo_block->dst);
goto out;
}
cache[blkpos] = value;
}
break;
default:
BUG();
if (snd_soc_set_cache_val(lzo_block->dst, blkpos, value,
codec->driver->reg_word_size)) {
kfree(lzo_block->dst);
goto out;
}

/* prepare the source to be the decompressed block */
Expand Down Expand Up @@ -1241,25 +1242,10 @@ static int snd_soc_lzo_cache_read(struct snd_soc_codec *codec,

/* decompress the block */
ret = snd_soc_lzo_decompress_cache_block(codec, lzo_block);
if (ret >= 0) {
if (ret >= 0)
/* fetch the value from the cache */
switch (codec->driver->reg_word_size) {
case 1: {
u8 *cache;
cache = lzo_block->dst;
*value = cache[blkpos];
}
break;
case 2: {
u16 *cache;
cache = lzo_block->dst;
*value = cache[blkpos];
}
break;
default:
BUG();
}
}
*value = snd_soc_get_cache_val(lzo_block->dst, blkpos,
codec->driver->reg_word_size);

kfree(lzo_block->dst);
/* restore the pointer and length of the compressed block */
Expand Down Expand Up @@ -1414,28 +1400,10 @@ static int snd_soc_flat_cache_sync(struct snd_soc_codec *codec)
ret = snd_soc_cache_read(codec, i, &val);
if (ret)
return ret;
if (codec_drv->reg_cache_default) {
switch (codec_drv->reg_word_size) {
case 1: {
const u8 *cache;

cache = codec_drv->reg_cache_default;
if (cache[i] == val)
continue;
}
break;
case 2: {
const u16 *cache;

cache = codec_drv->reg_cache_default;
if (cache[i] == val)
continue;
}
break;
default:
BUG();
}
}
if (codec_drv->reg_cache_default)
if (snd_soc_get_cache_val(codec_drv->reg_cache_default,
i, codec_drv->reg_word_size) == val)
continue;
ret = snd_soc_write(codec, i, val);
if (ret)
return ret;
Expand All @@ -1448,50 +1416,16 @@ static int snd_soc_flat_cache_sync(struct snd_soc_codec *codec)
static int snd_soc_flat_cache_write(struct snd_soc_codec *codec,
unsigned int reg, unsigned int value)
{
switch (codec->driver->reg_word_size) {
case 1: {
u8 *cache;

cache = codec->reg_cache;
cache[reg] = value;
}
break;
case 2: {
u16 *cache;

cache = codec->reg_cache;
cache[reg] = value;
}
break;
default:
BUG();
}

snd_soc_set_cache_val(codec->reg_cache, reg, value,
codec->driver->reg_word_size);
return 0;
}

static int snd_soc_flat_cache_read(struct snd_soc_codec *codec,
unsigned int reg, unsigned int *value)
{
switch (codec->driver->reg_word_size) {
case 1: {
u8 *cache;

cache = codec->reg_cache;
*value = cache[reg];
}
break;
case 2: {
u16 *cache;

cache = codec->reg_cache;
*value = cache[reg];
}
break;
default:
BUG();
}

*value = snd_soc_get_cache_val(codec->reg_cache, reg,
codec->driver->reg_word_size);
return 0;
}

Expand Down

0 comments on commit 1321e88

Please sign in to comment.