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

ASoC: stm32: i2s: manage rebind issue



The commit e894efef ("ASoC: core: add support to card rebind")
allows to rebind the sound card after a rebind of one of its component.
With this commit, the sound card is actually rebound,
but may be no more functional.

Corrections:
- Call snd_dmaengine_pcm_register() before snd_soc_register_component().
- Call snd_dmaengine_pcm_unregister() and snd_soc_unregister_component()
explicitly from I2S driver.

Signed-off-by: default avatarOlivier Moysan <olivier.moysan@st.com>
Link: https://lore.kernel.org/r/20200318144125.9163-4-olivier.moysan@st.com


Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent 794df944
Loading
Loading
Loading
Loading
+29 −11
Original line number Diff line number Diff line
@@ -888,6 +888,14 @@ static int stm32_i2s_parse_dt(struct platform_device *pdev,
	return 0;
}

static int stm32_i2s_remove(struct platform_device *pdev)
{
	snd_dmaengine_pcm_unregister(&pdev->dev);
	snd_soc_unregister_component(&pdev->dev);

	return 0;
}

static int stm32_i2s_probe(struct platform_device *pdev)
{
	struct stm32_i2s_data *i2s;
@@ -921,47 +929,56 @@ static int stm32_i2s_probe(struct platform_device *pdev)
		return PTR_ERR(i2s->regmap);
	}

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

	ret = devm_snd_dmaengine_pcm_register(&pdev->dev,
					      &stm32_i2s_pcm_config, 0);
	ret = snd_dmaengine_pcm_register(&pdev->dev, &stm32_i2s_pcm_config, 0);
	if (ret) {
		if (ret != -EPROBE_DEFER)
			dev_err(&pdev->dev, "PCM DMA register error %d\n", ret);
		return ret;
	}

	ret = snd_soc_register_component(&pdev->dev, &stm32_i2s_component,
					 i2s->dai_drv, 1);
	if (ret) {
		snd_dmaengine_pcm_unregister(&pdev->dev);
		return ret;
	}

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

	ret = regmap_read(i2s->regmap, STM32_I2S_IPIDR_REG, &val);
	if (ret)
		return ret;
		goto error;

	if (val == I2S_IPIDR_NUMBER) {
		ret = regmap_read(i2s->regmap, STM32_I2S_HWCFGR_REG, &val);
		if (ret)
			return ret;
			goto error;

		if (!FIELD_GET(I2S_HWCFGR_I2S_SUPPORT_MASK, val)) {
			dev_err(&pdev->dev,
				"Device does not support i2s mode\n");
			return -EPERM;
			ret = -EPERM;
			goto error;
		}

		ret = regmap_read(i2s->regmap, STM32_I2S_VERR_REG, &val);
		if (ret)
			goto error;

		dev_dbg(&pdev->dev, "I2S version: %lu.%lu registered\n",
			FIELD_GET(I2S_VERR_MAJ_MASK, val),
			FIELD_GET(I2S_VERR_MIN_MASK, val));
	}

	return ret;

error:
	stm32_i2s_remove(pdev);

	return ret;
}

@@ -998,6 +1015,7 @@ static struct platform_driver stm32_i2s_driver = {
		.pm = &stm32_i2s_pm_ops,
	},
	.probe = stm32_i2s_probe,
	.remove = stm32_i2s_remove,
};

module_platform_driver(stm32_i2s_driver);