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

Commit 33ffe080 authored by Olivier Moysan's avatar Olivier Moysan Committed by Greg Kroah-Hartman
Browse files

ASoC: stm32: dfsdm: manage multiple prepare



[ Upstream commit 19441e35a43b616ea6afad91ed0d9e77268d8f6a ]

The DFSDM must be stopped when a new setting is applied.
restart systematically DFSDM on multiple prepare calls,
to apply changes.

Signed-off-by: default avatarOlivier Moysan <olivier.moysan@st.com>
Signed-off-by: default avatarMark Brown <broonie@kernel.org>
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
parent 74f5898f
Loading
Loading
Loading
Loading
+16 −1
Original line number Diff line number Diff line
@@ -9,6 +9,7 @@

#include <linux/clk.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/platform_device.h>
#include <linux/slab.h>

@@ -37,6 +38,8 @@ struct stm32_adfsdm_priv {
	/* PCM buffer */
	unsigned char *pcm_buff;
	unsigned int pos;

	struct mutex lock; /* protect against race condition on iio state */
};

static const struct snd_pcm_hardware stm32_adfsdm_pcm_hw = {
@@ -62,10 +65,12 @@ static void stm32_adfsdm_shutdown(struct snd_pcm_substream *substream,
{
	struct stm32_adfsdm_priv *priv = snd_soc_dai_get_drvdata(dai);

	mutex_lock(&priv->lock);
	if (priv->iio_active) {
		iio_channel_stop_all_cb(priv->iio_cb);
		priv->iio_active = false;
	}
	mutex_unlock(&priv->lock);
}

static int stm32_adfsdm_dai_prepare(struct snd_pcm_substream *substream,
@@ -74,13 +79,19 @@ static int stm32_adfsdm_dai_prepare(struct snd_pcm_substream *substream,
	struct stm32_adfsdm_priv *priv = snd_soc_dai_get_drvdata(dai);
	int ret;

	mutex_lock(&priv->lock);
	if (priv->iio_active) {
		iio_channel_stop_all_cb(priv->iio_cb);
		priv->iio_active = false;
	}

	ret = iio_write_channel_attribute(priv->iio_ch,
					  substream->runtime->rate, 0,
					  IIO_CHAN_INFO_SAMP_FREQ);
	if (ret < 0) {
		dev_err(dai->dev, "%s: Failed to set %d sampling rate\n",
			__func__, substream->runtime->rate);
		return ret;
		goto out;
	}

	if (!priv->iio_active) {
@@ -92,6 +103,9 @@ static int stm32_adfsdm_dai_prepare(struct snd_pcm_substream *substream,
				__func__, ret);
	}

out:
	mutex_unlock(&priv->lock);

	return ret;
}

@@ -298,6 +312,7 @@ static int stm32_adfsdm_probe(struct platform_device *pdev)

	priv->dev = &pdev->dev;
	priv->dai_drv = stm32_adfsdm_dai;
	mutex_init(&priv->lock);

	dev_set_drvdata(&pdev->dev, priv);