1
0
Fork 0

Merge remote-tracking branch 'asoc/topic/cache' into asoc-next

hifive-unleashed-5.1
Mark Brown 2014-12-08 13:11:44 +00:00
commit 3ee3f45463
4 changed files with 12 additions and 185 deletions

View File

@ -409,13 +409,9 @@ int devm_snd_soc_register_component(struct device *dev,
const struct snd_soc_component_driver *cmpnt_drv,
struct snd_soc_dai_driver *dai_drv, int num_dai);
void snd_soc_unregister_component(struct device *dev);
int snd_soc_cache_sync(struct snd_soc_codec *codec);
int snd_soc_cache_init(struct snd_soc_codec *codec);
int snd_soc_cache_exit(struct snd_soc_codec *codec);
int snd_soc_cache_write(struct snd_soc_codec *codec,
unsigned int reg, unsigned int value);
int snd_soc_cache_read(struct snd_soc_codec *codec,
unsigned int reg, unsigned int *value);
int snd_soc_platform_read(struct snd_soc_platform *platform,
unsigned int reg);
int snd_soc_platform_write(struct snd_soc_platform *platform,
@ -791,13 +787,11 @@ struct snd_soc_codec {
unsigned int ac97_registered:1; /* Codec has been AC97 registered */
unsigned int ac97_created:1; /* Codec has been created by SoC */
unsigned int cache_init:1; /* codec cache has been initialized */
u32 cache_sync; /* Cache needs to be synced to hardware */
/* codec IO */
void *control_data; /* codec control (i2c/3wire) data */
hw_write_t hw_write;
void *reg_cache;
struct mutex cache_rw_mutex;
/* component */
struct snd_soc_component component;
@ -1264,6 +1258,17 @@ unsigned int snd_soc_read(struct snd_soc_codec *codec, unsigned int reg);
int snd_soc_write(struct snd_soc_codec *codec, unsigned int reg,
unsigned int val);
/**
* snd_soc_cache_sync() - Sync the register cache with the hardware
* @codec: CODEC to sync
*
* Note: This function will call regcache_sync()
*/
static inline int snd_soc_cache_sync(struct snd_soc_codec *codec)
{
return regcache_sync(codec->component.regmap);
}
/* component IO */
int snd_soc_component_read(struct snd_soc_component *component,
unsigned int reg, unsigned int *val);

View File

@ -288,31 +288,6 @@ TRACE_EVENT(snd_soc_jack_notify,
TP_printk("jack=%s %x", __get_str(name), (int)__entry->val)
);
TRACE_EVENT(snd_soc_cache_sync,
TP_PROTO(struct snd_soc_codec *codec, const char *type,
const char *status),
TP_ARGS(codec, type, status),
TP_STRUCT__entry(
__string( name, codec->component.name)
__string( status, status )
__string( type, type )
__field( int, id )
),
TP_fast_assign(
__assign_str(name, codec->component.name);
__assign_str(status, status);
__assign_str(type, type);
__entry->id = codec->component.id;
),
TP_printk("codec=%s.%d type=%s status=%s", __get_str(name),
(int)__entry->id, __get_str(type), __get_str(status))
);
#endif /* _TRACE_ASOC_H */
/* This part must be outside protection */

View File

@ -15,56 +15,6 @@
#include <linux/export.h>
#include <linux/slab.h>
#include <trace/events/asoc.h>
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:
WARN(1, "Invalid word_size %d\n", word_size);
break;
}
return false;
}
static unsigned int snd_soc_get_cache_val(const void *base, unsigned int idx,
unsigned int word_size)
{
if (!base)
return -1;
switch (word_size) {
case 1: {
const u8 *cache = base;
return cache[idx];
}
case 2: {
const u16 *cache = base;
return cache[idx];
}
default:
WARN(1, "Invalid word_size %d\n", word_size);
break;
}
/* unreachable */
return -1;
}
int snd_soc_cache_init(struct snd_soc_codec *codec)
{
const struct snd_soc_codec_driver *codec_drv = codec->driver;
@ -75,8 +25,6 @@ int snd_soc_cache_init(struct snd_soc_codec *codec)
if (!reg_size)
return 0;
mutex_init(&codec->cache_rw_mutex);
dev_dbg(codec->dev, "ASoC: Initializing cache for %s codec\n",
codec->component.name);
@ -103,100 +51,3 @@ int snd_soc_cache_exit(struct snd_soc_codec *codec)
codec->reg_cache = NULL;
return 0;
}
/**
* snd_soc_cache_read: Fetch the value of a given register from the cache.
*
* @codec: CODEC to configure.
* @reg: The register index.
* @value: The value to be returned.
*/
int snd_soc_cache_read(struct snd_soc_codec *codec,
unsigned int reg, unsigned int *value)
{
if (!value)
return -EINVAL;
mutex_lock(&codec->cache_rw_mutex);
if (!ZERO_OR_NULL_PTR(codec->reg_cache))
*value = snd_soc_get_cache_val(codec->reg_cache, reg,
codec->driver->reg_word_size);
mutex_unlock(&codec->cache_rw_mutex);
return 0;
}
EXPORT_SYMBOL_GPL(snd_soc_cache_read);
/**
* snd_soc_cache_write: Set the value of a given register in the cache.
*
* @codec: CODEC to configure.
* @reg: The register index.
* @value: The new register value.
*/
int snd_soc_cache_write(struct snd_soc_codec *codec,
unsigned int reg, unsigned int value)
{
mutex_lock(&codec->cache_rw_mutex);
if (!ZERO_OR_NULL_PTR(codec->reg_cache))
snd_soc_set_cache_val(codec->reg_cache, reg, value,
codec->driver->reg_word_size);
mutex_unlock(&codec->cache_rw_mutex);
return 0;
}
EXPORT_SYMBOL_GPL(snd_soc_cache_write);
static int snd_soc_flat_cache_sync(struct snd_soc_codec *codec)
{
int i;
int ret;
const struct snd_soc_codec_driver *codec_drv;
unsigned int val;
codec_drv = codec->driver;
for (i = 0; i < codec_drv->reg_cache_size; ++i) {
ret = snd_soc_cache_read(codec, i, &val);
if (ret)
return ret;
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;
dev_dbg(codec->dev, "ASoC: Synced register %#x, value = %#x\n",
i, val);
}
return 0;
}
/**
* snd_soc_cache_sync: Sync the register cache with the hardware.
*
* @codec: CODEC to configure.
*
* Any registers that should not be synced should be marked as
* volatile. In general drivers can choose not to use the provided
* syncing functionality if they so require.
*/
int snd_soc_cache_sync(struct snd_soc_codec *codec)
{
const char *name = "flat";
int ret;
if (!codec->cache_sync)
return 0;
dev_dbg(codec->dev, "ASoC: Syncing cache for %s codec\n",
codec->component.name);
trace_snd_soc_cache_sync(codec, name, "start");
ret = snd_soc_flat_cache_sync(codec);
if (!ret)
codec->cache_sync = 0;
trace_snd_soc_cache_sync(codec, name, "end");
return ret;
}
EXPORT_SYMBOL_GPL(snd_soc_cache_sync);

View File

@ -309,9 +309,6 @@ static void soc_init_codec_debugfs(struct snd_soc_component *component)
{
struct snd_soc_codec *codec = snd_soc_component_to_codec(component);
debugfs_create_bool("cache_sync", 0444, codec->component.debugfs_root,
&codec->cache_sync);
codec->debugfs_reg = debugfs_create_file("codec_reg", 0644,
codec->component.debugfs_root,
codec, &codec_reg_fops);
@ -656,7 +653,6 @@ int snd_soc_suspend(struct device *dev)
if (codec->driver->suspend)
codec->driver->suspend(codec);
codec->suspended = 1;
codec->cache_sync = 1;
if (codec->component.regmap)
regcache_mark_dirty(codec->component.regmap);
/* deactivate pins to sleep state */