xref: /openbmc/linux/sound/soc/fsl/fsl_sai.c (revision 6c870213d6f3a25981c10728f46294a3bed1703f)
1 /*
2  * Freescale ALSA SoC Digital Audio Interface (SAI) driver.
3  *
4  * Copyright 2012-2013 Freescale Semiconductor, Inc.
5  *
6  * This program is free software, you can redistribute it and/or modify it
7  * under the terms of the GNU General Public License as published by the
8  * Free Software Foundation, either version 2 of the License, or(at your
9  * option) any later version.
10  *
11  */
12 
13 #include <linux/clk.h>
14 #include <linux/delay.h>
15 #include <linux/dmaengine.h>
16 #include <linux/module.h>
17 #include <linux/of_address.h>
18 #include <linux/regmap.h>
19 #include <linux/slab.h>
20 #include <sound/core.h>
21 #include <sound/dmaengine_pcm.h>
22 #include <sound/pcm_params.h>
23 
24 #include "fsl_sai.h"
25 
26 #define FSL_SAI_FLAGS (FSL_SAI_CSR_SEIE |\
27 		       FSL_SAI_CSR_FEIE)
28 
29 static irqreturn_t fsl_sai_isr(int irq, void *devid)
30 {
31 	struct fsl_sai *sai = (struct fsl_sai *)devid;
32 	struct device *dev = &sai->pdev->dev;
33 	u32 xcsr, mask;
34 
35 	/* Only handle those what we enabled */
36 	mask = (FSL_SAI_FLAGS >> FSL_SAI_CSR_xIE_SHIFT) << FSL_SAI_CSR_xF_SHIFT;
37 
38 	/* Tx IRQ */
39 	regmap_read(sai->regmap, FSL_SAI_TCSR, &xcsr);
40 	xcsr &= mask;
41 
42 	if (xcsr & FSL_SAI_CSR_WSF)
43 		dev_dbg(dev, "isr: Start of Tx word detected\n");
44 
45 	if (xcsr & FSL_SAI_CSR_SEF)
46 		dev_warn(dev, "isr: Tx Frame sync error detected\n");
47 
48 	if (xcsr & FSL_SAI_CSR_FEF) {
49 		dev_warn(dev, "isr: Transmit underrun detected\n");
50 		/* FIFO reset for safety */
51 		xcsr |= FSL_SAI_CSR_FR;
52 	}
53 
54 	if (xcsr & FSL_SAI_CSR_FWF)
55 		dev_dbg(dev, "isr: Enabled transmit FIFO is empty\n");
56 
57 	if (xcsr & FSL_SAI_CSR_FRF)
58 		dev_dbg(dev, "isr: Transmit FIFO watermark has been reached\n");
59 
60 	regmap_update_bits(sai->regmap, FSL_SAI_TCSR,
61 			   FSL_SAI_CSR_xF_W_MASK | FSL_SAI_CSR_FR, xcsr);
62 
63 	/* Rx IRQ */
64 	regmap_read(sai->regmap, FSL_SAI_RCSR, &xcsr);
65 	xcsr &= mask;
66 
67 	if (xcsr & FSL_SAI_CSR_WSF)
68 		dev_dbg(dev, "isr: Start of Rx word detected\n");
69 
70 	if (xcsr & FSL_SAI_CSR_SEF)
71 		dev_warn(dev, "isr: Rx Frame sync error detected\n");
72 
73 	if (xcsr & FSL_SAI_CSR_FEF) {
74 		dev_warn(dev, "isr: Receive overflow detected\n");
75 		/* FIFO reset for safety */
76 		xcsr |= FSL_SAI_CSR_FR;
77 	}
78 
79 	if (xcsr & FSL_SAI_CSR_FWF)
80 		dev_dbg(dev, "isr: Enabled receive FIFO is full\n");
81 
82 	if (xcsr & FSL_SAI_CSR_FRF)
83 		dev_dbg(dev, "isr: Receive FIFO watermark has been reached\n");
84 
85 	regmap_update_bits(sai->regmap, FSL_SAI_RCSR,
86 			   FSL_SAI_CSR_xF_W_MASK | FSL_SAI_CSR_FR, xcsr);
87 
88 	return IRQ_HANDLED;
89 }
90 
91 static int fsl_sai_set_dai_sysclk_tr(struct snd_soc_dai *cpu_dai,
92 		int clk_id, unsigned int freq, int fsl_dir)
93 {
94 	struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);
95 	u32 val_cr2, reg_cr2;
96 
97 	if (fsl_dir == FSL_FMT_TRANSMITTER)
98 		reg_cr2 = FSL_SAI_TCR2;
99 	else
100 		reg_cr2 = FSL_SAI_RCR2;
101 
102 	regmap_read(sai->regmap, reg_cr2, &val_cr2);
103 
104 	val_cr2 &= ~FSL_SAI_CR2_MSEL_MASK;
105 
106 	switch (clk_id) {
107 	case FSL_SAI_CLK_BUS:
108 		val_cr2 |= FSL_SAI_CR2_MSEL_BUS;
109 		break;
110 	case FSL_SAI_CLK_MAST1:
111 		val_cr2 |= FSL_SAI_CR2_MSEL_MCLK1;
112 		break;
113 	case FSL_SAI_CLK_MAST2:
114 		val_cr2 |= FSL_SAI_CR2_MSEL_MCLK2;
115 		break;
116 	case FSL_SAI_CLK_MAST3:
117 		val_cr2 |= FSL_SAI_CR2_MSEL_MCLK3;
118 		break;
119 	default:
120 		return -EINVAL;
121 	}
122 
123 	regmap_write(sai->regmap, reg_cr2, val_cr2);
124 
125 	return 0;
126 }
127 
128 static int fsl_sai_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
129 		int clk_id, unsigned int freq, int dir)
130 {
131 	int ret;
132 
133 	if (dir == SND_SOC_CLOCK_IN)
134 		return 0;
135 
136 	ret = fsl_sai_set_dai_sysclk_tr(cpu_dai, clk_id, freq,
137 					FSL_FMT_TRANSMITTER);
138 	if (ret) {
139 		dev_err(cpu_dai->dev, "Cannot set tx sysclk: %d\n", ret);
140 		return ret;
141 	}
142 
143 	ret = fsl_sai_set_dai_sysclk_tr(cpu_dai, clk_id, freq,
144 					FSL_FMT_RECEIVER);
145 	if (ret)
146 		dev_err(cpu_dai->dev, "Cannot set rx sysclk: %d\n", ret);
147 
148 	return ret;
149 }
150 
151 static int fsl_sai_set_dai_fmt_tr(struct snd_soc_dai *cpu_dai,
152 				unsigned int fmt, int fsl_dir)
153 {
154 	struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);
155 	u32 val_cr2, val_cr4, reg_cr2, reg_cr4;
156 
157 	if (fsl_dir == FSL_FMT_TRANSMITTER) {
158 		reg_cr2 = FSL_SAI_TCR2;
159 		reg_cr4 = FSL_SAI_TCR4;
160 	} else {
161 		reg_cr2 = FSL_SAI_RCR2;
162 		reg_cr4 = FSL_SAI_RCR4;
163 	}
164 
165 	regmap_read(sai->regmap, reg_cr2, &val_cr2);
166 	regmap_read(sai->regmap, reg_cr4, &val_cr4);
167 
168 	if (sai->big_endian_data)
169 		val_cr4 &= ~FSL_SAI_CR4_MF;
170 	else
171 		val_cr4 |= FSL_SAI_CR4_MF;
172 
173 	/* DAI mode */
174 	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
175 	case SND_SOC_DAIFMT_I2S:
176 		/*
177 		 * Frame low, 1clk before data, one word length for frame sync,
178 		 * frame sync starts one serial clock cycle earlier,
179 		 * that is, together with the last bit of the previous
180 		 * data word.
181 		 */
182 		val_cr2 |= FSL_SAI_CR2_BCP;
183 		val_cr4 |= FSL_SAI_CR4_FSE | FSL_SAI_CR4_FSP;
184 		break;
185 	case SND_SOC_DAIFMT_LEFT_J:
186 		/*
187 		 * Frame high, one word length for frame sync,
188 		 * frame sync asserts with the first bit of the frame.
189 		 */
190 		val_cr2 |= FSL_SAI_CR2_BCP;
191 		val_cr4 &= ~(FSL_SAI_CR4_FSE | FSL_SAI_CR4_FSP);
192 		break;
193 	case SND_SOC_DAIFMT_DSP_A:
194 		/*
195 		 * Frame high, 1clk before data, one bit for frame sync,
196 		 * frame sync starts one serial clock cycle earlier,
197 		 * that is, together with the last bit of the previous
198 		 * data word.
199 		 */
200 		val_cr2 |= FSL_SAI_CR2_BCP;
201 		val_cr4 &= ~FSL_SAI_CR4_FSP;
202 		val_cr4 |= FSL_SAI_CR4_FSE;
203 		sai->is_dsp_mode = true;
204 		break;
205 	case SND_SOC_DAIFMT_DSP_B:
206 		/*
207 		 * Frame high, one bit for frame sync,
208 		 * frame sync asserts with the first bit of the frame.
209 		 */
210 		val_cr2 |= FSL_SAI_CR2_BCP;
211 		val_cr4 &= ~(FSL_SAI_CR4_FSE | FSL_SAI_CR4_FSP);
212 		sai->is_dsp_mode = true;
213 		break;
214 	case SND_SOC_DAIFMT_RIGHT_J:
215 		/* To be done */
216 	default:
217 		return -EINVAL;
218 	}
219 
220 	/* DAI clock inversion */
221 	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
222 	case SND_SOC_DAIFMT_IB_IF:
223 		/* Invert both clocks */
224 		val_cr2 ^= FSL_SAI_CR2_BCP;
225 		val_cr4 ^= FSL_SAI_CR4_FSP;
226 		break;
227 	case SND_SOC_DAIFMT_IB_NF:
228 		/* Invert bit clock */
229 		val_cr2 ^= FSL_SAI_CR2_BCP;
230 		break;
231 	case SND_SOC_DAIFMT_NB_IF:
232 		/* Invert frame clock */
233 		val_cr4 ^= FSL_SAI_CR4_FSP;
234 		break;
235 	case SND_SOC_DAIFMT_NB_NF:
236 		/* Nothing to do for both normal cases */
237 		break;
238 	default:
239 		return -EINVAL;
240 	}
241 
242 	/* DAI clock master masks */
243 	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
244 	case SND_SOC_DAIFMT_CBS_CFS:
245 		val_cr2 |= FSL_SAI_CR2_BCD_MSTR;
246 		val_cr4 |= FSL_SAI_CR4_FSD_MSTR;
247 		break;
248 	case SND_SOC_DAIFMT_CBM_CFM:
249 		val_cr2 &= ~FSL_SAI_CR2_BCD_MSTR;
250 		val_cr4 &= ~FSL_SAI_CR4_FSD_MSTR;
251 		break;
252 	case SND_SOC_DAIFMT_CBS_CFM:
253 		val_cr2 |= FSL_SAI_CR2_BCD_MSTR;
254 		val_cr4 &= ~FSL_SAI_CR4_FSD_MSTR;
255 		break;
256 	case SND_SOC_DAIFMT_CBM_CFS:
257 		val_cr2 &= ~FSL_SAI_CR2_BCD_MSTR;
258 		val_cr4 |= FSL_SAI_CR4_FSD_MSTR;
259 		break;
260 	default:
261 		return -EINVAL;
262 	}
263 
264 	regmap_write(sai->regmap, reg_cr2, val_cr2);
265 	regmap_write(sai->regmap, reg_cr4, val_cr4);
266 
267 	return 0;
268 }
269 
270 static int fsl_sai_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
271 {
272 	int ret;
273 
274 	ret = fsl_sai_set_dai_fmt_tr(cpu_dai, fmt, FSL_FMT_TRANSMITTER);
275 	if (ret) {
276 		dev_err(cpu_dai->dev, "Cannot set tx format: %d\n", ret);
277 		return ret;
278 	}
279 
280 	ret = fsl_sai_set_dai_fmt_tr(cpu_dai, fmt, FSL_FMT_RECEIVER);
281 	if (ret)
282 		dev_err(cpu_dai->dev, "Cannot set rx format: %d\n", ret);
283 
284 	return ret;
285 }
286 
287 static int fsl_sai_hw_params(struct snd_pcm_substream *substream,
288 		struct snd_pcm_hw_params *params,
289 		struct snd_soc_dai *cpu_dai)
290 {
291 	struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);
292 	u32 val_cr4, val_cr5, val_mr, reg_cr4, reg_cr5, reg_mr;
293 	unsigned int channels = params_channels(params);
294 	u32 word_width = snd_pcm_format_width(params_format(params));
295 
296 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
297 		reg_cr4 = FSL_SAI_TCR4;
298 		reg_cr5 = FSL_SAI_TCR5;
299 		reg_mr = FSL_SAI_TMR;
300 	} else {
301 		reg_cr4 = FSL_SAI_RCR4;
302 		reg_cr5 = FSL_SAI_RCR5;
303 		reg_mr = FSL_SAI_RMR;
304 	}
305 
306 	regmap_read(sai->regmap, reg_cr4, &val_cr4);
307 	regmap_read(sai->regmap, reg_cr4, &val_cr5);
308 
309 	val_cr4 &= ~FSL_SAI_CR4_SYWD_MASK;
310 	val_cr4 &= ~FSL_SAI_CR4_FRSZ_MASK;
311 
312 	val_cr5 &= ~FSL_SAI_CR5_WNW_MASK;
313 	val_cr5 &= ~FSL_SAI_CR5_W0W_MASK;
314 	val_cr5 &= ~FSL_SAI_CR5_FBT_MASK;
315 
316 	if (!sai->is_dsp_mode)
317 		val_cr4 |= FSL_SAI_CR4_SYWD(word_width);
318 
319 	val_cr5 |= FSL_SAI_CR5_WNW(word_width);
320 	val_cr5 |= FSL_SAI_CR5_W0W(word_width);
321 
322 	val_cr5 &= ~FSL_SAI_CR5_FBT_MASK;
323 	if (sai->big_endian_data)
324 		val_cr5 |= FSL_SAI_CR5_FBT(0);
325 	else
326 		val_cr5 |= FSL_SAI_CR5_FBT(word_width - 1);
327 
328 	val_cr4 |= FSL_SAI_CR4_FRSZ(channels);
329 	val_mr = ~0UL - ((1 << channels) - 1);
330 
331 	regmap_write(sai->regmap, reg_cr4, val_cr4);
332 	regmap_write(sai->regmap, reg_cr5, val_cr5);
333 	regmap_write(sai->regmap, reg_mr, val_mr);
334 
335 	return 0;
336 }
337 
338 static int fsl_sai_trigger(struct snd_pcm_substream *substream, int cmd,
339 		struct snd_soc_dai *cpu_dai)
340 {
341 	struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);
342 	u32 tcsr, rcsr;
343 
344 	/*
345 	 * The transmitter bit clock and frame sync are to be
346 	 * used by both the transmitter and receiver.
347 	 */
348 	regmap_update_bits(sai->regmap, FSL_SAI_TCR2, FSL_SAI_CR2_SYNC,
349 			   ~FSL_SAI_CR2_SYNC);
350 	regmap_update_bits(sai->regmap, FSL_SAI_RCR2, FSL_SAI_CR2_SYNC,
351 			   FSL_SAI_CR2_SYNC);
352 
353 	regmap_read(sai->regmap, FSL_SAI_TCSR, &tcsr);
354 	regmap_read(sai->regmap, FSL_SAI_RCSR, &rcsr);
355 
356 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
357 		tcsr |= FSL_SAI_CSR_FRDE;
358 		rcsr &= ~FSL_SAI_CSR_FRDE;
359 	} else {
360 		rcsr |= FSL_SAI_CSR_FRDE;
361 		tcsr &= ~FSL_SAI_CSR_FRDE;
362 	}
363 
364 	/*
365 	 * It is recommended that the transmitter is the last enabled
366 	 * and the first disabled.
367 	 */
368 	switch (cmd) {
369 	case SNDRV_PCM_TRIGGER_START:
370 	case SNDRV_PCM_TRIGGER_RESUME:
371 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
372 		tcsr |= FSL_SAI_CSR_TERE;
373 		rcsr |= FSL_SAI_CSR_TERE;
374 
375 		regmap_write(sai->regmap, FSL_SAI_RCSR, rcsr);
376 		regmap_write(sai->regmap, FSL_SAI_TCSR, tcsr);
377 		break;
378 	case SNDRV_PCM_TRIGGER_STOP:
379 	case SNDRV_PCM_TRIGGER_SUSPEND:
380 	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
381 		if (!(cpu_dai->playback_active || cpu_dai->capture_active)) {
382 			tcsr &= ~FSL_SAI_CSR_TERE;
383 			rcsr &= ~FSL_SAI_CSR_TERE;
384 		}
385 
386 		regmap_write(sai->regmap, FSL_SAI_TCSR, tcsr);
387 		regmap_write(sai->regmap, FSL_SAI_RCSR, rcsr);
388 		break;
389 	default:
390 		return -EINVAL;
391 	}
392 
393 	return 0;
394 }
395 
396 static int fsl_sai_startup(struct snd_pcm_substream *substream,
397 		struct snd_soc_dai *cpu_dai)
398 {
399 	struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);
400 	u32 reg;
401 
402 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
403 		reg = FSL_SAI_TCR3;
404 	else
405 		reg = FSL_SAI_RCR3;
406 
407 	regmap_update_bits(sai->regmap, reg, FSL_SAI_CR3_TRCE,
408 			   FSL_SAI_CR3_TRCE);
409 
410 	return 0;
411 }
412 
413 static void fsl_sai_shutdown(struct snd_pcm_substream *substream,
414 		struct snd_soc_dai *cpu_dai)
415 {
416 	struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);
417 	u32 reg;
418 
419 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
420 		reg = FSL_SAI_TCR3;
421 	else
422 		reg = FSL_SAI_RCR3;
423 
424 	regmap_update_bits(sai->regmap, reg, FSL_SAI_CR3_TRCE,
425 			   ~FSL_SAI_CR3_TRCE);
426 }
427 
428 static const struct snd_soc_dai_ops fsl_sai_pcm_dai_ops = {
429 	.set_sysclk	= fsl_sai_set_dai_sysclk,
430 	.set_fmt	= fsl_sai_set_dai_fmt,
431 	.hw_params	= fsl_sai_hw_params,
432 	.trigger	= fsl_sai_trigger,
433 	.startup	= fsl_sai_startup,
434 	.shutdown	= fsl_sai_shutdown,
435 };
436 
437 static int fsl_sai_dai_probe(struct snd_soc_dai *cpu_dai)
438 {
439 	struct fsl_sai *sai = dev_get_drvdata(cpu_dai->dev);
440 
441 	regmap_update_bits(sai->regmap, FSL_SAI_TCSR, 0xffffffff, FSL_SAI_FLAGS);
442 	regmap_update_bits(sai->regmap, FSL_SAI_RCSR, 0xffffffff, FSL_SAI_FLAGS);
443 	regmap_update_bits(sai->regmap, FSL_SAI_TCR1, FSL_SAI_CR1_RFW_MASK,
444 			   FSL_SAI_MAXBURST_TX * 2);
445 	regmap_update_bits(sai->regmap, FSL_SAI_RCR1, FSL_SAI_CR1_RFW_MASK,
446 			   FSL_SAI_MAXBURST_RX - 1);
447 
448 	snd_soc_dai_init_dma_data(cpu_dai, &sai->dma_params_tx,
449 				&sai->dma_params_rx);
450 
451 	snd_soc_dai_set_drvdata(cpu_dai, sai);
452 
453 	return 0;
454 }
455 
456 static struct snd_soc_dai_driver fsl_sai_dai = {
457 	.probe = fsl_sai_dai_probe,
458 	.playback = {
459 		.channels_min = 1,
460 		.channels_max = 2,
461 		.rates = SNDRV_PCM_RATE_8000_96000,
462 		.formats = FSL_SAI_FORMATS,
463 	},
464 	.capture = {
465 		.channels_min = 1,
466 		.channels_max = 2,
467 		.rates = SNDRV_PCM_RATE_8000_96000,
468 		.formats = FSL_SAI_FORMATS,
469 	},
470 	.ops = &fsl_sai_pcm_dai_ops,
471 };
472 
473 static const struct snd_soc_component_driver fsl_component = {
474 	.name           = "fsl-sai",
475 };
476 
477 static bool fsl_sai_readable_reg(struct device *dev, unsigned int reg)
478 {
479 	switch (reg) {
480 	case FSL_SAI_TCSR:
481 	case FSL_SAI_TCR1:
482 	case FSL_SAI_TCR2:
483 	case FSL_SAI_TCR3:
484 	case FSL_SAI_TCR4:
485 	case FSL_SAI_TCR5:
486 	case FSL_SAI_TFR:
487 	case FSL_SAI_TMR:
488 	case FSL_SAI_RCSR:
489 	case FSL_SAI_RCR1:
490 	case FSL_SAI_RCR2:
491 	case FSL_SAI_RCR3:
492 	case FSL_SAI_RCR4:
493 	case FSL_SAI_RCR5:
494 	case FSL_SAI_RDR:
495 	case FSL_SAI_RFR:
496 	case FSL_SAI_RMR:
497 		return true;
498 	default:
499 		return false;
500 	}
501 }
502 
503 static bool fsl_sai_volatile_reg(struct device *dev, unsigned int reg)
504 {
505 	switch (reg) {
506 	case FSL_SAI_TFR:
507 	case FSL_SAI_RFR:
508 	case FSL_SAI_TDR:
509 	case FSL_SAI_RDR:
510 		return true;
511 	default:
512 		return false;
513 	}
514 
515 }
516 
517 static bool fsl_sai_writeable_reg(struct device *dev, unsigned int reg)
518 {
519 	switch (reg) {
520 	case FSL_SAI_TCSR:
521 	case FSL_SAI_TCR1:
522 	case FSL_SAI_TCR2:
523 	case FSL_SAI_TCR3:
524 	case FSL_SAI_TCR4:
525 	case FSL_SAI_TCR5:
526 	case FSL_SAI_TDR:
527 	case FSL_SAI_TMR:
528 	case FSL_SAI_RCSR:
529 	case FSL_SAI_RCR1:
530 	case FSL_SAI_RCR2:
531 	case FSL_SAI_RCR3:
532 	case FSL_SAI_RCR4:
533 	case FSL_SAI_RCR5:
534 	case FSL_SAI_RMR:
535 		return true;
536 	default:
537 		return false;
538 	}
539 }
540 
541 static struct regmap_config fsl_sai_regmap_config = {
542 	.reg_bits = 32,
543 	.reg_stride = 4,
544 	.val_bits = 32,
545 
546 	.max_register = FSL_SAI_RMR,
547 	.readable_reg = fsl_sai_readable_reg,
548 	.volatile_reg = fsl_sai_volatile_reg,
549 	.writeable_reg = fsl_sai_writeable_reg,
550 };
551 
552 static int fsl_sai_probe(struct platform_device *pdev)
553 {
554 	struct device_node *np = pdev->dev.of_node;
555 	struct fsl_sai *sai;
556 	struct resource *res;
557 	void __iomem *base;
558 	int irq, ret;
559 
560 	sai = devm_kzalloc(&pdev->dev, sizeof(*sai), GFP_KERNEL);
561 	if (!sai)
562 		return -ENOMEM;
563 
564 	sai->pdev = pdev;
565 
566 	sai->big_endian_regs = of_property_read_bool(np, "big-endian-regs");
567 	if (sai->big_endian_regs)
568 		fsl_sai_regmap_config.val_format_endian = REGMAP_ENDIAN_BIG;
569 
570 	sai->big_endian_data = of_property_read_bool(np, "big-endian-data");
571 
572 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
573 	base = devm_ioremap_resource(&pdev->dev, res);
574 	if (IS_ERR(base))
575 		return PTR_ERR(base);
576 
577 	sai->regmap = devm_regmap_init_mmio_clk(&pdev->dev,
578 			"sai", base, &fsl_sai_regmap_config);
579 	if (IS_ERR(sai->regmap)) {
580 		dev_err(&pdev->dev, "regmap init failed\n");
581 		return PTR_ERR(sai->regmap);
582 	}
583 
584 	irq = platform_get_irq(pdev, 0);
585 	if (irq < 0) {
586 		dev_err(&pdev->dev, "no irq for node %s\n", np->full_name);
587 		return irq;
588 	}
589 
590 	ret = devm_request_irq(&pdev->dev, irq, fsl_sai_isr, 0, np->name, sai);
591 	if (ret) {
592 		dev_err(&pdev->dev, "failed to claim irq %u\n", irq);
593 		return ret;
594 	}
595 
596 	sai->dma_params_rx.addr = res->start + FSL_SAI_RDR;
597 	sai->dma_params_tx.addr = res->start + FSL_SAI_TDR;
598 	sai->dma_params_rx.maxburst = FSL_SAI_MAXBURST_RX;
599 	sai->dma_params_tx.maxburst = FSL_SAI_MAXBURST_TX;
600 
601 	platform_set_drvdata(pdev, sai);
602 
603 	ret = devm_snd_soc_register_component(&pdev->dev, &fsl_component,
604 			&fsl_sai_dai, 1);
605 	if (ret)
606 		return ret;
607 
608 	return devm_snd_dmaengine_pcm_register(&pdev->dev, NULL,
609 			SND_DMAENGINE_PCM_FLAG_NO_RESIDUE);
610 }
611 
612 static const struct of_device_id fsl_sai_ids[] = {
613 	{ .compatible = "fsl,vf610-sai", },
614 	{ /* sentinel */ }
615 };
616 
617 static struct platform_driver fsl_sai_driver = {
618 	.probe = fsl_sai_probe,
619 	.driver = {
620 		.name = "fsl-sai",
621 		.owner = THIS_MODULE,
622 		.of_match_table = fsl_sai_ids,
623 	},
624 };
625 module_platform_driver(fsl_sai_driver);
626 
627 MODULE_DESCRIPTION("Freescale Soc SAI Interface");
628 MODULE_AUTHOR("Xiubo Li, <Li.Xiubo@freescale.com>");
629 MODULE_ALIAS("platform:fsl-sai");
630 MODULE_LICENSE("GPL");
631