msg[1] = data[0];
spi_message_init(&m);
- memset(&t, 0, (sizeof t));
+ memset(&t, 0, sizeof t);
t.tx_buf = &msg[0];
t.len = len;
msg[1] = data[1];
spi_message_init(&m);
- memset(&t, 0, (sizeof t));
+ memset(&t, 0, sizeof t);
t.tx_buf = &msg[0];
t.len = len;
msg[1] = data[1];
spi_message_init(&m);
- memset(&t, 0, (sizeof t));
+ memset(&t, 0, sizeof t);
t.tx_buf = &msg[0];
t.len = len;
msg[2] = data[2];
spi_message_init(&m);
- memset(&t, 0, (sizeof t));
+ memset(&t, 0, sizeof t);
t.tx_buf = &msg[0];
t.len = len;
msg[2] = data[2];
spi_message_init(&m);
- memset(&t, 0, (sizeof t));
+ memset(&t, 0, sizeof t);
t.tx_buf = &msg[0];
t.len = len;
msg[3] = data[3];
spi_message_init(&m);
- memset(&t, 0, (sizeof t));
+ memset(&t, 0, sizeof t);
t.tx_buf = &msg[0];
t.len = len;
return -EINVAL;
}
- codec->driver->write = io_types[i].write;
- codec->driver->read = io_types[i].read;
+ codec->write = io_types[i].write;
+ codec->read = io_types[i].read;
switch (control) {
case SND_SOC_CUSTOM:
rbtree_ctx = codec->reg_cache;
rbtree_ctx->root = RB_ROOT;
- if (!codec->driver->reg_cache_default)
+ if (!codec->reg_def_copy)
return 0;
/*
struct snd_soc_rbtree_node *rbtree_node; \
\
ret = 0; \
- cache = codec->driver->reg_cache_default; \
+ cache = codec->reg_def_copy; \
for (i = 0; i < codec->driver->reg_cache_size; ++i) { \
if (!cache[i]) \
continue; \
return 0;
}
+#ifdef CONFIG_SND_SOC_CACHE_LZO
struct snd_soc_lzo_ctx {
void *wmem;
void *dst;
static inline int snd_soc_lzo_get_blkindex(struct snd_soc_codec *codec,
unsigned int reg)
{
- struct snd_soc_codec_driver *codec_drv;
+ const struct snd_soc_codec_driver *codec_drv;
size_t reg_size;
codec_drv = codec->driver;
static inline int snd_soc_lzo_get_blkpos(struct snd_soc_codec *codec,
unsigned int reg)
{
- struct snd_soc_codec_driver *codec_drv;
+ const struct snd_soc_codec_driver *codec_drv;
size_t reg_size;
codec_drv = codec->driver;
static inline int snd_soc_lzo_get_blksize(struct snd_soc_codec *codec)
{
- struct snd_soc_codec_driver *codec_drv;
+ const struct snd_soc_codec_driver *codec_drv;
size_t reg_size;
codec_drv = codec->driver;
{
struct snd_soc_lzo_ctx **lzo_blocks;
size_t reg_size, bmp_size;
- struct snd_soc_codec_driver *codec_drv;
+ const struct snd_soc_codec_driver *codec_drv;
int ret, tofree, i, blksize, blkcount;
const char *p, *end;
unsigned long *sync_bmp;
* and remember to free it afterwards.
*/
tofree = 0;
- if (!codec_drv->reg_cache_default)
+ if (!codec->reg_def_copy)
tofree = 1;
- if (!codec_drv->reg_cache_default) {
- codec_drv->reg_cache_default = kzalloc(reg_size,
+ if (!codec->reg_def_copy) {
+ codec->reg_def_copy = kzalloc(reg_size,
GFP_KERNEL);
- if (!codec_drv->reg_cache_default)
+ if (!codec->reg_def_copy)
return -ENOMEM;
}
* that register.
*/
bmp_size = codec_drv->reg_cache_size;
- sync_bmp = kmalloc(BITS_TO_LONGS(bmp_size) * sizeof (long),
+ sync_bmp = kmalloc(BITS_TO_LONGS(bmp_size) * sizeof(long),
GFP_KERNEL);
if (!sync_bmp) {
ret = -ENOMEM;
goto err;
}
- bitmap_zero(sync_bmp, reg_size);
+ bitmap_zero(sync_bmp, bmp_size);
/* allocate the lzo blocks and initialize them */
for (i = 0; i < blkcount; ++i) {
goto err;
}
lzo_blocks[i]->sync_bmp = sync_bmp;
- lzo_blocks[i]->sync_bmp_nbits = reg_size;
+ lzo_blocks[i]->sync_bmp_nbits = bmp_size;
/* alloc the working space for the compressed block */
ret = snd_soc_lzo_prepare(lzo_blocks[i]);
if (ret < 0)
}
blksize = snd_soc_lzo_get_blksize(codec);
- p = codec_drv->reg_cache_default;
- end = codec_drv->reg_cache_default + reg_size;
+ p = codec->reg_def_copy;
+ end = codec->reg_def_copy + reg_size;
/* compress the register map and fill the lzo blocks */
for (i = 0; i < blkcount; ++i, p += blksize) {
lzo_blocks[i]->src = p;
lzo_blocks[i]->src_len;
}
- if (tofree)
- kfree(codec_drv->reg_cache_default);
+ if (tofree) {
+ kfree(codec->reg_def_copy);
+ codec->reg_def_copy = NULL;
+ }
return 0;
err:
snd_soc_cache_exit(codec);
err_tofree:
- if (tofree)
- kfree(codec_drv->reg_cache_default);
+ if (tofree) {
+ kfree(codec->reg_def_copy);
+ codec->reg_def_copy = NULL;
+ }
return ret;
}
+#endif
static int snd_soc_flat_cache_sync(struct snd_soc_codec *codec)
{
int i;
int ret;
- struct snd_soc_codec_driver *codec_drv;
+ const struct snd_soc_codec_driver *codec_drv;
unsigned int val;
codec_drv = codec->driver;
static int snd_soc_flat_cache_init(struct snd_soc_codec *codec)
{
- struct snd_soc_codec_driver *codec_drv;
+ const struct snd_soc_codec_driver *codec_drv;
size_t reg_size;
codec_drv = codec->driver;
reg_size = codec_drv->reg_cache_size * codec_drv->reg_word_size;
+ /*
+ * for flat compression, we don't need to keep a copy of the
+ * original defaults register cache as it will definitely not
+ * be marked as __devinitconst
+ */
+ kfree(codec->reg_def_copy);
+ codec->reg_def_copy = NULL;
+
if (codec_drv->reg_cache_default)
codec->reg_cache = kmemdup(codec_drv->reg_cache_default,
reg_size, GFP_KERNEL);
/* an array of all supported compression types */
static const struct snd_soc_cache_ops cache_types[] = {
+ /* Flat *must* be the first entry for fallback */
{
- .id = SND_SOC_NO_COMPRESSION,
+ .id = SND_SOC_FLAT_COMPRESSION,
+ .name = "flat",
.init = snd_soc_flat_cache_init,
.exit = snd_soc_flat_cache_exit,
.read = snd_soc_flat_cache_read,
.write = snd_soc_flat_cache_write,
.sync = snd_soc_flat_cache_sync
},
+#ifdef CONFIG_SND_SOC_CACHE_LZO
{
.id = SND_SOC_LZO_COMPRESSION,
+ .name = "LZO",
.init = snd_soc_lzo_cache_init,
.exit = snd_soc_lzo_cache_exit,
.read = snd_soc_lzo_cache_read,
.write = snd_soc_lzo_cache_write,
.sync = snd_soc_lzo_cache_sync
},
+#endif
{
.id = SND_SOC_RBTREE_COMPRESSION,
+ .name = "rbtree",
.init = snd_soc_rbtree_cache_init,
.exit = snd_soc_rbtree_cache_exit,
.read = snd_soc_rbtree_cache_read,
int i;
for (i = 0; i < ARRAY_SIZE(cache_types); ++i)
- if (cache_types[i].id == codec->driver->compress_type)
+ if (cache_types[i].id == codec->compress_type)
break;
+
+ /* Fall back to flat compression */
if (i == ARRAY_SIZE(cache_types)) {
- dev_err(codec->dev, "Could not match compress type: %d\n",
- codec->driver->compress_type);
- return -EINVAL;
+ dev_warn(codec->dev, "Could not match compress type: %d\n",
+ codec->compress_type);
+ i = 0;
}
mutex_init(&codec->cache_rw_mutex);
codec->cache_ops = &cache_types[i];
- if (codec->cache_ops->init)
+ if (codec->cache_ops->init) {
+ if (codec->cache_ops->name)
+ dev_dbg(codec->dev, "Initializing %s cache for %s codec\n",
+ codec->cache_ops->name, codec->name);
return codec->cache_ops->init(codec);
+ }
return -EINVAL;
}
*/
int snd_soc_cache_exit(struct snd_soc_codec *codec)
{
- if (codec->cache_ops && codec->cache_ops->exit)
+ if (codec->cache_ops && codec->cache_ops->exit) {
+ if (codec->cache_ops->name)
+ dev_dbg(codec->dev, "Destroying %s cache for %s codec\n",
+ codec->cache_ops->name, codec->name);
return codec->cache_ops->exit(codec);
+ }
return -EINVAL;
}
}
if (codec->cache_ops && codec->cache_ops->sync) {
+ if (codec->cache_ops->name)
+ dev_dbg(codec->dev, "Syncing %s cache for %s codec\n",
+ codec->cache_ops->name, codec->name);
ret = codec->cache_ops->sync(codec);
if (!ret)
codec->cache_sync = 0;