diff options
Diffstat (limited to 'sound/soc/stm/stm32_i2s.c')
| -rw-r--r-- | sound/soc/stm/stm32_i2s.c | 75 | 
1 files changed, 55 insertions, 20 deletions
diff --git a/sound/soc/stm/stm32_i2s.c b/sound/soc/stm/stm32_i2s.c index 3e7226a53e53..7c4d63c33f15 100644 --- a/sound/soc/stm/stm32_i2s.c +++ b/sound/soc/stm/stm32_i2s.c @@ -831,25 +831,33 @@ static int stm32_i2s_parse_dt(struct platform_device *pdev,  	/* Get clocks */  	i2s->pclk = devm_clk_get(&pdev->dev, "pclk");  	if (IS_ERR(i2s->pclk)) { -		dev_err(&pdev->dev, "Could not get pclk\n"); +		if (PTR_ERR(i2s->pclk) != -EPROBE_DEFER) +			dev_err(&pdev->dev, "Could not get pclk: %ld\n", +				PTR_ERR(i2s->pclk));  		return PTR_ERR(i2s->pclk);  	}  	i2s->i2sclk = devm_clk_get(&pdev->dev, "i2sclk");  	if (IS_ERR(i2s->i2sclk)) { -		dev_err(&pdev->dev, "Could not get i2sclk\n"); +		if (PTR_ERR(i2s->i2sclk) != -EPROBE_DEFER) +			dev_err(&pdev->dev, "Could not get i2sclk: %ld\n", +				PTR_ERR(i2s->i2sclk));  		return PTR_ERR(i2s->i2sclk);  	}  	i2s->x8kclk = devm_clk_get(&pdev->dev, "x8k");  	if (IS_ERR(i2s->x8kclk)) { -		dev_err(&pdev->dev, "missing x8k parent clock\n"); +		if (PTR_ERR(i2s->x8kclk) != -EPROBE_DEFER) +			dev_err(&pdev->dev, "Could not get x8k parent clock: %ld\n", +				PTR_ERR(i2s->x8kclk));  		return PTR_ERR(i2s->x8kclk);  	}  	i2s->x11kclk = devm_clk_get(&pdev->dev, "x11k");  	if (IS_ERR(i2s->x11kclk)) { -		dev_err(&pdev->dev, "missing x11k parent clock\n"); +		if (PTR_ERR(i2s->x11kclk) != -EPROBE_DEFER) +			dev_err(&pdev->dev, "Could not get x11k parent clock: %ld\n", +				PTR_ERR(i2s->x11kclk));  		return PTR_ERR(i2s->x11kclk);  	} @@ -866,12 +874,24 @@ static int stm32_i2s_parse_dt(struct platform_device *pdev,  	}  	/* Reset */ -	rst = devm_reset_control_get_exclusive(&pdev->dev, NULL); -	if (!IS_ERR(rst)) { -		reset_control_assert(rst); -		udelay(2); -		reset_control_deassert(rst); +	rst = devm_reset_control_get_optional_exclusive(&pdev->dev, NULL); +	if (IS_ERR(rst)) { +		if (PTR_ERR(rst) != -EPROBE_DEFER) +			dev_err(&pdev->dev, "Reset controller error %ld\n", +				PTR_ERR(rst)); +		return PTR_ERR(rst);  	} +	reset_control_assert(rst); +	udelay(2); +	reset_control_deassert(rst); + +	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;  } @@ -903,42 +923,51 @@ static int stm32_i2s_probe(struct platform_device *pdev)  	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"); +		if (PTR_ERR(i2s->regmap) != -EPROBE_DEFER) +			dev_err(&pdev->dev, "Regmap init error %ld\n", +				PTR_ERR(i2s->regmap));  		return PTR_ERR(i2s->regmap);  	} -	ret = devm_snd_soc_register_component(&pdev->dev, &stm32_i2s_component, -					      i2s->dai_drv, 1); -	if (ret) +	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 = devm_snd_dmaengine_pcm_register(&pdev->dev, -					      &stm32_i2s_pcm_config, 0); -	if (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), @@ -946,6 +975,11 @@ static int stm32_i2s_probe(struct platform_device *pdev)  	}  	return ret; + +error: +	stm32_i2s_remove(pdev); + +	return ret;  }  MODULE_DEVICE_TABLE(of, stm32_i2s_ids); @@ -981,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);  |