diff --git a/sound/soc/bcm/bcm2835-i2s.c b/sound/soc/bcm/bcm2835-i2s.c index cbbf6723ba208..8be2e282837fb 100644 --- a/sound/soc/bcm/bcm2835-i2s.c +++ b/sound/soc/bcm/bcm2835-i2s.c @@ -149,8 +149,8 @@ static void bcm2835_i2s_stop_clock(struct bcm2835_i2s_dev *dev) dev->clk_prepared = false; } -static void bcm2835_i2s_clear_fifos(struct bcm2835_i2s_dev *dev, - bool tx, bool rx) +static int bcm2835_i2s_clear_fifos(struct bcm2835_i2s_dev *dev, + bool tx, bool rx) { int timeout = 1000; uint32_t syncval; @@ -187,8 +187,9 @@ static void bcm2835_i2s_clear_fifos(struct bcm2835_i2s_dev *dev, /* Wait for 2 PCM clock cycles */ /* - * Toggle the SYNC flag. After 2 PCM clock cycles it can be read back - * FIXME: This does not seem to work for slave mode! + * Toggle the SYNC flag. After 2 PCM clock cycles it can be read back. + * The reset will timeout in clock consumer mode without an external + * clock. */ regmap_read(dev->i2s_regmap, BCM2835_I2S_CS_A_REG, &syncval); syncval &= BCM2835_I2S_SYNC; @@ -204,7 +205,8 @@ static void bcm2835_i2s_clear_fifos(struct bcm2835_i2s_dev *dev, } if (!timeout) - dev_err(dev->dev, "I2S SYNC error!\n"); + dev_err(dev->dev, + "FIFO clear timed out: no PCM clock (clock consumer with the provider not running?)\n"); /* Stop clock if it was not running before */ if (!clk_was_prepared) @@ -213,6 +215,14 @@ static void bcm2835_i2s_clear_fifos(struct bcm2835_i2s_dev *dev, /* Restore I2S state */ regmap_update_bits(dev->i2s_regmap, BCM2835_I2S_CS_A_REG, BCM2835_I2S_RXON | BCM2835_I2S_TXON, i2s_active_state); + + /* + * Without the SYNC round trip the FIFOs were not actually cleared: + * starting DMA on top of a stale FIFO makes RX free-run (DREQ stuck + * high, the same dead word re-read at bus speed) and the state then + * survives further stream cycles. Fail the stream instead. + */ + return timeout ? 0 : -EIO; } static int bcm2835_i2s_set_dai_fmt(struct snd_soc_dai *dai, @@ -588,6 +598,11 @@ static int bcm2835_i2s_hw_params(struct snd_pcm_substream *substream, | BCM2835_I2S_RX(0x20), 0xffffffff); /* Clear FIFOs */ + /* + * May time out benignly here: on clock-consumer links the provider's + * clocks are often not running yet at hw_params time; the clear that + * must succeed is the one in .prepare. + */ bcm2835_i2s_clear_fifos(dev, true, true); dev_dbg(dev->dev, @@ -636,7 +651,13 @@ static int bcm2835_i2s_prepare(struct snd_pcm_substream *substream, bcm2835_i2s_clear_fifos(dev, true, false); else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE && (cs_reg & BCM2835_I2S_RXD)) - bcm2835_i2s_clear_fifos(dev, false, true); + /* + * Stale RX data with no working clock cannot be cleared: DMA + * would free-run over the dead FIFO (DREQ stuck high) and the + * poisoned state survives stream cycles. Fail this capture + * open instead of recording garbage. + */ + return bcm2835_i2s_clear_fifos(dev, false, true); return 0; }