2 * Freescale ALSA SoC Digital Audio Interface (SAI) driver.
4 * Copyright 2012-2013 Freescale Semiconductor, Inc.
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.
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>
26 #define FSL_SAI_FLAGS (FSL_SAI_CSR_SEIE |\
29 static irqreturn_t
fsl_sai_isr(int irq
, void *devid
)
31 struct fsl_sai
*sai
= (struct fsl_sai
*)devid
;
32 struct device
*dev
= &sai
->pdev
->dev
;
35 /* Only handle those what we enabled */
36 mask
= (FSL_SAI_FLAGS
>> FSL_SAI_CSR_xIE_SHIFT
) << FSL_SAI_CSR_xF_SHIFT
;
39 regmap_read(sai
->regmap
, FSL_SAI_TCSR
, &xcsr
);
42 if (xcsr
& FSL_SAI_CSR_WSF
)
43 dev_dbg(dev
, "isr: Start of Tx word detected\n");
45 if (xcsr
& FSL_SAI_CSR_SEF
)
46 dev_warn(dev
, "isr: Tx Frame sync error detected\n");
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
;
54 if (xcsr
& FSL_SAI_CSR_FWF
)
55 dev_dbg(dev
, "isr: Enabled transmit FIFO is empty\n");
57 if (xcsr
& FSL_SAI_CSR_FRF
)
58 dev_dbg(dev
, "isr: Transmit FIFO watermark has been reached\n");
60 regmap_update_bits(sai
->regmap
, FSL_SAI_TCSR
,
61 FSL_SAI_CSR_xF_W_MASK
| FSL_SAI_CSR_FR
, xcsr
);
64 regmap_read(sai
->regmap
, FSL_SAI_RCSR
, &xcsr
);
67 if (xcsr
& FSL_SAI_CSR_WSF
)
68 dev_dbg(dev
, "isr: Start of Rx word detected\n");
70 if (xcsr
& FSL_SAI_CSR_SEF
)
71 dev_warn(dev
, "isr: Rx Frame sync error detected\n");
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
;
79 if (xcsr
& FSL_SAI_CSR_FWF
)
80 dev_dbg(dev
, "isr: Enabled receive FIFO is full\n");
82 if (xcsr
& FSL_SAI_CSR_FRF
)
83 dev_dbg(dev
, "isr: Receive FIFO watermark has been reached\n");
85 regmap_update_bits(sai
->regmap
, FSL_SAI_RCSR
,
86 FSL_SAI_CSR_xF_W_MASK
| FSL_SAI_CSR_FR
, xcsr
);
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
)
94 struct fsl_sai
*sai
= snd_soc_dai_get_drvdata(cpu_dai
);
97 if (fsl_dir
== FSL_FMT_TRANSMITTER
)
98 reg_cr2
= FSL_SAI_TCR2
;
100 reg_cr2
= FSL_SAI_RCR2
;
102 regmap_read(sai
->regmap
, reg_cr2
, &val_cr2
);
104 val_cr2
&= ~FSL_SAI_CR2_MSEL_MASK
;
107 case FSL_SAI_CLK_BUS
:
108 val_cr2
|= FSL_SAI_CR2_MSEL_BUS
;
110 case FSL_SAI_CLK_MAST1
:
111 val_cr2
|= FSL_SAI_CR2_MSEL_MCLK1
;
113 case FSL_SAI_CLK_MAST2
:
114 val_cr2
|= FSL_SAI_CR2_MSEL_MCLK2
;
116 case FSL_SAI_CLK_MAST3
:
117 val_cr2
|= FSL_SAI_CR2_MSEL_MCLK3
;
123 regmap_write(sai
->regmap
, reg_cr2
, val_cr2
);
128 static int fsl_sai_set_dai_sysclk(struct snd_soc_dai
*cpu_dai
,
129 int clk_id
, unsigned int freq
, int dir
)
133 if (dir
== SND_SOC_CLOCK_IN
)
136 ret
= fsl_sai_set_dai_sysclk_tr(cpu_dai
, clk_id
, freq
,
137 FSL_FMT_TRANSMITTER
);
139 dev_err(cpu_dai
->dev
, "Cannot set tx sysclk: %d\n", ret
);
143 ret
= fsl_sai_set_dai_sysclk_tr(cpu_dai
, clk_id
, freq
,
146 dev_err(cpu_dai
->dev
, "Cannot set rx sysclk: %d\n", ret
);
151 static int fsl_sai_set_dai_fmt_tr(struct snd_soc_dai
*cpu_dai
,
152 unsigned int fmt
, int fsl_dir
)
154 struct fsl_sai
*sai
= snd_soc_dai_get_drvdata(cpu_dai
);
155 u32 val_cr2
, val_cr4
, reg_cr2
, reg_cr4
;
157 if (fsl_dir
== FSL_FMT_TRANSMITTER
) {
158 reg_cr2
= FSL_SAI_TCR2
;
159 reg_cr4
= FSL_SAI_TCR4
;
161 reg_cr2
= FSL_SAI_RCR2
;
162 reg_cr4
= FSL_SAI_RCR4
;
165 regmap_read(sai
->regmap
, reg_cr2
, &val_cr2
);
166 regmap_read(sai
->regmap
, reg_cr4
, &val_cr4
);
168 if (sai
->big_endian_data
)
169 val_cr4
&= ~FSL_SAI_CR4_MF
;
171 val_cr4
|= FSL_SAI_CR4_MF
;
174 switch (fmt
& SND_SOC_DAIFMT_FORMAT_MASK
) {
175 case SND_SOC_DAIFMT_I2S
:
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
182 val_cr2
|= FSL_SAI_CR2_BCP
;
183 val_cr4
|= FSL_SAI_CR4_FSE
| FSL_SAI_CR4_FSP
;
185 case SND_SOC_DAIFMT_LEFT_J
:
187 * Frame high, one word length for frame sync,
188 * frame sync asserts with the first bit of the frame.
190 val_cr2
|= FSL_SAI_CR2_BCP
;
191 val_cr4
&= ~(FSL_SAI_CR4_FSE
| FSL_SAI_CR4_FSP
);
193 case SND_SOC_DAIFMT_DSP_A
:
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
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;
205 case SND_SOC_DAIFMT_DSP_B
:
207 * Frame high, one bit for frame sync,
208 * frame sync asserts with the first bit of the frame.
210 val_cr2
|= FSL_SAI_CR2_BCP
;
211 val_cr4
&= ~(FSL_SAI_CR4_FSE
| FSL_SAI_CR4_FSP
);
212 sai
->is_dsp_mode
= true;
214 case SND_SOC_DAIFMT_RIGHT_J
:
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
;
227 case SND_SOC_DAIFMT_IB_NF
:
228 /* Invert bit clock */
229 val_cr2
^= FSL_SAI_CR2_BCP
;
231 case SND_SOC_DAIFMT_NB_IF
:
232 /* Invert frame clock */
233 val_cr4
^= FSL_SAI_CR4_FSP
;
235 case SND_SOC_DAIFMT_NB_NF
:
236 /* Nothing to do for both normal cases */
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
;
248 case SND_SOC_DAIFMT_CBM_CFM
:
249 val_cr2
&= ~FSL_SAI_CR2_BCD_MSTR
;
250 val_cr4
&= ~FSL_SAI_CR4_FSD_MSTR
;
252 case SND_SOC_DAIFMT_CBS_CFM
:
253 val_cr2
|= FSL_SAI_CR2_BCD_MSTR
;
254 val_cr4
&= ~FSL_SAI_CR4_FSD_MSTR
;
256 case SND_SOC_DAIFMT_CBM_CFS
:
257 val_cr2
&= ~FSL_SAI_CR2_BCD_MSTR
;
258 val_cr4
|= FSL_SAI_CR4_FSD_MSTR
;
264 regmap_write(sai
->regmap
, reg_cr2
, val_cr2
);
265 regmap_write(sai
->regmap
, reg_cr4
, val_cr4
);
270 static int fsl_sai_set_dai_fmt(struct snd_soc_dai
*cpu_dai
, unsigned int fmt
)
274 ret
= fsl_sai_set_dai_fmt_tr(cpu_dai
, fmt
, FSL_FMT_TRANSMITTER
);
276 dev_err(cpu_dai
->dev
, "Cannot set tx format: %d\n", ret
);
280 ret
= fsl_sai_set_dai_fmt_tr(cpu_dai
, fmt
, FSL_FMT_RECEIVER
);
282 dev_err(cpu_dai
->dev
, "Cannot set rx format: %d\n", ret
);
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
)
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
));
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
;
301 reg_cr4
= FSL_SAI_RCR4
;
302 reg_cr5
= FSL_SAI_RCR5
;
303 reg_mr
= FSL_SAI_RMR
;
306 regmap_read(sai
->regmap
, reg_cr4
, &val_cr4
);
307 regmap_read(sai
->regmap
, reg_cr4
, &val_cr5
);
309 val_cr4
&= ~FSL_SAI_CR4_SYWD_MASK
;
310 val_cr4
&= ~FSL_SAI_CR4_FRSZ_MASK
;
312 val_cr5
&= ~FSL_SAI_CR5_WNW_MASK
;
313 val_cr5
&= ~FSL_SAI_CR5_W0W_MASK
;
314 val_cr5
&= ~FSL_SAI_CR5_FBT_MASK
;
316 if (!sai
->is_dsp_mode
)
317 val_cr4
|= FSL_SAI_CR4_SYWD(word_width
);
319 val_cr5
|= FSL_SAI_CR5_WNW(word_width
);
320 val_cr5
|= FSL_SAI_CR5_W0W(word_width
);
322 val_cr5
&= ~FSL_SAI_CR5_FBT_MASK
;
323 if (sai
->big_endian_data
)
324 val_cr5
|= FSL_SAI_CR5_FBT(0);
326 val_cr5
|= FSL_SAI_CR5_FBT(word_width
- 1);
328 val_cr4
|= FSL_SAI_CR4_FRSZ(channels
);
329 val_mr
= ~0UL - ((1 << channels
) - 1);
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
);
338 static int fsl_sai_trigger(struct snd_pcm_substream
*substream
, int cmd
,
339 struct snd_soc_dai
*cpu_dai
)
341 struct fsl_sai
*sai
= snd_soc_dai_get_drvdata(cpu_dai
);
345 * The transmitter bit clock and frame sync are to be
346 * used by both the transmitter and receiver.
348 regmap_update_bits(sai
->regmap
, FSL_SAI_TCR2
, FSL_SAI_CR2_SYNC
,
350 regmap_update_bits(sai
->regmap
, FSL_SAI_RCR2
, FSL_SAI_CR2_SYNC
,
353 regmap_read(sai
->regmap
, FSL_SAI_TCSR
, &tcsr
);
354 regmap_read(sai
->regmap
, FSL_SAI_RCSR
, &rcsr
);
356 if (substream
->stream
== SNDRV_PCM_STREAM_PLAYBACK
) {
357 tcsr
|= FSL_SAI_CSR_FRDE
;
358 rcsr
&= ~FSL_SAI_CSR_FRDE
;
360 rcsr
|= FSL_SAI_CSR_FRDE
;
361 tcsr
&= ~FSL_SAI_CSR_FRDE
;
365 * It is recommended that the transmitter is the last enabled
366 * and the first disabled.
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
;
375 regmap_write(sai
->regmap
, FSL_SAI_RCSR
, rcsr
);
376 regmap_write(sai
->regmap
, FSL_SAI_TCSR
, tcsr
);
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
;
386 regmap_write(sai
->regmap
, FSL_SAI_TCSR
, tcsr
);
387 regmap_write(sai
->regmap
, FSL_SAI_RCSR
, rcsr
);
396 static int fsl_sai_startup(struct snd_pcm_substream
*substream
,
397 struct snd_soc_dai
*cpu_dai
)
399 struct fsl_sai
*sai
= snd_soc_dai_get_drvdata(cpu_dai
);
402 if (substream
->stream
== SNDRV_PCM_STREAM_PLAYBACK
)
407 regmap_update_bits(sai
->regmap
, reg
, FSL_SAI_CR3_TRCE
,
413 static void fsl_sai_shutdown(struct snd_pcm_substream
*substream
,
414 struct snd_soc_dai
*cpu_dai
)
416 struct fsl_sai
*sai
= snd_soc_dai_get_drvdata(cpu_dai
);
419 if (substream
->stream
== SNDRV_PCM_STREAM_PLAYBACK
)
424 regmap_update_bits(sai
->regmap
, reg
, FSL_SAI_CR3_TRCE
,
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
,
437 static int fsl_sai_dai_probe(struct snd_soc_dai
*cpu_dai
)
439 struct fsl_sai
*sai
= dev_get_drvdata(cpu_dai
->dev
);
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);
448 snd_soc_dai_init_dma_data(cpu_dai
, &sai
->dma_params_tx
,
449 &sai
->dma_params_rx
);
451 snd_soc_dai_set_drvdata(cpu_dai
, sai
);
456 static struct snd_soc_dai_driver fsl_sai_dai
= {
457 .probe
= fsl_sai_dai_probe
,
461 .rates
= SNDRV_PCM_RATE_8000_96000
,
462 .formats
= FSL_SAI_FORMATS
,
467 .rates
= SNDRV_PCM_RATE_8000_96000
,
468 .formats
= FSL_SAI_FORMATS
,
470 .ops
= &fsl_sai_pcm_dai_ops
,
473 static const struct snd_soc_component_driver fsl_component
= {
477 static bool fsl_sai_readable_reg(struct device
*dev
, unsigned int reg
)
503 static bool fsl_sai_volatile_reg(struct device
*dev
, unsigned int reg
)
517 static bool fsl_sai_writeable_reg(struct device
*dev
, unsigned int reg
)
541 static struct regmap_config fsl_sai_regmap_config
= {
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
,
552 static int fsl_sai_probe(struct platform_device
*pdev
)
554 struct device_node
*np
= pdev
->dev
.of_node
;
556 struct resource
*res
;
560 sai
= devm_kzalloc(&pdev
->dev
, sizeof(*sai
), GFP_KERNEL
);
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
;
570 sai
->big_endian_data
= of_property_read_bool(np
, "big-endian-data");
572 res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
573 base
= devm_ioremap_resource(&pdev
->dev
, res
);
575 return PTR_ERR(base
);
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
);
584 irq
= platform_get_irq(pdev
, 0);
586 dev_err(&pdev
->dev
, "no irq for node %s\n", np
->full_name
);
590 ret
= devm_request_irq(&pdev
->dev
, irq
, fsl_sai_isr
, 0, np
->name
, sai
);
592 dev_err(&pdev
->dev
, "failed to claim irq %u\n", irq
);
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
;
601 platform_set_drvdata(pdev
, sai
);
603 ret
= devm_snd_soc_register_component(&pdev
->dev
, &fsl_component
,
608 return devm_snd_dmaengine_pcm_register(&pdev
->dev
, NULL
,
609 SND_DMAENGINE_PCM_FLAG_NO_RESIDUE
);
612 static const struct of_device_id fsl_sai_ids
[] = {
613 { .compatible
= "fsl,vf610-sai", },
617 static struct platform_driver fsl_sai_driver
= {
618 .probe
= fsl_sai_probe
,
621 .owner
= THIS_MODULE
,
622 .of_match_table
= fsl_sai_ids
,
625 module_platform_driver(fsl_sai_driver
);
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");