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

Commit cfcff69a authored by Mark Brown's avatar Mark Brown
Browse files

ASoC: si476x: Fix locking of core



The conversion of the si476x to regmap removed locking of the core during
register updates, allowing things like power state changes for the MFD to
happen during a register update. Avoid this by taking the core lock in the
DAI operations (which are the only things that do register updates) as we
used to do in the open coded register I/O functions.

Signed-off-by: default avatarMark Brown <broonie@linaro.org>
Acked-by: default avatarAndrey Smirnov <andrew.smirnov@gmail.com>
parent d6173df3
Loading
Loading
Loading
Loading
+15 −3
Original line number Diff line number Diff line
@@ -73,6 +73,7 @@ static const struct snd_soc_dapm_route si476x_dapm_routes[] = {
static int si476x_codec_set_dai_fmt(struct snd_soc_dai *codec_dai,
				    unsigned int fmt)
{
	struct si476x_core *core = i2c_mfd_cell_to_core(codec_dai->dev);
	int err;
	u16 format = 0;

@@ -136,9 +137,14 @@ static int si476x_codec_set_dai_fmt(struct snd_soc_dai *codec_dai,
		return -EINVAL;
	}

	si476x_core_lock(core);

	err = snd_soc_update_bits(codec_dai->codec, SI476X_DIGITAL_IO_OUTPUT_FORMAT,
				  SI476X_DIGITAL_IO_OUTPUT_FORMAT_MASK,
				  format);

	si476x_core_unlock(core);

	if (err < 0) {
		dev_err(codec_dai->codec->dev, "Failed to set output format\n");
		return err;
@@ -151,6 +157,7 @@ static int si476x_codec_hw_params(struct snd_pcm_substream *substream,
				  struct snd_pcm_hw_params *params,
				  struct snd_soc_dai *dai)
{
	struct si476x_core *core = i2c_mfd_cell_to_core(dai->dev);
	int rate, width, err;

	rate = params_rate(params);
@@ -176,11 +183,13 @@ static int si476x_codec_hw_params(struct snd_pcm_substream *substream,
		return -EINVAL;
	}

	si476x_core_lock(core);

	err = snd_soc_write(dai->codec, SI476X_DIGITAL_IO_OUTPUT_SAMPLE_RATE,
			    rate);
	if (err < 0) {
		dev_err(dai->codec->dev, "Failed to set sample rate\n");
		return err;
		goto out;
	}

	err = snd_soc_update_bits(dai->codec, SI476X_DIGITAL_IO_OUTPUT_FORMAT,
@@ -189,10 +198,13 @@ static int si476x_codec_hw_params(struct snd_pcm_substream *substream,
				  (width << SI476X_DIGITAL_IO_SAMPLE_SIZE_SHIFT));
	if (err < 0) {
		dev_err(dai->codec->dev, "Failed to set output width\n");
		return err;
		goto out;
	}

	return 0;
out:
	si476x_core_unlock(core);

	return err;
}

static int si476x_codec_probe(struct snd_soc_codec *codec)