2 * imx-ssi.c -- ALSA Soc Audio Layer
4 * Copyright 2009 Sascha Hauer <s.hauer@pengutronix.de>
6 * This code is based on code copyrighted by Freescale,
7 * Liam Girdwood, Javier Martin and probably others.
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the
11 * Free Software Foundation; either version 2 of the License, or (at your
12 * option) any later version.
15 * The i.MX SSI core has some nasty limitations in AC97 mode. While most
16 * sane processor vendors have a FIFO per AC97 slot, the i.MX has only
17 * one FIFO which combines all valid receive slots. We cannot even select
18 * which slots we want to receive. The WM9712 with which this driver
19 * was developped with always sends GPIO status data in slot 12 which
20 * we receive in our (PCM-) data stream. The only chance we have is to
21 * manually skip this data in the FIQ handler. With sampling rates different
22 * from 48000Hz not every frame has valid receive data, so the ratio
23 * between pcm data and GPIO status data changes. Our FIQ handler is not
24 * able to handle this, hence this driver only works with 48000Hz sampling
26 * Reading and writing AC97 registers is another challange. The core
27 * provides us status bits when the read register is updated with *another*
28 * value. When we read the same register two times (and the register still
29 * contains the same value) these status bits are not set. We work
30 * around this by not polling these bits but only wait a fixed delay.
34 #include <linux/clk.h>
35 #include <linux/delay.h>
36 #include <linux/device.h>
37 #include <linux/dma-mapping.h>
38 #include <linux/init.h>
39 #include <linux/interrupt.h>
40 #include <linux/module.h>
41 #include <linux/platform_device.h>
43 #include <sound/core.h>
44 #include <sound/initval.h>
45 #include <sound/pcm.h>
46 #include <sound/pcm_params.h>
47 #include <sound/soc.h>
50 #include <mach/hardware.h>
54 #define SSI_SACNT_DEFAULT (SSI_SACNT_AC97EN | SSI_SACNT_FV)
57 * SSI Network Mode or TDM slots configuration.
58 * Should only be called when port is inactive (i.e. SSIEN = 0).
60 static int imx_ssi_set_dai_tdm_slot(struct snd_soc_dai
*cpu_dai
,
61 unsigned int tx_mask
, unsigned int rx_mask
, int slots
, int slot_width
)
63 struct imx_ssi
*ssi
= cpu_dai
->private_data
;
66 sccr
= readl(ssi
->base
+ SSI_STCCR
);
67 sccr
&= ~SSI_STCCR_DC_MASK
;
68 sccr
|= SSI_STCCR_DC(slots
- 1);
69 writel(sccr
, ssi
->base
+ SSI_STCCR
);
71 sccr
= readl(ssi
->base
+ SSI_SRCCR
);
72 sccr
&= ~SSI_STCCR_DC_MASK
;
73 sccr
|= SSI_STCCR_DC(slots
- 1);
74 writel(sccr
, ssi
->base
+ SSI_SRCCR
);
76 writel(tx_mask
, ssi
->base
+ SSI_STMSK
);
77 writel(rx_mask
, ssi
->base
+ SSI_SRMSK
);
83 * SSI DAI format configuration.
84 * Should only be called when port is inactive (i.e. SSIEN = 0).
85 * Note: We don't use the I2S modes but instead manually configure the
86 * SSI for I2S because the I2S mode is only a register preset.
88 static int imx_ssi_set_dai_fmt(struct snd_soc_dai
*cpu_dai
, unsigned int fmt
)
90 struct imx_ssi
*ssi
= cpu_dai
->private_data
;
93 scr
= readl(ssi
->base
+ SSI_SCR
) & ~(SSI_SCR_SYN
| SSI_SCR_NET
);
96 switch (fmt
& SND_SOC_DAIFMT_FORMAT_MASK
) {
97 case SND_SOC_DAIFMT_I2S
:
98 /* data on rising edge of bclk, frame low 1clk before data */
99 strcr
|= SSI_STCR_TFSI
| SSI_STCR_TEFS
| SSI_STCR_TXBIT0
;
102 case SND_SOC_DAIFMT_LEFT_J
:
103 /* data on rising edge of bclk, frame high with data */
104 strcr
|= SSI_STCR_TXBIT0
;
106 case SND_SOC_DAIFMT_DSP_B
:
107 /* data on rising edge of bclk, frame high with data */
108 strcr
|= SSI_STCR_TFSL
;
110 case SND_SOC_DAIFMT_DSP_A
:
111 /* data on rising edge of bclk, frame high 1clk before data */
112 strcr
|= SSI_STCR_TFSL
| SSI_STCR_TEFS
;
116 /* DAI clock inversion */
117 switch (fmt
& SND_SOC_DAIFMT_INV_MASK
) {
118 case SND_SOC_DAIFMT_IB_IF
:
119 strcr
|= SSI_STCR_TFSI
;
120 strcr
&= ~SSI_STCR_TSCKP
;
122 case SND_SOC_DAIFMT_IB_NF
:
123 strcr
&= ~(SSI_STCR_TSCKP
| SSI_STCR_TFSI
);
125 case SND_SOC_DAIFMT_NB_IF
:
126 strcr
|= SSI_STCR_TFSI
| SSI_STCR_TSCKP
;
128 case SND_SOC_DAIFMT_NB_NF
:
129 strcr
&= ~SSI_STCR_TFSI
;
130 strcr
|= SSI_STCR_TSCKP
;
134 /* DAI clock master masks */
135 switch (fmt
& SND_SOC_DAIFMT_MASTER_MASK
) {
136 case SND_SOC_DAIFMT_CBM_CFM
:
139 /* Master mode not implemented, needs handling of clocks. */
143 strcr
|= SSI_STCR_TFEN0
;
145 writel(strcr
, ssi
->base
+ SSI_STCR
);
146 writel(strcr
, ssi
->base
+ SSI_SRCR
);
147 writel(scr
, ssi
->base
+ SSI_SCR
);
153 * SSI system clock configuration.
154 * Should only be called when port is inactive (i.e. SSIEN = 0).
156 static int imx_ssi_set_dai_sysclk(struct snd_soc_dai
*cpu_dai
,
157 int clk_id
, unsigned int freq
, int dir
)
159 struct imx_ssi
*ssi
= cpu_dai
->private_data
;
162 scr
= readl(ssi
->base
+ SSI_SCR
);
165 case IMX_SSP_SYS_CLK
:
166 if (dir
== SND_SOC_CLOCK_OUT
)
167 scr
|= SSI_SCR_SYS_CLK_EN
;
169 scr
&= ~SSI_SCR_SYS_CLK_EN
;
175 writel(scr
, ssi
->base
+ SSI_SCR
);
182 * Should only be called when port is inactive (i.e. SSIEN = 0).
184 static int imx_ssi_set_dai_clkdiv(struct snd_soc_dai
*cpu_dai
,
187 struct imx_ssi
*ssi
= cpu_dai
->private_data
;
190 stccr
= readl(ssi
->base
+ SSI_STCCR
);
191 srccr
= readl(ssi
->base
+ SSI_SRCCR
);
194 case IMX_SSI_TX_DIV_2
:
195 stccr
&= ~SSI_STCCR_DIV2
;
198 case IMX_SSI_TX_DIV_PSR
:
199 stccr
&= ~SSI_STCCR_PSR
;
202 case IMX_SSI_TX_DIV_PM
:
204 stccr
|= SSI_STCCR_PM(div
);
206 case IMX_SSI_RX_DIV_2
:
207 stccr
&= ~SSI_STCCR_DIV2
;
210 case IMX_SSI_RX_DIV_PSR
:
211 stccr
&= ~SSI_STCCR_PSR
;
214 case IMX_SSI_RX_DIV_PM
:
216 stccr
|= SSI_STCCR_PM(div
);
222 writel(stccr
, ssi
->base
+ SSI_STCCR
);
223 writel(srccr
, ssi
->base
+ SSI_SRCCR
);
229 * Should only be called when port is inactive (i.e. SSIEN = 0),
230 * although can be called multiple times by upper layers.
232 static int imx_ssi_hw_params(struct snd_pcm_substream
*substream
,
233 struct snd_pcm_hw_params
*params
,
234 struct snd_soc_dai
*cpu_dai
)
236 struct imx_ssi
*ssi
= cpu_dai
->private_data
;
240 if (substream
->stream
== SNDRV_PCM_STREAM_PLAYBACK
) {
242 cpu_dai
->dma_data
= &ssi
->dma_params_tx
;
245 cpu_dai
->dma_data
= &ssi
->dma_params_rx
;
248 sccr
= readl(ssi
->base
+ reg
) & ~SSI_STCCR_WL_MASK
;
250 /* DAI data (word) size */
251 switch (params_format(params
)) {
252 case SNDRV_PCM_FORMAT_S16_LE
:
253 sccr
|= SSI_SRCCR_WL(16);
255 case SNDRV_PCM_FORMAT_S20_3LE
:
256 sccr
|= SSI_SRCCR_WL(20);
258 case SNDRV_PCM_FORMAT_S24_LE
:
259 sccr
|= SSI_SRCCR_WL(24);
263 writel(sccr
, ssi
->base
+ reg
);
268 static int imx_ssi_trigger(struct snd_pcm_substream
*substream
, int cmd
,
269 struct snd_soc_dai
*dai
)
271 struct snd_soc_pcm_runtime
*rtd
= substream
->private_data
;
272 struct snd_soc_dai
*cpu_dai
= rtd
->dai
->cpu_dai
;
273 struct imx_ssi
*ssi
= cpu_dai
->private_data
;
274 unsigned int sier_bits
, sier
;
277 scr
= readl(ssi
->base
+ SSI_SCR
);
278 sier
= readl(ssi
->base
+ SSI_SIER
);
280 if (substream
->stream
== SNDRV_PCM_STREAM_PLAYBACK
) {
281 if (ssi
->flags
& IMX_SSI_DMA
)
282 sier_bits
= SSI_SIER_TDMAE
;
284 sier_bits
= SSI_SIER_TIE
| SSI_SIER_TFE0_EN
;
286 if (ssi
->flags
& IMX_SSI_DMA
)
287 sier_bits
= SSI_SIER_RDMAE
;
289 sier_bits
= SSI_SIER_RIE
| SSI_SIER_RFF0_EN
;
293 case SNDRV_PCM_TRIGGER_START
:
294 case SNDRV_PCM_TRIGGER_RESUME
:
295 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE
:
296 if (substream
->stream
== SNDRV_PCM_STREAM_PLAYBACK
)
302 if (++ssi
->enabled
== 1)
303 scr
|= SSI_SCR_SSIEN
;
307 case SNDRV_PCM_TRIGGER_STOP
:
308 case SNDRV_PCM_TRIGGER_SUSPEND
:
309 case SNDRV_PCM_TRIGGER_PAUSE_PUSH
:
310 if (substream
->stream
== SNDRV_PCM_STREAM_PLAYBACK
)
316 if (--ssi
->enabled
== 0)
317 scr
&= ~SSI_SCR_SSIEN
;
324 if (!(ssi
->flags
& IMX_SSI_USE_AC97
))
325 /* rx/tx are always enabled to access ac97 registers */
326 writel(scr
, ssi
->base
+ SSI_SCR
);
328 writel(sier
, ssi
->base
+ SSI_SIER
);
333 static struct snd_soc_dai_ops imx_ssi_pcm_dai_ops
= {
334 .hw_params
= imx_ssi_hw_params
,
335 .set_fmt
= imx_ssi_set_dai_fmt
,
336 .set_clkdiv
= imx_ssi_set_dai_clkdiv
,
337 .set_sysclk
= imx_ssi_set_dai_sysclk
,
338 .set_tdm_slot
= imx_ssi_set_dai_tdm_slot
,
339 .trigger
= imx_ssi_trigger
,
342 static struct snd_soc_dai imx_ssi_dai
= {
346 .rates
= SNDRV_PCM_RATE_8000_96000
,
347 .formats
= SNDRV_PCM_FMTBIT_S16_LE
,
352 .rates
= SNDRV_PCM_RATE_8000_96000
,
353 .formats
= SNDRV_PCM_FMTBIT_S16_LE
,
355 .ops
= &imx_ssi_pcm_dai_ops
,
358 int snd_imx_pcm_mmap(struct snd_pcm_substream
*substream
,
359 struct vm_area_struct
*vma
)
361 struct snd_pcm_runtime
*runtime
= substream
->runtime
;
364 ret
= dma_mmap_coherent(NULL
, vma
, runtime
->dma_area
,
365 runtime
->dma_addr
, runtime
->dma_bytes
);
367 pr_debug("%s: ret: %d %p 0x%08x 0x%08x\n", __func__
, ret
,
374 static int imx_pcm_preallocate_dma_buffer(struct snd_pcm
*pcm
, int stream
)
376 struct snd_pcm_substream
*substream
= pcm
->streams
[stream
].substream
;
377 struct snd_dma_buffer
*buf
= &substream
->dma_buffer
;
378 size_t size
= IMX_SSI_DMABUF_SIZE
;
380 buf
->dev
.type
= SNDRV_DMA_TYPE_DEV
;
381 buf
->dev
.dev
= pcm
->card
->dev
;
382 buf
->private_data
= NULL
;
383 buf
->area
= dma_alloc_writecombine(pcm
->card
->dev
, size
,
384 &buf
->addr
, GFP_KERNEL
);
392 static u64 imx_pcm_dmamask
= DMA_BIT_MASK(32);
394 int imx_pcm_new(struct snd_card
*card
, struct snd_soc_dai
*dai
,
400 if (!card
->dev
->dma_mask
)
401 card
->dev
->dma_mask
= &imx_pcm_dmamask
;
402 if (!card
->dev
->coherent_dma_mask
)
403 card
->dev
->coherent_dma_mask
= DMA_BIT_MASK(32);
404 if (dai
->playback
.channels_min
) {
405 ret
= imx_pcm_preallocate_dma_buffer(pcm
,
406 SNDRV_PCM_STREAM_PLAYBACK
);
411 if (dai
->capture
.channels_min
) {
412 ret
= imx_pcm_preallocate_dma_buffer(pcm
,
413 SNDRV_PCM_STREAM_CAPTURE
);
422 void imx_pcm_free(struct snd_pcm
*pcm
)
424 struct snd_pcm_substream
*substream
;
425 struct snd_dma_buffer
*buf
;
428 for (stream
= 0; stream
< 2; stream
++) {
429 substream
= pcm
->streams
[stream
].substream
;
433 buf
= &substream
->dma_buffer
;
437 dma_free_writecombine(pcm
->card
->dev
, buf
->bytes
,
438 buf
->area
, buf
->addr
);
443 struct snd_soc_platform imx_soc_platform
= {
446 EXPORT_SYMBOL_GPL(imx_soc_platform
);
448 static struct snd_soc_dai imx_ac97_dai
= {
452 .stream_name
= "AC97 Playback",
455 .rates
= SNDRV_PCM_RATE_48000
,
456 .formats
= SNDRV_PCM_FMTBIT_S16_LE
,
459 .stream_name
= "AC97 Capture",
462 .rates
= SNDRV_PCM_RATE_48000
,
463 .formats
= SNDRV_PCM_FMTBIT_S16_LE
,
465 .ops
= &imx_ssi_pcm_dai_ops
,
468 static void setup_channel_to_ac97(struct imx_ssi
*imx_ssi
)
470 void __iomem
*base
= imx_ssi
->base
;
472 writel(0x0, base
+ SSI_SCR
);
473 writel(0x0, base
+ SSI_STCR
);
474 writel(0x0, base
+ SSI_SRCR
);
476 writel(SSI_SCR_SYN
| SSI_SCR_NET
, base
+ SSI_SCR
);
478 writel(SSI_SFCSR_RFWM0(8) |
481 SSI_SFCSR_TFWM1(8), base
+ SSI_SFCSR
);
483 writel(SSI_STCCR_WL(16) | SSI_STCCR_DC(12), base
+ SSI_STCCR
);
484 writel(SSI_STCCR_WL(16) | SSI_STCCR_DC(12), base
+ SSI_SRCCR
);
486 writel(SSI_SCR_SYN
| SSI_SCR_NET
| SSI_SCR_SSIEN
, base
+ SSI_SCR
);
487 writel(SSI_SOR_WAIT(3), base
+ SSI_SOR
);
489 writel(SSI_SCR_SYN
| SSI_SCR_NET
| SSI_SCR_SSIEN
|
490 SSI_SCR_TE
| SSI_SCR_RE
,
493 writel(SSI_SACNT_DEFAULT
, base
+ SSI_SACNT
);
494 writel(0xff, base
+ SSI_SACCDIS
);
495 writel(0x300, base
+ SSI_SACCEN
);
498 static struct imx_ssi
*ac97_ssi
;
500 static void imx_ssi_ac97_write(struct snd_ac97
*ac97
, unsigned short reg
,
503 struct imx_ssi
*imx_ssi
= ac97_ssi
;
504 void __iomem
*base
= imx_ssi
->base
;
511 pr_debug("%s: 0x%02x 0x%04x\n", __func__
, reg
, val
);
514 writel(lreg
, base
+ SSI_SACADD
);
517 writel(lval
, base
+ SSI_SACDAT
);
519 writel(SSI_SACNT_DEFAULT
| SSI_SACNT_WR
, base
+ SSI_SACNT
);
523 static unsigned short imx_ssi_ac97_read(struct snd_ac97
*ac97
,
526 struct imx_ssi
*imx_ssi
= ac97_ssi
;
527 void __iomem
*base
= imx_ssi
->base
;
529 unsigned short val
= -1;
532 lreg
= (reg
& 0x7f) << 12 ;
533 writel(lreg
, base
+ SSI_SACADD
);
534 writel(SSI_SACNT_DEFAULT
| SSI_SACNT_RD
, base
+ SSI_SACNT
);
538 val
= (readl(base
+ SSI_SACDAT
) >> 4) & 0xffff;
540 pr_debug("%s: 0x%02x 0x%04x\n", __func__
, reg
, val
);
545 static void imx_ssi_ac97_reset(struct snd_ac97
*ac97
)
547 struct imx_ssi
*imx_ssi
= ac97_ssi
;
549 if (imx_ssi
->ac97_reset
)
550 imx_ssi
->ac97_reset(ac97
);
553 static void imx_ssi_ac97_warm_reset(struct snd_ac97
*ac97
)
555 struct imx_ssi
*imx_ssi
= ac97_ssi
;
557 if (imx_ssi
->ac97_warm_reset
)
558 imx_ssi
->ac97_warm_reset(ac97
);
561 struct snd_ac97_bus_ops soc_ac97_ops
= {
562 .read
= imx_ssi_ac97_read
,
563 .write
= imx_ssi_ac97_write
,
564 .reset
= imx_ssi_ac97_reset
,
565 .warm_reset
= imx_ssi_ac97_warm_reset
567 EXPORT_SYMBOL_GPL(soc_ac97_ops
);
569 struct snd_soc_dai imx_ssi_pcm_dai
[2];
570 EXPORT_SYMBOL_GPL(imx_ssi_pcm_dai
);
572 static int imx_ssi_probe(struct platform_device
*pdev
)
574 struct resource
*res
;
576 struct imx_ssi_platform_data
*pdata
= pdev
->dev
.platform_data
;
577 struct snd_soc_platform
*platform
;
580 struct snd_soc_dai
*dai
= &imx_ssi_pcm_dai
[pdev
->id
];
582 if (dai
->id
>= ARRAY_SIZE(imx_ssi_pcm_dai
))
585 ssi
= kzalloc(sizeof(*ssi
), GFP_KERNEL
);
590 ssi
->ac97_reset
= pdata
->ac97_reset
;
591 ssi
->ac97_warm_reset
= pdata
->ac97_warm_reset
;
592 ssi
->flags
= pdata
->flags
;
595 ssi
->irq
= platform_get_irq(pdev
, 0);
597 ssi
->clk
= clk_get(&pdev
->dev
, NULL
);
598 if (IS_ERR(ssi
->clk
)) {
599 ret
= PTR_ERR(ssi
->clk
);
600 dev_err(&pdev
->dev
, "Cannot get the clock: %d\n",
604 clk_enable(ssi
->clk
);
606 res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
609 goto failed_get_resource
;
612 if (!request_mem_region(res
->start
, resource_size(res
), DRV_NAME
)) {
613 dev_err(&pdev
->dev
, "request_mem_region failed\n");
615 goto failed_get_resource
;
618 ssi
->base
= ioremap(res
->start
, resource_size(res
));
620 dev_err(&pdev
->dev
, "ioremap failed\n");
625 if (ssi
->flags
& IMX_SSI_USE_AC97
) {
631 setup_channel_to_ac97(ssi
);
632 memcpy(dai
, &imx_ac97_dai
, sizeof(imx_ac97_dai
));
634 memcpy(dai
, &imx_ssi_dai
, sizeof(imx_ssi_dai
));
636 writel(0x0, ssi
->base
+ SSI_SIER
);
638 ssi
->dma_params_rx
.dma_addr
= res
->start
+ SSI_SRX0
;
639 ssi
->dma_params_tx
.dma_addr
= res
->start
+ SSI_STX0
;
641 res
= platform_get_resource_byname(pdev
, IORESOURCE_DMA
, "tx0");
643 ssi
->dma_params_tx
.dma
= res
->start
;
645 res
= platform_get_resource_byname(pdev
, IORESOURCE_DMA
, "rx0");
647 ssi
->dma_params_rx
.dma
= res
->start
;
650 dai
->dev
= &pdev
->dev
;
651 dai
->name
= kasprintf(GFP_KERNEL
, "imx-ssi.%d", pdev
->id
);
652 dai
->private_data
= ssi
;
654 if ((cpu_is_mx27() || cpu_is_mx21()) &&
655 !(ssi
->flags
& IMX_SSI_USE_AC97
)) {
656 ssi
->flags
|= IMX_SSI_DMA
;
657 platform
= imx_ssi_dma_mx2_init(pdev
, ssi
);
659 platform
= imx_ssi_fiq_init(pdev
, ssi
);
661 imx_soc_platform
.pcm_ops
= platform
->pcm_ops
;
662 imx_soc_platform
.pcm_new
= platform
->pcm_new
;
663 imx_soc_platform
.pcm_free
= platform
->pcm_free
;
665 val
= SSI_SFCSR_TFWM0(ssi
->dma_params_tx
.burstsize
) |
666 SSI_SFCSR_RFWM0(ssi
->dma_params_rx
.burstsize
);
667 writel(val
, ssi
->base
+ SSI_SFCSR
);
669 ret
= snd_soc_register_dai(dai
);
671 dev_err(&pdev
->dev
, "register DAI failed\n");
672 goto failed_register
;
675 platform_set_drvdata(pdev
, ssi
);
683 release_mem_region(res
->start
, resource_size(res
));
685 clk_disable(ssi
->clk
);
693 static int __devexit
imx_ssi_remove(struct platform_device
*pdev
)
695 struct resource
*res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
696 struct imx_ssi
*ssi
= platform_get_drvdata(pdev
);
697 struct snd_soc_dai
*dai
= &imx_ssi_pcm_dai
[pdev
->id
];
699 snd_soc_unregister_dai(dai
);
701 if (ssi
->flags
& IMX_SSI_USE_AC97
)
704 if (!(ssi
->flags
& IMX_SSI_DMA
))
705 imx_ssi_fiq_exit(pdev
, ssi
);
708 release_mem_region(res
->start
, resource_size(res
));
709 clk_disable(ssi
->clk
);
716 static struct platform_driver imx_ssi_driver
= {
717 .probe
= imx_ssi_probe
,
718 .remove
= __devexit_p(imx_ssi_remove
),
722 .owner
= THIS_MODULE
,
726 static int __init
imx_ssi_init(void)
730 ret
= snd_soc_register_platform(&imx_soc_platform
);
732 pr_err("failed to register soc platform: %d\n", ret
);
736 ret
= platform_driver_register(&imx_ssi_driver
);
738 snd_soc_unregister_platform(&imx_soc_platform
);
745 static void __exit
imx_ssi_exit(void)
747 platform_driver_unregister(&imx_ssi_driver
);
748 snd_soc_unregister_platform(&imx_soc_platform
);
751 module_init(imx_ssi_init
);
752 module_exit(imx_ssi_exit
);
754 /* Module information */
755 MODULE_AUTHOR("Sascha Hauer, <s.hauer@pengutronix.de>");
756 MODULE_DESCRIPTION("i.MX I2S/ac97 SoC Interface");
757 MODULE_LICENSE("GPL");