[PATCH 2/6] ASoC: sirf: add I2S CPU DAI driver
Mark Brown
broonie at kernel.org
Fri Jul 19 12:52:46 EDT 2013
On Fri, Jul 19, 2013 at 07:07:18PM +0800, Barry Song wrote:
Pretty good overall - there's a few things below but should all be
fairly small.
> +static int sirf_i2s_startup(struct snd_pcm_substream *substream,
> + struct snd_soc_dai *dai)
> +{
> +
> + struct sirf_i2s *si2s = snd_soc_dai_get_drvdata(dai);
> +
> + if (si2s->master_mode)
> + pwm_enable(si2s->mclk_pwm);
> + clk_prepare_enable(si2s->clk);
> +
> + device_reset(dai->dev);
> + snd_soc_dai_set_dma_data(dai, substream,
> + &sirf_i2s_dai_dma_data[substream->stream]);
> + return 0;
> +}
device_reset() sounds like it's not going to work for simultaneous
playback and capture.
> +static int sirf_i2s_trigger(struct snd_pcm_substream *substream,
> + int cmd, struct snd_soc_dai *dai)
> +{
> + struct sirf_i2s *si2s = snd_soc_dai_get_drvdata(dai);
> + int playback = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
> +
> + switch (cmd) {
> + case SNDRV_PCM_TRIGGER_START:
> + case SNDRV_PCM_TRIGGER_RESUME:
> + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
> + spin_lock(&si2s->lock);
> +
> + if (playback) {
> + /* First start the FIFO, then enable the tx/rx */
> + writel(AUDIO_FIFO_RESET,
> + si2s->base + AUDIO_CTRL_EXT_TXFIFO1_OP);
> + mdelay(1);
> + writel(AUDIO_FIFO_START,
> + si2s->base + AUDIO_CTRL_EXT_TXFIFO1_OP);
> + mdelay(1);
Do we really need these 1ms delays? They're very long for the
context...
> +static int sirf_i2s_prepare(struct snd_pcm_substream *substream,
> + struct snd_soc_dai *dai)
> +{
> + struct snd_pcm_runtime *runtime = substream->runtime;
> + struct sirf_i2s *si2s = snd_soc_dai_get_drvdata(dai);
> + u32 ctrl = readl(si2s->base + AUDIO_CTRL_I2S_CTRL);
> +
> + if (runtime->channels == 2)
> + ctrl &= ~I2S_SIX_CHANNELS;
> + else
> + ctrl |= I2S_SIX_CHANNELS;
A switch statement for the number of channels would make me happier
here.
> + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
> + case SND_SOC_DAIFMT_CBM_CFM:
> + ctrl = readl(si2s->base + AUDIO_CTRL_I2S_CTRL);
> + ctrl |= I2S_SLAVE_MODE;
> + writel(ctrl, si2s->base + AUDIO_CTRL_I2S_CTRL);
> + si2s->master_mode = 0;
> + break;
Do we need locking on all these register updates?
> + case SND_SOC_DAIFMT_CBS_CFS:
> + si2s->master_mode = 1;
> + return -EINVAL;
Should this be undoing the work done for _CBM_CFM?
> +#ifdef CONFIG_PM
> +static int sirf_i2s_suspend(struct platform_device *pdev,
> + pm_message_t state)
> +{
> + struct sirf_i2s *si2s = platform_get_drvdata(pdev);
> +
> + si2s->i2s_ctrl = readl(si2s->base+AUDIO_CTRL_I2S_CTRL);
> +
> + clk_disable_unprepare(si2s->clk);
> +
> + if (si2s->master_mode)
> + pwm_disable(si2s->mclk_pwm);
> + return 0;
> +}
Should these be runtime PM calls as well? Seems like the bus could be
unclocked whenever audio is not playing. If you need the clock to write
conifguraiton perhaps regmap-mmio could help?
> + spin_lock_init(&si2s->lock);
What is this lock actually protecting?
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20130719/727ea2f8/attachment.sig>
More information about the linux-arm-kernel
mailing list