Message ID | 20230217185225.43310-3-prabhakar.mahadev-lad.rj@bp.renesas.com |
---|---|
State | New |
Headers | show |
Series | RZ/G2L SSI: Update interrupt numbers | expand |
Hi Prabhakar, Thanks for the patch. > Subject: [PATCH 2/4] ASoC: sh: rz-ssi: Update interrupt handling for half > duplex channels > > From: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com> > > 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. Just a thought, As dt-binding doc mentions, a way to distinguish half duplex and full duplex by Counting the number of interrupts. Maybe we could use that property for detecting channel with full/half duplex mode. See below > > Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com> > Reviewed-by: Biju Das <biju.das.jz@bp.renesas.com> > --- > sound/soc/sh/rz-ssi.c | 63 ++++++++++++++++++++++++++++++------------- > 1 file changed, 44 insertions(+), 19 deletions(-) > > diff --git a/sound/soc/sh/rz-ssi.c b/sound/soc/sh/rz-ssi.c index > 5d6bae33ae34..d502aa55c5a8 100644 > --- a/sound/soc/sh/rz-ssi.c > +++ b/sound/soc/sh/rz-ssi.c > @@ -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)) { Here, Detect Half duplex or full duplex by counting number of interrupts. If half duplex get IRQ associated with dma_rt If full duplex get IRQ associated with dma_rx and dma_tx. > /* 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; > - > - 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"); > + 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_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"); Typo dma_rt?? Cheers, Biju > + } 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); > -- > 2.25.1
diff --git a/sound/soc/sh/rz-ssi.c b/sound/soc/sh/rz-ssi.c index 5d6bae33ae34..d502aa55c5a8 100644 --- a/sound/soc/sh/rz-ssi.c +++ b/sound/soc/sh/rz-ssi.c @@ -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; - - 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"); + 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_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);