Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+1 −0
Original line number Original line Diff line number Diff line
@@ -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 */


+15 −10
Original line number Original line Diff line number Diff line
@@ -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,
		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;
}
}
+17 −10
Original line number Original line Diff line number Diff line
@@ -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,
			if (ret < 0)
			if (ret < 0)
				return ret;
				return ret;
		}
		}
	}


	return change;
	return change;
}
}
+1 −0
Original line number Original line Diff line number Diff line
@@ -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: