Commit 066d16c3 authored by Dimitris Papastamos's avatar Dimitris Papastamos Committed by Mark Brown

ASoC: soc-cache: Add support for default readable()/volatile() functions

For common scenarios, device drivers can provide a table of all the
registers that are at least either readable/writable/volatile.  The idea
is that if a register lookup fails, all of its read/write/vol members
will be zero and will be treated as default.  This also reduces the
size of the register access array.
Signed-off-by: default avatarDimitris Papastamos <dp@opensource.wolfsonmicro.com>
Acked-by: default avatarLiam Girdwood <lrg@slimlogic.co.uk>
Signed-off-by: default avatarMark Brown <broonie@opensource.wolfsonmicro.com>
parent 3e8e2cc4
...@@ -276,6 +276,10 @@ int snd_soc_cache_write(struct snd_soc_codec *codec, ...@@ -276,6 +276,10 @@ int snd_soc_cache_write(struct snd_soc_codec *codec,
unsigned int reg, unsigned int value); unsigned int reg, unsigned int value);
int snd_soc_cache_read(struct snd_soc_codec *codec, int snd_soc_cache_read(struct snd_soc_codec *codec,
unsigned int reg, unsigned int *value); unsigned int reg, unsigned int *value);
int snd_soc_default_volatile_register(struct snd_soc_codec *codec,
unsigned int reg);
int snd_soc_default_readable_register(struct snd_soc_codec *codec,
unsigned int reg);
/* Utility functions to get clock rates from various things */ /* Utility functions to get clock rates from various things */
int snd_soc_calc_frame_size(int sample_size, int channels, int tdm_slots); int snd_soc_calc_frame_size(int sample_size, int channels, int tdm_slots);
...@@ -366,6 +370,22 @@ int snd_soc_get_volsw_2r_sx(struct snd_kcontrol *kcontrol, ...@@ -366,6 +370,22 @@ int snd_soc_get_volsw_2r_sx(struct snd_kcontrol *kcontrol,
int snd_soc_put_volsw_2r_sx(struct snd_kcontrol *kcontrol, int snd_soc_put_volsw_2r_sx(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol); struct snd_ctl_elem_value *ucontrol);
/**
* struct snd_soc_reg_access - Describes whether a given register is
* readable, writable or volatile.
*
* @reg: the register number
* @read: whether this register is readable
* @write: whether this register is writable
* @vol: whether this register is volatile
*/
struct snd_soc_reg_access {
u16 reg;
u16 read;
u16 write;
u16 vol;
};
/** /**
* struct snd_soc_jack_pin - Describes a pin to update based on jack detection * struct snd_soc_jack_pin - Describes a pin to update based on jack detection
* *
...@@ -515,6 +535,8 @@ struct snd_soc_codec_driver { ...@@ -515,6 +535,8 @@ struct snd_soc_codec_driver {
short reg_cache_step; short reg_cache_step;
short reg_word_size; short reg_word_size;
const void *reg_cache_default; const void *reg_cache_default;
short reg_access_size;
const struct snd_soc_reg_access *reg_access_default;
enum snd_soc_compress_type compress_type; enum snd_soc_compress_type compress_type;
/* codec bias level */ /* codec bias level */
......
...@@ -1603,3 +1603,52 @@ int snd_soc_cache_sync(struct snd_soc_codec *codec) ...@@ -1603,3 +1603,52 @@ int snd_soc_cache_sync(struct snd_soc_codec *codec)
return -EINVAL; return -EINVAL;
} }
EXPORT_SYMBOL_GPL(snd_soc_cache_sync); EXPORT_SYMBOL_GPL(snd_soc_cache_sync);
static int snd_soc_get_reg_access_index(struct snd_soc_codec *codec,
unsigned int reg)
{
const struct snd_soc_codec_driver *codec_drv;
unsigned int min, max, index;
codec_drv = codec->driver;
min = 0;
max = codec_drv->reg_access_size - 1;
do {
index = (min + max) / 2;
if (codec_drv->reg_access_default[index].reg == reg)
return index;
if (codec_drv->reg_access_default[index].reg < reg)
min = index + 1;
else
max = index;
} while (min <= max);
return -1;
}
int snd_soc_default_volatile_register(struct snd_soc_codec *codec,
unsigned int reg)
{
int index;
if (reg >= codec->driver->reg_cache_size)
return 1;
index = snd_soc_get_reg_access_index(codec, reg);
if (index < 0)
return 0;
return codec->driver->reg_access_default[index].vol;
}
EXPORT_SYMBOL_GPL(snd_soc_default_volatile_register);
int snd_soc_default_readable_register(struct snd_soc_codec *codec,
unsigned int reg)
{
int index;
if (reg >= codec->driver->reg_cache_size)
return 1;
index = snd_soc_get_reg_access_index(codec, reg);
if (index < 0)
return 0;
return codec->driver->reg_access_default[index].read;
}
EXPORT_SYMBOL_GPL(snd_soc_default_readable_register);
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment