1 From 21cf15cd000ba45bc02b8bfcf59df1e13bfdb803 Mon Sep 17 00:00:00 2001
2 From: Shengjiu Wang <shengjiu.wang@freescale.com>
3 Date: Thu, 22 Jun 2017 15:39:24 +0800
4 Subject: [PATCH] MLK-15140-1: ASoC: fsl_sai: support latest sai module
6 The version of sai is upgrate in imx8mq, which add two register
7 in beginning, there is VERID and PARAM. the driver need to be
10 Signed-off-by: Mihai Serban <mihai.serban@nxp.com>
11 Signed-off-by: Shengjiu Wang <shengjiu.wang@freescale.com>
13 sound/soc/fsl/fsl_sai.c | 273 ++++++++++++++++++++++++++++--------------------
14 sound/soc/fsl/fsl_sai.h | 43 ++++----
15 2 files changed, 180 insertions(+), 136 deletions(-)
17 --- a/sound/soc/fsl/fsl_sai.c
18 +++ b/sound/soc/fsl/fsl_sai.c
19 @@ -43,6 +43,7 @@ static struct fsl_sai_soc_data fsl_sai_i
26 static struct fsl_sai_soc_data fsl_sai_imx6ul = {
27 @@ -51,6 +52,7 @@ static struct fsl_sai_soc_data fsl_sai_i
34 static struct fsl_sai_soc_data fsl_sai_imx7ulp = {
35 @@ -59,6 +61,16 @@ static struct fsl_sai_soc_data fsl_sai_i
38 .flags = SAI_FLAG_PMQOS,
42 +static struct fsl_sai_soc_data fsl_sai_imx8mq = {
51 static const unsigned int fsl_sai_rates[] = {
52 @@ -75,6 +87,7 @@ static const struct snd_pcm_hw_constrain
53 static irqreturn_t fsl_sai_isr(int irq, void *devid)
55 struct fsl_sai *sai = (struct fsl_sai *)devid;
56 + unsigned char offset = sai->soc->reg_offset;
57 struct device *dev = &sai->pdev->dev;
58 u32 flags, xcsr, mask;
60 @@ -87,7 +100,7 @@ static irqreturn_t fsl_sai_isr(int irq,
61 mask = (FSL_SAI_FLAGS >> FSL_SAI_CSR_xIE_SHIFT) << FSL_SAI_CSR_xF_SHIFT;
64 - regmap_read(sai->regmap, FSL_SAI_TCSR, &xcsr);
65 + regmap_read(sai->regmap, FSL_SAI_TCSR(offset), &xcsr);
69 @@ -117,11 +130,11 @@ static irqreturn_t fsl_sai_isr(int irq,
70 xcsr &= ~FSL_SAI_CSR_xF_MASK;
73 - regmap_write(sai->regmap, FSL_SAI_TCSR, flags | xcsr);
74 + regmap_write(sai->regmap, FSL_SAI_TCSR(offset), flags | xcsr);
78 - regmap_read(sai->regmap, FSL_SAI_RCSR, &xcsr);
79 + regmap_read(sai->regmap, FSL_SAI_RCSR(offset), &xcsr);
83 @@ -151,7 +164,7 @@ irq_rx:
84 xcsr &= ~FSL_SAI_CSR_xF_MASK;
87 - regmap_write(sai->regmap, FSL_SAI_RCSR, flags | xcsr);
88 + regmap_write(sai->regmap, FSL_SAI_RCSR(offset), flags | xcsr);
92 @@ -175,6 +188,7 @@ static int fsl_sai_set_dai_sysclk_tr(str
93 int clk_id, unsigned int freq, int fsl_dir)
95 struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);
96 + unsigned char offset = sai->soc->reg_offset;
97 bool tx = fsl_dir == FSL_FMT_TRANSMITTER;
100 @@ -195,7 +209,7 @@ static int fsl_sai_set_dai_sysclk_tr(str
104 - regmap_update_bits(sai->regmap, FSL_SAI_xCR2(tx),
105 + regmap_update_bits(sai->regmap, FSL_SAI_xCR2(tx, offset),
106 FSL_SAI_CR2_MSEL_MASK, val_cr2);
109 @@ -228,6 +242,7 @@ static int fsl_sai_set_dai_fmt_tr(struct
110 unsigned int fmt, int fsl_dir)
112 struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);
113 + unsigned char offset = sai->soc->reg_offset;
114 bool tx = fsl_dir == FSL_FMT_TRANSMITTER;
115 u32 val_cr2 = 0, val_cr4 = 0;
117 @@ -324,9 +339,9 @@ static int fsl_sai_set_dai_fmt_tr(struct
121 - regmap_update_bits(sai->regmap, FSL_SAI_xCR2(tx),
122 + regmap_update_bits(sai->regmap, FSL_SAI_xCR2(tx, offset),
123 FSL_SAI_CR2_BCP | FSL_SAI_CR2_BCD_MSTR, val_cr2);
124 - regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx),
125 + regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx, offset),
126 FSL_SAI_CR4_MF | FSL_SAI_CR4_FSE |
127 FSL_SAI_CR4_FSP | FSL_SAI_CR4_FSD_MSTR, val_cr4);
129 @@ -362,6 +377,7 @@ static int fsl_sai_set_dai_fmt(struct sn
130 static int fsl_sai_set_bclk(struct snd_soc_dai *dai, bool tx, u32 freq)
132 struct fsl_sai *sai = snd_soc_dai_get_drvdata(dai);
133 + unsigned char offset = sai->soc->reg_offset;
134 unsigned long clk_rate;
135 u32 savediv = 0, ratio, savesub = freq;
137 @@ -424,17 +440,17 @@ static int fsl_sai_set_bclk(struct snd_s
139 if ((sai->synchronous[TX] && !sai->synchronous[RX]) ||
140 (!tx && !sai->synchronous[RX])) {
141 - regmap_update_bits(sai->regmap, FSL_SAI_RCR2,
142 + regmap_update_bits(sai->regmap, FSL_SAI_RCR2(offset),
143 FSL_SAI_CR2_MSEL_MASK,
144 FSL_SAI_CR2_MSEL(sai->mclk_id[tx]));
145 - regmap_update_bits(sai->regmap, FSL_SAI_RCR2,
146 + regmap_update_bits(sai->regmap, FSL_SAI_RCR2(offset),
147 FSL_SAI_CR2_DIV_MASK, savediv - 1);
148 } else if ((sai->synchronous[RX] && !sai->synchronous[TX]) ||
149 (tx && !sai->synchronous[TX])) {
150 - regmap_update_bits(sai->regmap, FSL_SAI_TCR2,
151 + regmap_update_bits(sai->regmap, FSL_SAI_TCR2(offset),
152 FSL_SAI_CR2_MSEL_MASK,
153 FSL_SAI_CR2_MSEL(sai->mclk_id[tx]));
154 - regmap_update_bits(sai->regmap, FSL_SAI_TCR2,
155 + regmap_update_bits(sai->regmap, FSL_SAI_TCR2(offset),
156 FSL_SAI_CR2_DIV_MASK, savediv - 1);
159 @@ -449,6 +465,7 @@ static int fsl_sai_hw_params(struct snd_
160 struct snd_soc_dai *cpu_dai)
162 struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);
163 + unsigned char offset = sai->soc->reg_offset;
164 bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
165 unsigned int channels = params_channels(params);
166 u32 word_width = params_width(params);
167 @@ -501,49 +518,35 @@ static int fsl_sai_hw_params(struct snd_
169 if (!sai->slave_mode[tx]) {
170 if (!sai->synchronous[TX] && sai->synchronous[RX] && !tx) {
171 - regmap_update_bits(sai->regmap, FSL_SAI_TCR4,
172 + regmap_update_bits(sai->regmap, FSL_SAI_TCR4(offset),
173 FSL_SAI_CR4_SYWD_MASK | FSL_SAI_CR4_FRSZ_MASK,
175 - regmap_update_bits(sai->regmap, FSL_SAI_TCR5,
176 + regmap_update_bits(sai->regmap, FSL_SAI_TCR5(offset),
177 FSL_SAI_CR5_WNW_MASK | FSL_SAI_CR5_W0W_MASK |
178 FSL_SAI_CR5_FBT_MASK, val_cr5);
179 } else if (!sai->synchronous[RX] && sai->synchronous[TX] && tx) {
180 - regmap_update_bits(sai->regmap, FSL_SAI_RCR4,
181 + regmap_update_bits(sai->regmap, FSL_SAI_RCR4(offset),
182 FSL_SAI_CR4_SYWD_MASK | FSL_SAI_CR4_FRSZ_MASK,
184 - regmap_update_bits(sai->regmap, FSL_SAI_RCR5,
185 + regmap_update_bits(sai->regmap, FSL_SAI_RCR5(offset),
186 FSL_SAI_CR5_WNW_MASK | FSL_SAI_CR5_W0W_MASK |
187 FSL_SAI_CR5_FBT_MASK, val_cr5);
191 if (sai->soc->dataline != 0x1) {
192 - switch (sai->dataline[tx]) {
196 - regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx),
197 - FSL_SAI_CR4_FCOMB_SOFT | FSL_SAI_CR4_FCOMB_SHIFT, 0);
200 - regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx),
201 - FSL_SAI_CR4_FCOMB_SOFT | FSL_SAI_CR4_FCOMB_SHIFT,
202 - FSL_SAI_CR4_FCOMB_SOFT | FSL_SAI_CR4_FCOMB_SHIFT);
205 - regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx),
206 - FSL_SAI_CR4_FCOMB_SOFT | FSL_SAI_CR4_FCOMB_SHIFT,
207 - FSL_SAI_CR4_FCOMB_SOFT);
212 + if (sai->dataline[tx] <= 1)
213 + regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx, offset),
214 + FSL_SAI_CR4_FCOMB_MASK, 0);
216 + regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx, offset),
217 + FSL_SAI_CR4_FCOMB_MASK, FSL_SAI_CR4_FCOMB_SOFT);
220 - regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx),
221 + regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx, offset),
222 FSL_SAI_CR4_SYWD_MASK | FSL_SAI_CR4_FRSZ_MASK,
224 - regmap_update_bits(sai->regmap, FSL_SAI_xCR5(tx),
225 + regmap_update_bits(sai->regmap, FSL_SAI_xCR5(tx, offset),
226 FSL_SAI_CR5_WNW_MASK | FSL_SAI_CR5_W0W_MASK |
227 FSL_SAI_CR5_FBT_MASK, val_cr5);
228 regmap_write(sai->regmap, FSL_SAI_xMR(tx), ~0UL - ((1 << channels) - 1));
229 @@ -571,6 +574,7 @@ static int fsl_sai_trigger(struct snd_pc
230 struct snd_soc_dai *cpu_dai)
232 struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);
233 + unsigned char offset = sai->soc->reg_offset;
234 bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
235 u8 channels = substream->runtime->channels;
236 u32 xcsr, count = 100;
237 @@ -581,9 +585,9 @@ static int fsl_sai_trigger(struct snd_pc
238 * Rx sync with Tx clocks: Clear SYNC for Tx, set it for Rx.
239 * Tx sync with Rx clocks: Clear SYNC for Rx, set it for Tx.
241 - regmap_update_bits(sai->regmap, FSL_SAI_TCR2, FSL_SAI_CR2_SYNC,
242 + regmap_update_bits(sai->regmap, FSL_SAI_TCR2(offset), FSL_SAI_CR2_SYNC,
243 sai->synchronous[TX] ? FSL_SAI_CR2_SYNC : 0);
244 - regmap_update_bits(sai->regmap, FSL_SAI_RCR2, FSL_SAI_CR2_SYNC,
245 + regmap_update_bits(sai->regmap, FSL_SAI_RCR2(offset), FSL_SAI_CR2_SYNC,
246 sai->synchronous[RX] ? FSL_SAI_CR2_SYNC : 0);
249 @@ -599,49 +603,50 @@ static int fsl_sai_trigger(struct snd_pc
253 - regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx),
254 + regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx, offset),
255 FSL_SAI_CSR_FRDE, FSL_SAI_CSR_FRDE);
256 - regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx),
258 + regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx, offset),
259 FSL_SAI_CSR_TERE, FSL_SAI_CSR_TERE);
260 - regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx),
261 + regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx, offset),
262 FSL_SAI_CSR_SE, FSL_SAI_CSR_SE);
263 if (!sai->synchronous[TX] && sai->synchronous[RX] && !tx) {
264 - regmap_update_bits(sai->regmap, FSL_SAI_xCSR((!tx)),
265 + regmap_update_bits(sai->regmap, FSL_SAI_xCSR((!tx), offset),
266 FSL_SAI_CSR_TERE, FSL_SAI_CSR_TERE);
267 } else if (!sai->synchronous[RX] && sai->synchronous[TX] && tx) {
268 - regmap_update_bits(sai->regmap, FSL_SAI_xCSR((!tx)),
269 + regmap_update_bits(sai->regmap, FSL_SAI_xCSR((!tx), offset),
270 FSL_SAI_CSR_TERE, FSL_SAI_CSR_TERE);
273 - regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx),
274 + regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx, offset),
275 FSL_SAI_CSR_xIE_MASK, FSL_SAI_FLAGS);
277 case SNDRV_PCM_TRIGGER_STOP:
278 case SNDRV_PCM_TRIGGER_SUSPEND:
279 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
280 - regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx),
281 + regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx, offset),
282 FSL_SAI_CSR_FRDE, 0);
283 - regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx),
284 + regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx, offset),
285 FSL_SAI_CSR_xIE_MASK, 0);
287 /* Check if the opposite FRDE is also disabled */
288 - regmap_read(sai->regmap, FSL_SAI_xCSR(!tx), &xcsr);
289 + regmap_read(sai->regmap, FSL_SAI_xCSR(!tx, offset), &xcsr);
290 if (!(xcsr & FSL_SAI_CSR_FRDE)) {
291 /* Disable both directions and reset their FIFOs */
292 - regmap_update_bits(sai->regmap, FSL_SAI_TCSR,
293 + regmap_update_bits(sai->regmap, FSL_SAI_TCSR(offset),
294 FSL_SAI_CSR_TERE, 0);
295 - regmap_update_bits(sai->regmap, FSL_SAI_RCSR,
296 + regmap_update_bits(sai->regmap, FSL_SAI_RCSR(offset),
297 FSL_SAI_CSR_TERE, 0);
299 /* TERE will remain set till the end of current frame */
302 - regmap_read(sai->regmap, FSL_SAI_xCSR(tx), &xcsr);
303 + regmap_read(sai->regmap, FSL_SAI_xCSR(tx, offset), &xcsr);
304 } while (--count && xcsr & FSL_SAI_CSR_TERE);
306 - regmap_update_bits(sai->regmap, FSL_SAI_TCSR,
307 + regmap_update_bits(sai->regmap, FSL_SAI_TCSR(offset),
308 FSL_SAI_CSR_FR, FSL_SAI_CSR_FR);
309 - regmap_update_bits(sai->regmap, FSL_SAI_RCSR,
310 + regmap_update_bits(sai->regmap, FSL_SAI_RCSR(offset),
311 FSL_SAI_CSR_FR, FSL_SAI_CSR_FR);
314 @@ -654,12 +659,12 @@ static int fsl_sai_trigger(struct snd_pc
315 if (!sai->slave_mode[tx]) {
316 /* Software Reset for both Tx and Rx */
317 regmap_write(sai->regmap,
318 - FSL_SAI_TCSR, FSL_SAI_CSR_SR);
319 + FSL_SAI_TCSR(offset), FSL_SAI_CSR_SR);
320 regmap_write(sai->regmap,
321 - FSL_SAI_RCSR, FSL_SAI_CSR_SR);
322 + FSL_SAI_RCSR(offset), FSL_SAI_CSR_SR);
323 /* Clear SR bit to finish the reset */
324 - regmap_write(sai->regmap, FSL_SAI_TCSR, 0);
325 - regmap_write(sai->regmap, FSL_SAI_RCSR, 0);
326 + regmap_write(sai->regmap, FSL_SAI_TCSR(offset), 0);
327 + regmap_write(sai->regmap, FSL_SAI_RCSR(offset), 0);
331 @@ -674,6 +679,7 @@ static int fsl_sai_startup(struct snd_pc
332 struct snd_soc_dai *cpu_dai)
334 struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);
335 + unsigned char offset = sai->soc->reg_offset;
336 bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
339 @@ -682,7 +688,8 @@ static int fsl_sai_startup(struct snd_pc
341 sai->is_stream_opened[tx] = true;
343 - regmap_update_bits(sai->regmap, FSL_SAI_xCR3(tx), FSL_SAI_CR3_TRCE0|FSL_SAI_CR3_TRCE1,
344 + regmap_update_bits(sai->regmap, FSL_SAI_xCR3(tx, offset),
345 + FSL_SAI_CR3_TRCE_MASK,
346 FSL_SAI_CR3_TRCE(sai->dataline[tx]));
348 ret = snd_pcm_hw_constraint_list(substream->runtime, 0,
349 @@ -695,12 +702,14 @@ static void fsl_sai_shutdown(struct snd_
350 struct snd_soc_dai *cpu_dai)
352 struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);
353 + unsigned char offset = sai->soc->reg_offset;
354 bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
356 regmap_update_bits(sai->regmap, FSL_SAI_xCR3(tx), FSL_SAI_CR3_TRCE, 0);
358 if (sai->is_stream_opened[tx]) {
359 - regmap_update_bits(sai->regmap, FSL_SAI_xCR3(tx), FSL_SAI_CR3_TRCE0 | FSL_SAI_CR3_TRCE1, 0);
360 + regmap_update_bits(sai->regmap, FSL_SAI_xCR3(tx, offset),
361 + FSL_SAI_CR3_TRCE_MASK, 0);
362 sai->is_stream_opened[tx] = false;
365 @@ -719,17 +728,18 @@ static const struct snd_soc_dai_ops fsl_
366 static int fsl_sai_dai_probe(struct snd_soc_dai *cpu_dai)
368 struct fsl_sai *sai = dev_get_drvdata(cpu_dai->dev);
369 + unsigned char offset = sai->soc->reg_offset;
371 /* Software Reset for both Tx and Rx */
372 - regmap_write(sai->regmap, FSL_SAI_TCSR, FSL_SAI_CSR_SR);
373 - regmap_write(sai->regmap, FSL_SAI_RCSR, FSL_SAI_CSR_SR);
374 + regmap_write(sai->regmap, FSL_SAI_TCSR(offset), FSL_SAI_CSR_SR);
375 + regmap_write(sai->regmap, FSL_SAI_RCSR(offset), FSL_SAI_CSR_SR);
376 /* Clear SR bit to finish the reset */
377 - regmap_write(sai->regmap, FSL_SAI_TCSR, 0);
378 - regmap_write(sai->regmap, FSL_SAI_RCSR, 0);
379 + regmap_write(sai->regmap, FSL_SAI_TCSR(offset), 0);
380 + regmap_write(sai->regmap, FSL_SAI_RCSR(offset), 0);
382 - regmap_update_bits(sai->regmap, FSL_SAI_TCR1, FSL_SAI_CR1_RFW_MASK,
383 + regmap_update_bits(sai->regmap, FSL_SAI_TCR1(offset), FSL_SAI_CR1_RFW_MASK,
384 sai->soc->fifo_depth - FSL_SAI_MAXBURST_TX);
385 - regmap_update_bits(sai->regmap, FSL_SAI_RCR1, FSL_SAI_CR1_RFW_MASK,
386 + regmap_update_bits(sai->regmap, FSL_SAI_RCR1(offset), FSL_SAI_CR1_RFW_MASK,
387 FSL_SAI_MAXBURST_RX - 1);
389 snd_soc_dai_init_dma_data(cpu_dai, &sai->dma_params_tx,
390 @@ -767,41 +777,55 @@ static const struct snd_soc_component_dr
394 -static struct reg_default fsl_sai_reg_defaults[] = {
400 +static struct reg_default fsl_sai_v2_reg_defaults[] = {
401 + {FSL_SAI_TCR1(0), 0},
402 + {FSL_SAI_TCR2(0), 0},
403 + {FSL_SAI_TCR3(0), 0},
404 + {FSL_SAI_TCR4(0), 0},
405 + {FSL_SAI_TCR5(0), 0},
409 + {FSL_SAI_RCR1(0), 0},
410 + {FSL_SAI_RCR2(0), 0},
411 + {FSL_SAI_RCR3(0), 0},
412 + {FSL_SAI_RCR4(0), 0},
413 + {FSL_SAI_RCR5(0), 0},
417 +static struct reg_default fsl_sai_v3_reg_defaults[] = {
418 + {FSL_SAI_TCR1(8), 0},
419 + {FSL_SAI_TCR2(8), 0},
420 + {FSL_SAI_TCR3(8), 0},
421 + {FSL_SAI_TCR4(8), 0},
422 + {FSL_SAI_TCR5(8), 0},
431 + {FSL_SAI_RCR1(8), 0},
432 + {FSL_SAI_RCR2(8), 0},
433 + {FSL_SAI_RCR3(8), 0},
434 + {FSL_SAI_RCR4(8), 0},
435 + {FSL_SAI_RCR5(8), 0},
439 static bool fsl_sai_readable_reg(struct device *dev, unsigned int reg)
441 + struct fsl_sai *sai = dev_get_drvdata(dev);
442 + unsigned char offset = sai->soc->reg_offset;
444 + if (reg >= FSL_SAI_TCSR(offset) && reg <= FSL_SAI_TCR5(offset))
447 + if (reg >= FSL_SAI_RCSR(offset) && reg <= FSL_SAI_RCR5(offset))
469 @@ -815,9 +839,13 @@ static bool fsl_sai_readable_reg(struct
471 static bool fsl_sai_volatile_reg(struct device *dev, unsigned int reg)
473 + struct fsl_sai *sai = dev_get_drvdata(dev);
474 + unsigned char offset = sai->soc->reg_offset;
476 + if (reg == FSL_SAI_TCSR(offset) || reg == FSL_SAI_RCSR(offset))
485 @@ -832,22 +860,19 @@ static bool fsl_sai_volatile_reg(struct
487 static bool fsl_sai_writeable_reg(struct device *dev, unsigned int reg)
489 + struct fsl_sai *sai = dev_get_drvdata(dev);
490 + unsigned char offset = sai->soc->reg_offset;
492 + if (reg >= FSL_SAI_TCSR(offset) && reg <= FSL_SAI_TCR5(offset))
495 + if (reg >= FSL_SAI_RCSR(offset) && reg <= FSL_SAI_RCR5(offset))
517 @@ -855,14 +880,28 @@ static bool fsl_sai_writeable_reg(struct
521 -static const struct regmap_config fsl_sai_regmap_config = {
522 +static const struct regmap_config fsl_sai_v2_regmap_config = {
527 .max_register = FSL_SAI_RMR,
528 - .reg_defaults = fsl_sai_reg_defaults,
529 - .num_reg_defaults = ARRAY_SIZE(fsl_sai_reg_defaults),
530 + .reg_defaults = fsl_sai_v2_reg_defaults,
531 + .num_reg_defaults = ARRAY_SIZE(fsl_sai_v2_reg_defaults),
532 + .readable_reg = fsl_sai_readable_reg,
533 + .volatile_reg = fsl_sai_volatile_reg,
534 + .writeable_reg = fsl_sai_writeable_reg,
535 + .cache_type = REGCACHE_FLAT,
538 +static const struct regmap_config fsl_sai_v3_regmap_config = {
543 + .max_register = FSL_SAI_RMR,
544 + .reg_defaults = fsl_sai_v3_reg_defaults,
545 + .num_reg_defaults = ARRAY_SIZE(fsl_sai_v3_reg_defaults),
546 .readable_reg = fsl_sai_readable_reg,
547 .volatile_reg = fsl_sai_volatile_reg,
548 .writeable_reg = fsl_sai_writeable_reg,
549 @@ -874,6 +913,7 @@ static const struct of_device_id fsl_sai
550 { .compatible = "fsl,imx6sx-sai", .data = &fsl_sai_imx6sx },
551 { .compatible = "fsl,imx6ul-sai", .data = &fsl_sai_imx6ul },
552 { .compatible = "fsl,imx7ulp-sai", .data = &fsl_sai_imx7ulp },
553 + { .compatible = "fsl,imx8mq-sai", .data = &fsl_sai_imx8mq },
556 MODULE_DEVICE_TABLE(of, fsl_sai_ids);
557 @@ -889,7 +929,8 @@ static int fsl_sai_probe(struct platform
561 - unsigned long irqflag = 0;
562 + struct regmap_config fsl_sai_regmap_config = fsl_sai_v2_regmap_config;
563 + unsigned long irqflags = 0;
565 sai = devm_kzalloc(&pdev->dev, sizeof(*sai), GFP_KERNEL);
567 @@ -909,6 +950,9 @@ static int fsl_sai_probe(struct platform
569 return PTR_ERR(base);
571 + if (sai->soc->reg_offset == 8)
572 + fsl_sai_regmap_config = fsl_sai_v3_regmap_config;
574 sai->regmap = devm_regmap_init_mmio_clk(&pdev->dev,
575 "bus", base, &fsl_sai_regmap_config);
577 @@ -963,11 +1007,11 @@ static int fsl_sai_probe(struct platform
580 /* SAI shared interrupt */
581 - if (of_property_read_bool(np, "shared-interrupt"))
582 - irqflag = IRQF_SHARED;
583 + if (of_property_read_bool(np, "fsl,shared-interrupt"))
584 + irqflags = IRQF_SHARED;
586 - ret = devm_request_irq(&pdev->dev, irq, fsl_sai_isr, irqflag,
588 + ret = devm_request_irq(&pdev->dev, irq, fsl_sai_isr, irqflags, np->name,
591 dev_err(&pdev->dev, "failed to claim irq %u\n", irq);
593 @@ -1090,6 +1134,7 @@ static int fsl_sai_runtime_suspend(struc
594 static int fsl_sai_runtime_resume(struct device *dev)
596 struct fsl_sai *sai = dev_get_drvdata(dev);
597 + unsigned char offset = sai->soc->reg_offset;
600 ret = clk_prepare_enable(sai->bus_clk);
601 @@ -1115,11 +1160,11 @@ static int fsl_sai_runtime_resume(struct
602 PM_QOS_CPU_DMA_LATENCY, 0);
604 regcache_cache_only(sai->regmap, false);
605 - regmap_write(sai->regmap, FSL_SAI_TCSR, FSL_SAI_CSR_SR);
606 - regmap_write(sai->regmap, FSL_SAI_RCSR, FSL_SAI_CSR_SR);
607 + regmap_write(sai->regmap, FSL_SAI_TCSR(offset), FSL_SAI_CSR_SR);
608 + regmap_write(sai->regmap, FSL_SAI_RCSR(offset), FSL_SAI_CSR_SR);
609 usleep_range(1000, 2000);
610 - regmap_write(sai->regmap, FSL_SAI_TCSR, 0);
611 - regmap_write(sai->regmap, FSL_SAI_RCSR, 0);
612 + regmap_write(sai->regmap, FSL_SAI_TCSR(offset), 0);
613 + regmap_write(sai->regmap, FSL_SAI_RCSR(offset), 0);
615 ret = regcache_sync(sai->regmap);
617 --- a/sound/soc/fsl/fsl_sai.h
618 +++ b/sound/soc/fsl/fsl_sai.h
620 SNDRV_PCM_FMTBIT_S32_LE)
622 /* SAI Register Map Register */
623 -#define FSL_SAI_TCSR 0x00 /* SAI Transmit Control */
624 -#define FSL_SAI_TCR1 0x04 /* SAI Transmit Configuration 1 */
625 -#define FSL_SAI_TCR2 0x08 /* SAI Transmit Configuration 2 */
626 -#define FSL_SAI_TCR3 0x0c /* SAI Transmit Configuration 3 */
627 -#define FSL_SAI_TCR4 0x10 /* SAI Transmit Configuration 4 */
628 -#define FSL_SAI_TCR5 0x14 /* SAI Transmit Configuration 5 */
629 +#define FSL_SAI_TCSR(offset) (0x00 + offset) /* SAI Transmit Control */
630 +#define FSL_SAI_TCR1(offset) (0x04 + offset) /* SAI Transmit Configuration 1 */
631 +#define FSL_SAI_TCR2(offset) (0x08 + offset) /* SAI Transmit Configuration 2 */
632 +#define FSL_SAI_TCR3(offset) (0x0c + offset) /* SAI Transmit Configuration 3 */
633 +#define FSL_SAI_TCR4(offset) (0x10 + offset) /* SAI Transmit Configuration 4 */
634 +#define FSL_SAI_TCR5(offset) (0x14 + offset) /* SAI Transmit Configuration 5 */
635 #define FSL_SAI_TDR0 0x20 /* SAI Transmit Data */
636 #define FSL_SAI_TDR1 0x24 /* SAI Transmit Data */
637 #define FSL_SAI_TFR0 0x40 /* SAI Transmit FIFO */
638 #define FSL_SAI_TFR1 0x44 /* SAI Transmit FIFO */
639 #define FSL_SAI_TFR 0x40 /* SAI Transmit FIFO */
640 #define FSL_SAI_TMR 0x60 /* SAI Transmit Mask */
641 -#define FSL_SAI_RCSR 0x80 /* SAI Receive Control */
642 -#define FSL_SAI_RCR1 0x84 /* SAI Receive Configuration 1 */
643 -#define FSL_SAI_RCR2 0x88 /* SAI Receive Configuration 2 */
644 -#define FSL_SAI_RCR3 0x8c /* SAI Receive Configuration 3 */
645 -#define FSL_SAI_RCR4 0x90 /* SAI Receive Configuration 4 */
646 -#define FSL_SAI_RCR5 0x94 /* SAI Receive Configuration 5 */
647 +#define FSL_SAI_RCSR(offset) (0x80 + offset) /* SAI Receive Control */
648 +#define FSL_SAI_RCR1(offset) (0x84 + offset) /* SAI Receive Configuration 1 */
649 +#define FSL_SAI_RCR2(offset) (0x88 + offset) /* SAI Receive Configuration 2 */
650 +#define FSL_SAI_RCR3(offset) (0x8c + offset) /* SAI Receive Configuration 3 */
651 +#define FSL_SAI_RCR4(offset) (0x90 + offset) /* SAI Receive Configuration 4 */
652 +#define FSL_SAI_RCR5(offset) (0x94 + offset) /* SAI Receive Configuration 5 */
653 #define FSL_SAI_RDR0 0xa0 /* SAI Receive Data */
654 #define FSL_SAI_RDR1 0xa4 /* SAI Receive Data */
655 #define FSL_SAI_RFR0 0xc0 /* SAI Receive FIFO */
656 #define FSL_SAI_RFR1 0xc4 /* SAI Receive FIFO */
657 #define FSL_SAI_RMR 0xe0 /* SAI Receive Mask */
659 -#define FSL_SAI_xCSR(tx) (tx ? FSL_SAI_TCSR : FSL_SAI_RCSR)
660 -#define FSL_SAI_xCR1(tx) (tx ? FSL_SAI_TCR1 : FSL_SAI_RCR1)
661 -#define FSL_SAI_xCR2(tx) (tx ? FSL_SAI_TCR2 : FSL_SAI_RCR2)
662 -#define FSL_SAI_xCR3(tx) (tx ? FSL_SAI_TCR3 : FSL_SAI_RCR3)
663 -#define FSL_SAI_xCR4(tx) (tx ? FSL_SAI_TCR4 : FSL_SAI_RCR4)
664 -#define FSL_SAI_xCR5(tx) (tx ? FSL_SAI_TCR5 : FSL_SAI_RCR5)
665 -#define FSL_SAI_xDR(tx) (tx ? FSL_SAI_TDR : FSL_SAI_RDR)
666 -#define FSL_SAI_xFR(tx) (tx ? FSL_SAI_TFR : FSL_SAI_RFR)
667 +#define FSL_SAI_xCSR(tx, off) (tx ? FSL_SAI_TCSR(off) : FSL_SAI_RCSR(off))
668 +#define FSL_SAI_xCR1(tx, off) (tx ? FSL_SAI_TCR1(off) : FSL_SAI_RCR1(off))
669 +#define FSL_SAI_xCR2(tx, off) (tx ? FSL_SAI_TCR2(off) : FSL_SAI_RCR2(off))
670 +#define FSL_SAI_xCR3(tx, off) (tx ? FSL_SAI_TCR3(off) : FSL_SAI_RCR3(off))
671 +#define FSL_SAI_xCR4(tx, off) (tx ? FSL_SAI_TCR4(off) : FSL_SAI_RCR4(off))
672 +#define FSL_SAI_xCR5(tx, off) (tx ? FSL_SAI_TCR5(off) : FSL_SAI_RCR5(off))
673 #define FSL_SAI_xMR(tx) (tx ? FSL_SAI_TMR : FSL_SAI_RMR)
675 /* SAI Transmit/Receive Control Register */
677 #define FSL_SAI_CR2_DIV_MASK 0xff
679 /* SAI Transmit and Receive Configuration 3 Register */
680 -#define FSL_SAI_CR3_TRCE0 BIT(16)
681 -#define FSL_SAI_CR3_TRCE1 BIT(17)
682 +#define FSL_SAI_CR3_TRCE_MASK (0xff << 16)
683 #define FSL_SAI_CR3_TRCE(x) (x << 16)
684 #define FSL_SAI_CR3_WDFL(x) (x)
685 #define FSL_SAI_CR3_WDFL_MASK 0x1f
687 #define FSL_SAI_CR4_FCONT BIT(28)
688 #define FSL_SAI_CR4_FCOMB_SHIFT BIT(26)
689 #define FSL_SAI_CR4_FCOMB_SOFT BIT(27)
690 +#define FSL_SAI_CR4_FCOMB_MASK (0x3 << 26)
691 #define FSL_SAI_CR4_FPACK_8 (0x2 << 24)
692 #define FSL_SAI_CR4_FPACK_16 (0x3 << 24)
693 #define FSL_SAI_CR4_FRSZ(x) (((x) - 1) << 16)
694 @@ -147,6 +145,7 @@ struct fsl_sai_soc_data {
696 unsigned int dataline;
698 + unsigned char reg_offset;