ASoC: sh: rz-ssi: Drop calling rz_ssi_pio_recv() recursively
Instead of recursively calling rz_ssi_pio_recv() use a while loop
to read the samples from RX fifo.
This also fixes an issue where the return value of rz_ssi_pio_recv()
was ignored when called recursively.
Fixes: 03e786bd43
("ASoC: sh: Add RZ/G2L SSIF-2 driver")
Reported-by: Pavel Machek <pavel@denx.de>
Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
Reviewed-by: Biju Das <biju.das.jz@bp.renesas.com>
Link: https://lore.kernel.org/r/20220110094711.8574-2-prabhakar.mahadev-lad.rj@bp.renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
Родитель
6cbff4b3a1
Коммит
6570f99158
|
@ -411,55 +411,57 @@ static int rz_ssi_pio_recv(struct rz_ssi_priv *ssi, struct rz_ssi_stream *strm)
|
|||
{
|
||||
struct snd_pcm_substream *substream = strm->substream;
|
||||
struct snd_pcm_runtime *runtime;
|
||||
bool done = false;
|
||||
u16 *buf;
|
||||
int fifo_samples;
|
||||
int frames_left;
|
||||
int samples = 0;
|
||||
int samples;
|
||||
int i;
|
||||
|
||||
if (!rz_ssi_stream_is_valid(ssi, strm))
|
||||
return -EINVAL;
|
||||
|
||||
runtime = substream->runtime;
|
||||
/* frames left in this period */
|
||||
frames_left = runtime->period_size - (strm->buffer_pos %
|
||||
runtime->period_size);
|
||||
if (frames_left == 0)
|
||||
frames_left = runtime->period_size;
|
||||
|
||||
/* Samples in RX FIFO */
|
||||
fifo_samples = (rz_ssi_reg_readl(ssi, SSIFSR) >>
|
||||
SSIFSR_RDC_SHIFT) & SSIFSR_RDC_MASK;
|
||||
while (!done) {
|
||||
/* frames left in this period */
|
||||
frames_left = runtime->period_size -
|
||||
(strm->buffer_pos % runtime->period_size);
|
||||
if (!frames_left)
|
||||
frames_left = runtime->period_size;
|
||||
|
||||
/* Only read full frames at a time */
|
||||
while (frames_left && (fifo_samples >= runtime->channels)) {
|
||||
samples += runtime->channels;
|
||||
fifo_samples -= runtime->channels;
|
||||
frames_left--;
|
||||
/* Samples in RX FIFO */
|
||||
fifo_samples = (rz_ssi_reg_readl(ssi, SSIFSR) >>
|
||||
SSIFSR_RDC_SHIFT) & SSIFSR_RDC_MASK;
|
||||
|
||||
/* Only read full frames at a time */
|
||||
samples = 0;
|
||||
while (frames_left && (fifo_samples >= runtime->channels)) {
|
||||
samples += runtime->channels;
|
||||
fifo_samples -= runtime->channels;
|
||||
frames_left--;
|
||||
}
|
||||
|
||||
/* not enough samples yet */
|
||||
if (!samples)
|
||||
break;
|
||||
|
||||
/* calculate new buffer index */
|
||||
buf = (u16 *)(runtime->dma_area);
|
||||
buf += strm->buffer_pos * runtime->channels;
|
||||
|
||||
/* Note, only supports 16-bit samples */
|
||||
for (i = 0; i < samples; i++)
|
||||
*buf++ = (u16)(rz_ssi_reg_readl(ssi, SSIFRDR) >> 16);
|
||||
|
||||
rz_ssi_reg_mask_setl(ssi, SSIFSR, SSIFSR_RDF, 0);
|
||||
rz_ssi_pointer_update(strm, samples / runtime->channels);
|
||||
|
||||
/* check if there are no more samples in the RX FIFO */
|
||||
if (!(!frames_left && fifo_samples >= runtime->channels))
|
||||
done = true;
|
||||
}
|
||||
|
||||
/* not enough samples yet */
|
||||
if (samples == 0)
|
||||
return 0;
|
||||
|
||||
/* calculate new buffer index */
|
||||
buf = (u16 *)(runtime->dma_area);
|
||||
buf += strm->buffer_pos * runtime->channels;
|
||||
|
||||
/* Note, only supports 16-bit samples */
|
||||
for (i = 0; i < samples; i++)
|
||||
*buf++ = (u16)(rz_ssi_reg_readl(ssi, SSIFRDR) >> 16);
|
||||
|
||||
rz_ssi_reg_mask_setl(ssi, SSIFSR, SSIFSR_RDF, 0);
|
||||
rz_ssi_pointer_update(strm, samples / runtime->channels);
|
||||
|
||||
/*
|
||||
* If we finished this period, but there are more samples in
|
||||
* the RX FIFO, call this function again
|
||||
*/
|
||||
if (frames_left == 0 && fifo_samples >= runtime->channels)
|
||||
rz_ssi_pio_recv(ssi, strm);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче