Unverified Commit 6a68eeee authored by Olivier Moysan's avatar Olivier Moysan Committed by Mark Brown
Browse files

SoC: stm32: i2s: manage clock power



Kernel clock management:
Enable/disable I2S kernel clock on audio stream startup/shutdown.

Peripheral clock management:
Manage I2S peripheral clock power through regmap services.

Signed-off-by: default avatarOlivier Moysan <olivier.moysan@st.com>
Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent 307cce4a
Loading
Loading
Loading
Loading
+15 −29
Original line number Diff line number Diff line
@@ -545,9 +545,16 @@ static int stm32_i2s_startup(struct snd_pcm_substream *substream,
			     struct snd_soc_dai *cpu_dai)
{
	struct stm32_i2s_data *i2s = snd_soc_dai_get_drvdata(cpu_dai);
	int ret;

	i2s->substream = substream;

	ret = clk_prepare_enable(i2s->i2sclk);
	if (ret < 0) {
		dev_err(cpu_dai->dev, "Failed to enable clock: %d\n", ret);
		return ret;
	}

	spin_lock(&i2s->lock_fd);
	i2s->refcount++;
	spin_unlock(&i2s->lock_fd);
@@ -674,6 +681,8 @@ static void stm32_i2s_shutdown(struct snd_pcm_substream *substream,

	regmap_update_bits(i2s->regmap, STM32_I2S_CGFR_REG,
			   I2S_CGFR_MCKOE, (unsigned int)~I2S_CGFR_MCKOE);

	clk_disable_unprepare(i2s->i2sclk);
}

static int stm32_i2s_dai_probe(struct snd_soc_dai *cpu_dai)
@@ -874,49 +883,26 @@ static int stm32_i2s_probe(struct platform_device *pdev)
	if (ret)
		return ret;

	i2s->regmap = devm_regmap_init_mmio(&pdev->dev, i2s->base,
					    i2s->regmap_conf);
	i2s->regmap = devm_regmap_init_mmio_clk(&pdev->dev, "pclk",
						i2s->base, i2s->regmap_conf);
	if (IS_ERR(i2s->regmap)) {
		dev_err(&pdev->dev, "regmap init failed\n");
		return PTR_ERR(i2s->regmap);
	}

	ret = clk_prepare_enable(i2s->pclk);
	if (ret) {
		dev_err(&pdev->dev, "Enable pclk failed: %d\n", ret);
		return ret;
	}

	ret = clk_prepare_enable(i2s->i2sclk);
	if (ret) {
		dev_err(&pdev->dev, "Enable i2sclk failed: %d\n", ret);
		goto err_pclk_disable;
	}

	ret = devm_snd_soc_register_component(&pdev->dev, &stm32_i2s_component,
					      i2s->dai_drv, 1);
	if (ret)
		goto err_clocks_disable;
		return ret;

	ret = devm_snd_dmaengine_pcm_register(&pdev->dev,
					      &stm32_i2s_pcm_config, 0);
	if (ret)
		goto err_clocks_disable;
		return ret;

	/* Set SPI/I2S in i2s mode */
	ret = regmap_update_bits(i2s->regmap, STM32_I2S_CGFR_REG,
	return regmap_update_bits(i2s->regmap, STM32_I2S_CGFR_REG,
				  I2S_CGFR_I2SMOD, I2S_CGFR_I2SMOD);
	if (ret)
		goto err_clocks_disable;

	return ret;

err_clocks_disable:
	clk_disable_unprepare(i2s->i2sclk);
err_pclk_disable:
	clk_disable_unprepare(i2s->pclk);

	return ret;
}

static int stm32_i2s_remove(struct platform_device *pdev)