Commit 38c042b5 authored by Lad Prabhakar's avatar Lad Prabhakar Committed by Mark Brown

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: default avatarLad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
Reviewed-by: default avatarBiju Das <biju.das.jz@bp.renesas.com>
Link: https://lore.kernel.org/r/20230217185225.43310-3-prabhakar.mahadev-lad.rj@bp.renesas.comSigned-off-by: default avatarMark Brown <broonie@kernel.org>
parent 56a38404
......@@ -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,20 +1005,32 @@ 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;
ssi->irq_rx = platform_get_irq_byname(pdev, "dma_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_tx,
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;
ssi->irq_rx = platform_get_irq_byname(pdev, "dma_rx");
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);
......@@ -1014,6 +1038,7 @@ static int rz_ssi_probe(struct platform_device *pdev)
return dev_err_probe(&pdev->dev, ret,
"irq request error (dma_rx)\n");
}
}
ssi->rstc = devm_reset_control_get_exclusive(&pdev->dev, NULL);
if (IS_ERR(ssi->rstc)) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment