at91: add kernel support for sama7g5 soc
[openwrt/openwrt.git] / target / linux / at91 / patches-5.10 / 153-ASoC-mchp-i2s-mcc-Add-FIFOs-support.patch
1 From 36bb4f0ab8e7ef69cc11d4d888aa898223b0e901 Mon Sep 17 00:00:00 2001
2 From: Codrin Ciubotariu <codrin.ciubotariu@microchip.com>
3 Date: Mon, 1 Mar 2021 19:09:04 +0200
4 Subject: [PATCH 153/247] ASoC: mchp-i2s-mcc: Add FIFOs support
5
6 I2S-MCC found on SAMA7G5 includes 2 FIFOs (capture and playback). When
7 FIFOs are enabled, bits I2SMCC_ISRA.TXLRDYx and I2SMCC_ISRA.TXRRDYx must
8 not be used. Bits I2SMCC_ISRB.TXFFRDY and I2SMCC_ISRB.RXFFRDY must be used
9 instead.
10
11 Signed-off-by: Codrin Ciubotariu <codrin.ciubotariu@microchip.com>
12 Link: https://lore.kernel.org/r/20210301170905.835091-7-codrin.ciubotariu@microchip.com
13 Signed-off-by: Mark Brown <broonie@kernel.org>
14 ---
15 sound/soc/atmel/mchp-i2s-mcc.c | 76 +++++++++++++++++++++++++---------
16 1 file changed, 56 insertions(+), 20 deletions(-)
17
18 diff --git a/sound/soc/atmel/mchp-i2s-mcc.c b/sound/soc/atmel/mchp-i2s-mcc.c
19 index 0818fa864f0e..188484e84f94 100644
20 --- a/sound/soc/atmel/mchp-i2s-mcc.c
21 +++ b/sound/soc/atmel/mchp-i2s-mcc.c
22 @@ -176,7 +176,7 @@
23 */
24 #define MCHP_I2SMCC_MRB_CRAMODE_REGULAR (1 << 0)
25
26 -#define MCHP_I2SMCC_MRB_FIFOEN BIT(1)
27 +#define MCHP_I2SMCC_MRB_FIFOEN BIT(4)
28
29 #define MCHP_I2SMCC_MRB_DMACHUNK_MASK GENMASK(9, 8)
30 #define MCHP_I2SMCC_MRB_DMACHUNK(no_words) \
31 @@ -230,6 +230,7 @@ static const struct regmap_config mchp_i2s_mcc_regmap_config = {
32
33 struct mchp_i2s_mcc_soc_data {
34 unsigned int data_pin_pair_num;
35 + bool has_fifo;
36 };
37
38 struct mchp_i2s_mcc_dev {
39 @@ -257,7 +258,7 @@ struct mchp_i2s_mcc_dev {
40 static irqreturn_t mchp_i2s_mcc_interrupt(int irq, void *dev_id)
41 {
42 struct mchp_i2s_mcc_dev *dev = dev_id;
43 - u32 sra, imra, srb, imrb, pendinga, pendingb, idra = 0;
44 + u32 sra, imra, srb, imrb, pendinga, pendingb, idra = 0, idrb = 0;
45 irqreturn_t ret = IRQ_NONE;
46
47 regmap_read(dev->regmap, MCHP_I2SMCC_IMRA, &imra);
48 @@ -275,24 +276,36 @@ static irqreturn_t mchp_i2s_mcc_interrupt(int irq, void *dev_id)
49 * Tx/Rx ready interrupts are enabled when stopping only, to assure
50 * availability and to disable clocks if necessary
51 */
52 - idra |= pendinga & (MCHP_I2SMCC_INT_TXRDY_MASK(dev->channels) |
53 - MCHP_I2SMCC_INT_RXRDY_MASK(dev->channels));
54 - if (idra)
55 + if (dev->soc->has_fifo) {
56 + idrb |= pendingb & (MCHP_I2SMCC_INT_TXFFRDY |
57 + MCHP_I2SMCC_INT_RXFFRDY);
58 + } else {
59 + idra |= pendinga & (MCHP_I2SMCC_INT_TXRDY_MASK(dev->channels) |
60 + MCHP_I2SMCC_INT_RXRDY_MASK(dev->channels));
61 + }
62 + if (idra || idrb)
63 ret = IRQ_HANDLED;
64
65 - if ((imra & MCHP_I2SMCC_INT_TXRDY_MASK(dev->channels)) &&
66 - (imra & MCHP_I2SMCC_INT_TXRDY_MASK(dev->channels)) ==
67 - (idra & MCHP_I2SMCC_INT_TXRDY_MASK(dev->channels))) {
68 + if ((!dev->soc->has_fifo &&
69 + (imra & MCHP_I2SMCC_INT_TXRDY_MASK(dev->channels)) &&
70 + (imra & MCHP_I2SMCC_INT_TXRDY_MASK(dev->channels)) ==
71 + (idra & MCHP_I2SMCC_INT_TXRDY_MASK(dev->channels))) ||
72 + (dev->soc->has_fifo && imrb & MCHP_I2SMCC_INT_TXFFRDY)) {
73 dev->tx_rdy = 1;
74 wake_up_interruptible(&dev->wq_txrdy);
75 }
76 - if ((imra & MCHP_I2SMCC_INT_RXRDY_MASK(dev->channels)) &&
77 - (imra & MCHP_I2SMCC_INT_RXRDY_MASK(dev->channels)) ==
78 - (idra & MCHP_I2SMCC_INT_RXRDY_MASK(dev->channels))) {
79 + if ((!dev->soc->has_fifo &&
80 + (imra & MCHP_I2SMCC_INT_RXRDY_MASK(dev->channels)) &&
81 + (imra & MCHP_I2SMCC_INT_RXRDY_MASK(dev->channels)) ==
82 + (idra & MCHP_I2SMCC_INT_RXRDY_MASK(dev->channels))) ||
83 + (dev->soc->has_fifo && imrb & MCHP_I2SMCC_INT_RXFFRDY)) {
84 dev->rx_rdy = 1;
85 wake_up_interruptible(&dev->wq_rxrdy);
86 }
87 - regmap_write(dev->regmap, MCHP_I2SMCC_IDRA, idra);
88 + if (dev->soc->has_fifo)
89 + regmap_write(dev->regmap, MCHP_I2SMCC_IDRB, idrb);
90 + else
91 + regmap_write(dev->regmap, MCHP_I2SMCC_IDRA, idra);
92
93 return ret;
94 }
95 @@ -664,6 +677,10 @@ static int mchp_i2s_mcc_hw_params(struct snd_pcm_substream *substream,
96 }
97 }
98
99 + /* enable FIFO if available */
100 + if (dev->soc->has_fifo)
101 + mrb |= MCHP_I2SMCC_MRB_FIFOEN;
102 +
103 /*
104 * If we are already running, the wanted setup must be
105 * the same with the one that's currently ongoing
106 @@ -726,8 +743,13 @@ static int mchp_i2s_mcc_hw_free(struct snd_pcm_substream *substream,
107 if (err == 0) {
108 dev_warn_once(dev->dev,
109 "Timeout waiting for Tx ready\n");
110 - regmap_write(dev->regmap, MCHP_I2SMCC_IDRA,
111 - MCHP_I2SMCC_INT_TXRDY_MASK(dev->channels));
112 + if (dev->soc->has_fifo)
113 + regmap_write(dev->regmap, MCHP_I2SMCC_IDRB,
114 + MCHP_I2SMCC_INT_TXFFRDY);
115 + else
116 + regmap_write(dev->regmap, MCHP_I2SMCC_IDRA,
117 + MCHP_I2SMCC_INT_TXRDY_MASK(dev->channels));
118 +
119 dev->tx_rdy = 1;
120 }
121 } else {
122 @@ -737,8 +759,12 @@ static int mchp_i2s_mcc_hw_free(struct snd_pcm_substream *substream,
123 if (err == 0) {
124 dev_warn_once(dev->dev,
125 "Timeout waiting for Rx ready\n");
126 - regmap_write(dev->regmap, MCHP_I2SMCC_IDRA,
127 - MCHP_I2SMCC_INT_RXRDY_MASK(dev->channels));
128 + if (dev->soc->has_fifo)
129 + regmap_write(dev->regmap, MCHP_I2SMCC_IDRB,
130 + MCHP_I2SMCC_INT_RXFFRDY);
131 + else
132 + regmap_write(dev->regmap, MCHP_I2SMCC_IDRA,
133 + MCHP_I2SMCC_INT_RXRDY_MASK(dev->channels));
134 dev->rx_rdy = 1;
135 }
136 }
137 @@ -765,7 +791,7 @@ static int mchp_i2s_mcc_trigger(struct snd_pcm_substream *substream, int cmd,
138 struct mchp_i2s_mcc_dev *dev = snd_soc_dai_get_drvdata(dai);
139 bool is_playback = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
140 u32 cr = 0;
141 - u32 iera = 0;
142 + u32 iera = 0, ierb = 0;
143 u32 sr;
144 int err;
145
146 @@ -789,7 +815,10 @@ static int mchp_i2s_mcc_trigger(struct snd_pcm_substream *substream, int cmd,
147 * Enable Tx Ready interrupts on all channels
148 * to assure all data is sent
149 */
150 - iera = MCHP_I2SMCC_INT_TXRDY_MASK(dev->channels);
151 + if (dev->soc->has_fifo)
152 + ierb = MCHP_I2SMCC_INT_TXFFRDY;
153 + else
154 + iera = MCHP_I2SMCC_INT_TXRDY_MASK(dev->channels);
155 } else if (!is_playback && (sr & MCHP_I2SMCC_SR_RXEN)) {
156 cr = MCHP_I2SMCC_CR_RXDIS;
157 dev->rx_rdy = 0;
158 @@ -797,7 +826,10 @@ static int mchp_i2s_mcc_trigger(struct snd_pcm_substream *substream, int cmd,
159 * Enable Rx Ready interrupts on all channels
160 * to assure all data is received
161 */
162 - iera = MCHP_I2SMCC_INT_RXRDY_MASK(dev->channels);
163 + if (dev->soc->has_fifo)
164 + ierb = MCHP_I2SMCC_INT_RXFFRDY;
165 + else
166 + iera = MCHP_I2SMCC_INT_RXRDY_MASK(dev->channels);
167 }
168 break;
169 default:
170 @@ -815,7 +847,10 @@ static int mchp_i2s_mcc_trigger(struct snd_pcm_substream *substream, int cmd,
171 }
172 }
173
174 - regmap_write(dev->regmap, MCHP_I2SMCC_IERA, iera);
175 + if (dev->soc->has_fifo)
176 + regmap_write(dev->regmap, MCHP_I2SMCC_IERB, ierb);
177 + else
178 + regmap_write(dev->regmap, MCHP_I2SMCC_IERA, iera);
179 regmap_write(dev->regmap, MCHP_I2SMCC_CR, cr);
180
181 return 0;
182 @@ -903,6 +938,7 @@ static struct mchp_i2s_mcc_soc_data mchp_i2s_mcc_sam9x60 = {
183
184 static struct mchp_i2s_mcc_soc_data mchp_i2s_mcc_sama7g5 = {
185 .data_pin_pair_num = 4,
186 + .has_fifo = true,
187 };
188
189 static const struct of_device_id mchp_i2s_mcc_dt_ids[] = {
190 --
191 2.32.0
192