mirror of
https://github.com/torvalds/linux.git
synced 2024-11-24 05:02:12 +00:00
Merge remote-tracking branch 'asoc/topic/cache' into asoc-next
This commit is contained in:
commit
3ee3f45463
@ -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);
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
|
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user