mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-25 16:31:13 +00:00
05ed7dc50d
Patches automatically rebased. Signed-off-by: Rui Salvaterra <rsalvaterra@gmail.com>
188 lines
6.4 KiB
Diff
188 lines
6.4 KiB
Diff
From 36bb4f0ab8e7ef69cc11d4d888aa898223b0e901 Mon Sep 17 00:00:00 2001
|
|
From: Codrin Ciubotariu <codrin.ciubotariu@microchip.com>
|
|
Date: Mon, 1 Mar 2021 19:09:04 +0200
|
|
Subject: [PATCH 153/247] ASoC: mchp-i2s-mcc: Add FIFOs support
|
|
|
|
I2S-MCC found on SAMA7G5 includes 2 FIFOs (capture and playback). When
|
|
FIFOs are enabled, bits I2SMCC_ISRA.TXLRDYx and I2SMCC_ISRA.TXRRDYx must
|
|
not be used. Bits I2SMCC_ISRB.TXFFRDY and I2SMCC_ISRB.RXFFRDY must be used
|
|
instead.
|
|
|
|
Signed-off-by: Codrin Ciubotariu <codrin.ciubotariu@microchip.com>
|
|
Link: https://lore.kernel.org/r/20210301170905.835091-7-codrin.ciubotariu@microchip.com
|
|
Signed-off-by: Mark Brown <broonie@kernel.org>
|
|
---
|
|
sound/soc/atmel/mchp-i2s-mcc.c | 76 +++++++++++++++++++++++++---------
|
|
1 file changed, 56 insertions(+), 20 deletions(-)
|
|
|
|
--- a/sound/soc/atmel/mchp-i2s-mcc.c
|
|
+++ b/sound/soc/atmel/mchp-i2s-mcc.c
|
|
@@ -176,7 +176,7 @@
|
|
*/
|
|
#define MCHP_I2SMCC_MRB_CRAMODE_REGULAR (1 << 0)
|
|
|
|
-#define MCHP_I2SMCC_MRB_FIFOEN BIT(1)
|
|
+#define MCHP_I2SMCC_MRB_FIFOEN BIT(4)
|
|
|
|
#define MCHP_I2SMCC_MRB_DMACHUNK_MASK GENMASK(9, 8)
|
|
#define MCHP_I2SMCC_MRB_DMACHUNK(no_words) \
|
|
@@ -230,6 +230,7 @@ static const struct regmap_config mchp_i
|
|
|
|
struct mchp_i2s_mcc_soc_data {
|
|
unsigned int data_pin_pair_num;
|
|
+ bool has_fifo;
|
|
};
|
|
|
|
struct mchp_i2s_mcc_dev {
|
|
@@ -257,7 +258,7 @@ struct mchp_i2s_mcc_dev {
|
|
static irqreturn_t mchp_i2s_mcc_interrupt(int irq, void *dev_id)
|
|
{
|
|
struct mchp_i2s_mcc_dev *dev = dev_id;
|
|
- u32 sra, imra, srb, imrb, pendinga, pendingb, idra = 0;
|
|
+ u32 sra, imra, srb, imrb, pendinga, pendingb, idra = 0, idrb = 0;
|
|
irqreturn_t ret = IRQ_NONE;
|
|
|
|
regmap_read(dev->regmap, MCHP_I2SMCC_IMRA, &imra);
|
|
@@ -275,24 +276,36 @@ static irqreturn_t mchp_i2s_mcc_interrup
|
|
* Tx/Rx ready interrupts are enabled when stopping only, to assure
|
|
* availability and to disable clocks if necessary
|
|
*/
|
|
- idra |= pendinga & (MCHP_I2SMCC_INT_TXRDY_MASK(dev->channels) |
|
|
- MCHP_I2SMCC_INT_RXRDY_MASK(dev->channels));
|
|
- if (idra)
|
|
+ if (dev->soc->has_fifo) {
|
|
+ idrb |= pendingb & (MCHP_I2SMCC_INT_TXFFRDY |
|
|
+ MCHP_I2SMCC_INT_RXFFRDY);
|
|
+ } else {
|
|
+ idra |= pendinga & (MCHP_I2SMCC_INT_TXRDY_MASK(dev->channels) |
|
|
+ MCHP_I2SMCC_INT_RXRDY_MASK(dev->channels));
|
|
+ }
|
|
+ if (idra || idrb)
|
|
ret = IRQ_HANDLED;
|
|
|
|
- if ((imra & MCHP_I2SMCC_INT_TXRDY_MASK(dev->channels)) &&
|
|
- (imra & MCHP_I2SMCC_INT_TXRDY_MASK(dev->channels)) ==
|
|
- (idra & MCHP_I2SMCC_INT_TXRDY_MASK(dev->channels))) {
|
|
+ if ((!dev->soc->has_fifo &&
|
|
+ (imra & MCHP_I2SMCC_INT_TXRDY_MASK(dev->channels)) &&
|
|
+ (imra & MCHP_I2SMCC_INT_TXRDY_MASK(dev->channels)) ==
|
|
+ (idra & MCHP_I2SMCC_INT_TXRDY_MASK(dev->channels))) ||
|
|
+ (dev->soc->has_fifo && imrb & MCHP_I2SMCC_INT_TXFFRDY)) {
|
|
dev->tx_rdy = 1;
|
|
wake_up_interruptible(&dev->wq_txrdy);
|
|
}
|
|
- if ((imra & MCHP_I2SMCC_INT_RXRDY_MASK(dev->channels)) &&
|
|
- (imra & MCHP_I2SMCC_INT_RXRDY_MASK(dev->channels)) ==
|
|
- (idra & MCHP_I2SMCC_INT_RXRDY_MASK(dev->channels))) {
|
|
+ if ((!dev->soc->has_fifo &&
|
|
+ (imra & MCHP_I2SMCC_INT_RXRDY_MASK(dev->channels)) &&
|
|
+ (imra & MCHP_I2SMCC_INT_RXRDY_MASK(dev->channels)) ==
|
|
+ (idra & MCHP_I2SMCC_INT_RXRDY_MASK(dev->channels))) ||
|
|
+ (dev->soc->has_fifo && imrb & MCHP_I2SMCC_INT_RXFFRDY)) {
|
|
dev->rx_rdy = 1;
|
|
wake_up_interruptible(&dev->wq_rxrdy);
|
|
}
|
|
- regmap_write(dev->regmap, MCHP_I2SMCC_IDRA, idra);
|
|
+ if (dev->soc->has_fifo)
|
|
+ regmap_write(dev->regmap, MCHP_I2SMCC_IDRB, idrb);
|
|
+ else
|
|
+ regmap_write(dev->regmap, MCHP_I2SMCC_IDRA, idra);
|
|
|
|
return ret;
|
|
}
|
|
@@ -664,6 +677,10 @@ static int mchp_i2s_mcc_hw_params(struct
|
|
}
|
|
}
|
|
|
|
+ /* enable FIFO if available */
|
|
+ if (dev->soc->has_fifo)
|
|
+ mrb |= MCHP_I2SMCC_MRB_FIFOEN;
|
|
+
|
|
/*
|
|
* If we are already running, the wanted setup must be
|
|
* the same with the one that's currently ongoing
|
|
@@ -726,8 +743,13 @@ static int mchp_i2s_mcc_hw_free(struct s
|
|
if (err == 0) {
|
|
dev_warn_once(dev->dev,
|
|
"Timeout waiting for Tx ready\n");
|
|
- regmap_write(dev->regmap, MCHP_I2SMCC_IDRA,
|
|
- MCHP_I2SMCC_INT_TXRDY_MASK(dev->channels));
|
|
+ if (dev->soc->has_fifo)
|
|
+ regmap_write(dev->regmap, MCHP_I2SMCC_IDRB,
|
|
+ MCHP_I2SMCC_INT_TXFFRDY);
|
|
+ else
|
|
+ regmap_write(dev->regmap, MCHP_I2SMCC_IDRA,
|
|
+ MCHP_I2SMCC_INT_TXRDY_MASK(dev->channels));
|
|
+
|
|
dev->tx_rdy = 1;
|
|
}
|
|
} else {
|
|
@@ -737,8 +759,12 @@ static int mchp_i2s_mcc_hw_free(struct s
|
|
if (err == 0) {
|
|
dev_warn_once(dev->dev,
|
|
"Timeout waiting for Rx ready\n");
|
|
- regmap_write(dev->regmap, MCHP_I2SMCC_IDRA,
|
|
- MCHP_I2SMCC_INT_RXRDY_MASK(dev->channels));
|
|
+ if (dev->soc->has_fifo)
|
|
+ regmap_write(dev->regmap, MCHP_I2SMCC_IDRB,
|
|
+ MCHP_I2SMCC_INT_RXFFRDY);
|
|
+ else
|
|
+ regmap_write(dev->regmap, MCHP_I2SMCC_IDRA,
|
|
+ MCHP_I2SMCC_INT_RXRDY_MASK(dev->channels));
|
|
dev->rx_rdy = 1;
|
|
}
|
|
}
|
|
@@ -765,7 +791,7 @@ static int mchp_i2s_mcc_trigger(struct s
|
|
struct mchp_i2s_mcc_dev *dev = snd_soc_dai_get_drvdata(dai);
|
|
bool is_playback = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
|
|
u32 cr = 0;
|
|
- u32 iera = 0;
|
|
+ u32 iera = 0, ierb = 0;
|
|
u32 sr;
|
|
int err;
|
|
|
|
@@ -789,7 +815,10 @@ static int mchp_i2s_mcc_trigger(struct s
|
|
* Enable Tx Ready interrupts on all channels
|
|
* to assure all data is sent
|
|
*/
|
|
- iera = MCHP_I2SMCC_INT_TXRDY_MASK(dev->channels);
|
|
+ if (dev->soc->has_fifo)
|
|
+ ierb = MCHP_I2SMCC_INT_TXFFRDY;
|
|
+ else
|
|
+ iera = MCHP_I2SMCC_INT_TXRDY_MASK(dev->channels);
|
|
} else if (!is_playback && (sr & MCHP_I2SMCC_SR_RXEN)) {
|
|
cr = MCHP_I2SMCC_CR_RXDIS;
|
|
dev->rx_rdy = 0;
|
|
@@ -797,7 +826,10 @@ static int mchp_i2s_mcc_trigger(struct s
|
|
* Enable Rx Ready interrupts on all channels
|
|
* to assure all data is received
|
|
*/
|
|
- iera = MCHP_I2SMCC_INT_RXRDY_MASK(dev->channels);
|
|
+ if (dev->soc->has_fifo)
|
|
+ ierb = MCHP_I2SMCC_INT_RXFFRDY;
|
|
+ else
|
|
+ iera = MCHP_I2SMCC_INT_RXRDY_MASK(dev->channels);
|
|
}
|
|
break;
|
|
default:
|
|
@@ -815,7 +847,10 @@ static int mchp_i2s_mcc_trigger(struct s
|
|
}
|
|
}
|
|
|
|
- regmap_write(dev->regmap, MCHP_I2SMCC_IERA, iera);
|
|
+ if (dev->soc->has_fifo)
|
|
+ regmap_write(dev->regmap, MCHP_I2SMCC_IERB, ierb);
|
|
+ else
|
|
+ regmap_write(dev->regmap, MCHP_I2SMCC_IERA, iera);
|
|
regmap_write(dev->regmap, MCHP_I2SMCC_CR, cr);
|
|
|
|
return 0;
|
|
@@ -903,6 +938,7 @@ static struct mchp_i2s_mcc_soc_data mchp
|
|
|
|
static struct mchp_i2s_mcc_soc_data mchp_i2s_mcc_sama7g5 = {
|
|
.data_pin_pair_num = 4,
|
|
+ .has_fifo = true,
|
|
};
|
|
|
|
static const struct of_device_id mchp_i2s_mcc_dt_ids[] = {
|