Commit 8a713da8 authored by Mark Brown's avatar Mark Brown

ASoC: Use regmap update bits operation for drivers using regmap

If a driver is using regmap directly ensure that we're coherent with
non-ASoC register updates by using the regmap API directly to do our
read/modify/write cycles. This will bypass the ASoC cache but drivers
using regmap directly should not be using the ASoC cache.
Signed-off-by: default avatarMark Brown <broonie@opensource.wolfsonmicro.com>
parent 278047fd
...@@ -560,6 +560,7 @@ struct snd_soc_codec { ...@@ -560,6 +560,7 @@ struct snd_soc_codec {
unsigned int ac97_created:1; /* Codec has been created by SoC */ unsigned int ac97_created:1; /* Codec has been created by SoC */
unsigned int sysfs_registered:1; /* codec has been sysfs registered */ unsigned int sysfs_registered:1; /* codec has been sysfs registered */
unsigned int cache_init:1; /* codec cache has been initialized */ unsigned int cache_init:1; /* codec cache has been initialized */
unsigned int using_regmap:1; /* using regmap access */
u32 cache_only; /* Suppress writes to hardware */ u32 cache_only; /* Suppress writes to hardware */
u32 cache_sync; /* Cache needs to be synced to hardware */ u32 cache_sync; /* Cache needs to be synced to hardware */
......
...@@ -1869,10 +1869,14 @@ EXPORT_SYMBOL_GPL(snd_soc_bulk_write_raw); ...@@ -1869,10 +1869,14 @@ EXPORT_SYMBOL_GPL(snd_soc_bulk_write_raw);
int snd_soc_update_bits(struct snd_soc_codec *codec, unsigned short reg, int snd_soc_update_bits(struct snd_soc_codec *codec, unsigned short reg,
unsigned int mask, unsigned int value) unsigned int mask, unsigned int value)
{ {
int change; bool change;
unsigned int old, new; unsigned int old, new;
int ret; int ret;
if (codec->using_regmap) {
ret = regmap_update_bits_check(codec->control_data, reg,
mask, value, &change);
} else {
ret = snd_soc_read(codec, reg); ret = snd_soc_read(codec, reg);
if (ret < 0) if (ret < 0)
return ret; return ret;
...@@ -1880,11 +1884,12 @@ int snd_soc_update_bits(struct snd_soc_codec *codec, unsigned short reg, ...@@ -1880,11 +1884,12 @@ int snd_soc_update_bits(struct snd_soc_codec *codec, unsigned short reg,
old = ret; old = ret;
new = (old & ~mask) | (value & mask); new = (old & ~mask) | (value & mask);
change = old != new; change = old != new;
if (change) { if (change)
ret = snd_soc_write(codec, reg, new); ret = snd_soc_write(codec, reg, new);
}
if (ret < 0) if (ret < 0)
return ret; return ret;
}
return change; return change;
} }
......
...@@ -197,10 +197,16 @@ static int soc_widget_write(struct snd_soc_dapm_widget *w, int reg, int val) ...@@ -197,10 +197,16 @@ static int soc_widget_write(struct snd_soc_dapm_widget *w, int reg, int val)
static int soc_widget_update_bits(struct snd_soc_dapm_widget *w, static int soc_widget_update_bits(struct snd_soc_dapm_widget *w,
unsigned short reg, unsigned int mask, unsigned int value) unsigned short reg, unsigned int mask, unsigned int value)
{ {
int change; bool change;
unsigned int old, new; unsigned int old, new;
int ret; int ret;
if (w->codec && w->codec->using_regmap) {
ret = regmap_update_bits_check(w->codec->control_data,
reg, mask, value, &change);
if (ret != 0)
return ret;
} else {
ret = soc_widget_read(w, reg); ret = soc_widget_read(w, reg);
if (ret < 0) if (ret < 0)
return ret; return ret;
...@@ -213,6 +219,7 @@ static int soc_widget_update_bits(struct snd_soc_dapm_widget *w, ...@@ -213,6 +219,7 @@ static int soc_widget_update_bits(struct snd_soc_dapm_widget *w,
if (ret < 0) if (ret < 0)
return ret; return ret;
} }
}
return change; return change;
} }
......
...@@ -140,6 +140,7 @@ int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec, ...@@ -140,6 +140,7 @@ int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec,
case SND_SOC_REGMAP: case SND_SOC_REGMAP:
/* Device has made its own regmap arrangements */ /* Device has made its own regmap arrangements */
codec->using_regmap = true;
break; break;
default: default:
......
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