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?