aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/at91/patches-5.10/153-ASoC-mchp-i2s-mcc-Add-FIFOs-support.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/at91/patches-5.10/153-ASoC-mchp-i2s-mcc-Add-FIFOs-support.patch')
-rw-r--r--target/linux/at91/patches-5.10/153-ASoC-mchp-i2s-mcc-Add-FIFOs-support.patch192
1 files changed, 192 insertions, 0 deletions
diff --git a/target/linux/at91/patches-5.10/153-ASoC-mchp-i2s-mcc-Add-FIFOs-support.patch b/target/linux/at91/patches-5.10/153-ASoC-mchp-i2s-mcc-Add-FIFOs-support.patch
new file mode 100644
index 0000000000..cf2063b884
--- /dev/null
+++ b/target/linux/at91/patches-5.10/153-ASoC-mchp-i2s-mcc-Add-FIFOs-support.patch
@@ -0,0 +1,192 @@
+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(-)
+
+diff --git a/sound/soc/atmel/mchp-i2s-mcc.c b/sound/soc/atmel/mchp-i2s-mcc.c
+index 0818fa864f0e..188484e84f94 100644
+--- 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_i2s_mcc_regmap_config = {
+
+ 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_interrupt(int irq, void *dev_id)
+ * 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 snd_pcm_substream *substream,
+ }
+ }
+
++ /* 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 snd_pcm_substream *substream,
+ 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 snd_pcm_substream *substream,
+ 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 snd_pcm_substream *substream, int cmd,
+ 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 snd_pcm_substream *substream, int cmd,
+ * 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 snd_pcm_substream *substream, int cmd,
+ * 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 snd_pcm_substream *substream, int cmd,
+ }
+ }
+
+- 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_i2s_mcc_sam9x60 = {
+
+ 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[] = {
+--
+2.32.0
+