[alsa-devel] [PATCH 5/8] ASoC: Ux500: Add MSP I2S-driver

Ola Lilja ola.o.lilja at stericsson.com
Fri Apr 27 10:45:59 CEST 2012


On 04/23/2012 08:29 PM, Mark Brown wrote:

> On Fri, Apr 20, 2012 at 11:33:06AM +0200, Ola Lilja wrote:
> 
>> Add driver for running I2S with the MSP-block.
> 
> This depends on the change for the debug print function.  Otherwise
> there's a bunch of relatively minor stuff but overall this looks
> generally good.


Good to hear!

> 
>> +static int ux500_msp_dai_startup(struct snd_pcm_substream *substream,
>> +				struct snd_soc_dai *dai)
>> +{
>> +	int ret = 0;
>> +	struct ux500_msp_i2s_drvdata *drvdata = dev_get_drvdata(dai->dev);
>> +
>> +	dev_dbg(dai->dev, "%s: MSP %d (%s): Enter.\n", __func__, dai->id,
>> +		snd_soc_stream_str(substream));
>> +
>> +	/* Don't enable regulator if it's MSP1/3 */
> 
> Why not?


Other blocks take this regulator and when the driver needs to go into low-power
mode this other block will disable the regulator. However, for now I think we
can safely remove this special-case and take the regulator even for MSP1/3.

> 
>> +static void ux500_msp_dai_shutdown(struct snd_pcm_substream *substream,
>> +				struct snd_soc_dai *dai)
>> +{
> 
>> +	if (drvdata->reg_enabled) {
>> +		ret = regulator_disable(drvdata->reg_vape);
>> +		if (ret < 0)
>> +			dev_err(dai->dev,
>> +				"%s: ERROR: Failed to disable regulator (%d)!\n",
>> +				__func__, ret);
>> +		drvdata->reg_enabled = 0;
>> +	}
> 
> This looks like the driver is going to get confused with bidirectional
> audio - if one direction stops then it'll turn the regulator off.


Yes, will fix this.

> 
>> +	/* Don't enable regulator if it's MSP1/3 */
>> +	if (!drvdata->reg_enabled && (drvdata->msp->id != MSP_1_I2S_CONTROLLER)
>> +		&& (drvdata->msp->id != MSP_3_I2S_CONTROLLER)) {
> 
> This seems confused, you're enabling in multiple places...
> 


Indeed. Will fix.

>> +static int ux500_msp_dai_hw_params(struct snd_pcm_substream *substream,
>> +				struct snd_pcm_hw_params *params,
>> +				struct snd_soc_dai *dai)
>> +{
>> +	unsigned int mask, slots_active;
>> +	struct ux500_msp_i2s_drvdata *drvdata = dev_get_drvdata(dai->dev);
>> +
>> +	dev_dbg(dai->dev, "%s: MSP %d (%s): Enter.\n",
>> +			__func__, dai->id, snd_soc_stream_str(substream));
>> +
>> +	switch (drvdata->fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
>> +	case SND_SOC_DAIFMT_I2S:
>> +		if (params_channels(params) != 2) {
>> +			dev_err(dai->dev,
>> +				"%s: Error: I2S requires ch = 2 (ch = %d)!\n",
>> +				__func__, params_channels(params));
>> +			return -EINVAL;
>> +		}
> 
> Should really set up constraints for this, though in principle format
> can change at runtime (though it rarely does).  Perhaps we should do
> something special if the configuration happens on init...


OK, I will try to rewrite these checks to use constraints instead.

> 
>> +		if (params_channels(params) != slots_active) {
>> +			dev_err(dai->dev,
>> +				"%s: Error: Channels to slots mismatch (ch = %d, slots = %d)!\n",
>> +				__func__, params_channels(params),
>> +				slots_active);
>> +			return -EINVAL;
>> +		}
> 
> Similarly here.
> 
>> +	drvdata->reg_vape = regulator_get(NULL, "v-ape");
>> +	if (IS_ERR(drvdata->reg_vape)) {
> 
> No, this should be using the struct device.  Regulators should always
> be requested in the context of their consumer.  You could use
> devm_regulator_get() too (there's a clock one too, but only in -next).


OK, I'll look into that.

> 
>> +	ret = ux500_msp_i2s_init_msp(pdev, &drvdata->msp, platform_data);
>> +	if (!drvdata->msp) {
> 
> Should be no need to cast away from void.


OK, will change.

> 
>> +
>> +	ux500_msp_i2s_cleanup_msp(pdev, drvdata->msp);
>> +	devm_kfree(&pdev->dev, drvdata);
> 
> You're missing the point of devm_ here! :)


Ah! =)


More information about the Alsa-devel mailing list