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