1

ASoC: sh: rz-ssi: Update interrupt handling for half duplex channels

For half duplex channels we dont have separate interrupts for Tx and Rx
instead we have single interrupt Rt (where the signal for Rx and Tx is
muxed). To handle such a case install a handler in case we have a dma_rt
interrupt specified in the DT for the PIO mode.

Note, for backward compatibility we check if the Rx and Tx interrupts
are present first instead of checking Rt interrupt.

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/20230217185225.43310-3-prabhakar.mahadev-lad.rj@bp.renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
Lad Prabhakar 2023-02-17 18:52:23 +00:00 committed by Mark Brown
parent 56a3840486
commit 38c042b59a
No known key found for this signature in database
GPG Key ID: 24D68B725D5487D0

View File

@ -109,6 +109,7 @@ struct rz_ssi_priv {
int irq_int;
int irq_tx;
int irq_rx;
int irq_rt;
spinlock_t lock;
@ -565,6 +566,17 @@ static irqreturn_t rz_ssi_interrupt(int irq, void *data)
rz_ssi_reg_mask_setl(ssi, SSIFSR, SSIFSR_RDF, 0);
}
if (irq == ssi->irq_rt) {
struct snd_pcm_substream *substream = strm->substream;
if (rz_ssi_stream_is_play(ssi, substream)) {
strm->transfer(ssi, &ssi->playback);
} else {
strm->transfer(ssi, &ssi->capture);
rz_ssi_reg_mask_setl(ssi, SSIFSR, SSIFSR_RDF, 0);
}
}
return IRQ_HANDLED;
}
@ -993,26 +1005,39 @@ static int rz_ssi_probe(struct platform_device *pdev)
if (!rz_ssi_is_dma_enabled(ssi)) {
/* Tx and Rx interrupts (pio only) */
ssi->irq_tx = platform_get_irq_byname(pdev, "dma_tx");
if (ssi->irq_tx < 0)
return ssi->irq_tx;
ret = devm_request_irq(&pdev->dev, ssi->irq_tx,
&rz_ssi_interrupt, 0,
dev_name(&pdev->dev), ssi);
if (ret < 0)
return dev_err_probe(&pdev->dev, ret,
"irq request error (dma_tx)\n");
ssi->irq_rx = platform_get_irq_byname(pdev, "dma_rx");
if (ssi->irq_rx < 0)
return ssi->irq_rx;
if (ssi->irq_tx == -ENXIO && ssi->irq_rx == -ENXIO) {
ssi->irq_rt = platform_get_irq_byname(pdev, "dma_rt");
if (ssi->irq_rt < 0)
return ssi->irq_rt;
ret = devm_request_irq(&pdev->dev, ssi->irq_rx,
&rz_ssi_interrupt, 0,
dev_name(&pdev->dev), ssi);
if (ret < 0)
return dev_err_probe(&pdev->dev, ret,
"irq request error (dma_rx)\n");
ret = devm_request_irq(&pdev->dev, ssi->irq_rt,
&rz_ssi_interrupt, 0,
dev_name(&pdev->dev), ssi);
if (ret < 0)
return dev_err_probe(&pdev->dev, ret,
"irq request error (dma_tx)\n");
} else {
if (ssi->irq_tx < 0)
return ssi->irq_tx;
if (ssi->irq_rx < 0)
return ssi->irq_rx;
ret = devm_request_irq(&pdev->dev, ssi->irq_tx,
&rz_ssi_interrupt, 0,
dev_name(&pdev->dev), ssi);
if (ret < 0)
return dev_err_probe(&pdev->dev, ret,
"irq request error (dma_tx)\n");
ret = devm_request_irq(&pdev->dev, ssi->irq_rx,
&rz_ssi_interrupt, 0,
dev_name(&pdev->dev), ssi);
if (ret < 0)
return dev_err_probe(&pdev->dev, ret,
"irq request error (dma_rx)\n");
}
}
ssi->rstc = devm_reset_control_get_exclusive(&pdev->dev, NULL);