2 * at91-i2s.c -- ALSA SoC I2S Audio Layer Platform driver
4 * Author: Frank Mandarino <fmandarino@endrelia.com>
5 * Endrelia Technologies Inc.
7 * Based on pxa2xx Platform drivers by
8 * Liam Girdwood <liam.girdwood@wolfsonmicro.com>
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the
12 * Free Software Foundation; either version 2 of the License, or (at your
13 * option) any later version.
17 #include <linux/init.h>
18 #include <linux/module.h>
19 #include <linux/interrupt.h>
20 #include <linux/device.h>
21 #include <linux/delay.h>
22 #include <linux/clk.h>
23 #include <linux/atmel_pdc.h>
25 #include <sound/driver.h>
26 #include <sound/core.h>
27 #include <sound/pcm.h>
28 #include <sound/initval.h>
29 #include <sound/soc.h>
31 #include <asm/arch/hardware.h>
32 #include <asm/arch/at91_pmc.h>
33 #include <asm/arch/at91_ssc.h>
39 #define DBG(x...) printk(KERN_DEBUG "at91-i2s:" x)
44 #if defined(CONFIG_ARCH_AT91SAM9260)
45 #define NUM_SSC_DEVICES 1
47 #define NUM_SSC_DEVICES 3
52 * SSC PDC registers required by the PCM DMA engine.
54 static struct at91_pdc_regs pdc_tx_reg
= {
57 .xnpr
= ATMEL_PDC_TNPR
,
58 .xncr
= ATMEL_PDC_TNCR
,
61 static struct at91_pdc_regs pdc_rx_reg
= {
64 .xnpr
= ATMEL_PDC_RNPR
,
65 .xncr
= ATMEL_PDC_RNCR
,
69 * SSC & PDC status bits for transmit and receive.
71 static struct at91_ssc_mask ssc_tx_mask
= {
72 .ssc_enable
= AT91_SSC_TXEN
,
73 .ssc_disable
= AT91_SSC_TXDIS
,
74 .ssc_endx
= AT91_SSC_ENDTX
,
75 .ssc_endbuf
= AT91_SSC_TXBUFE
,
76 .pdc_enable
= ATMEL_PDC_TXTEN
,
77 .pdc_disable
= ATMEL_PDC_TXTDIS
,
80 static struct at91_ssc_mask ssc_rx_mask
= {
81 .ssc_enable
= AT91_SSC_RXEN
,
82 .ssc_disable
= AT91_SSC_RXDIS
,
83 .ssc_endx
= AT91_SSC_ENDRX
,
84 .ssc_endbuf
= AT91_SSC_RXBUFF
,
85 .pdc_enable
= ATMEL_PDC_RXTEN
,
86 .pdc_disable
= ATMEL_PDC_RXTDIS
,
93 static struct at91_pcm_dma_params ssc_dma_params
[NUM_SSC_DEVICES
][2] = {
95 .name
= "SSC0/I2S PCM Stereo out",
100 .name
= "SSC0/I2S PCM Stereo in",
102 .mask
= &ssc_rx_mask
,
104 #if NUM_SSC_DEVICES == 3
106 .name
= "SSC1/I2S PCM Stereo out",
108 .mask
= &ssc_tx_mask
,
111 .name
= "SSC1/I2S PCM Stereo in",
113 .mask
= &ssc_rx_mask
,
116 .name
= "SSC2/I2S PCM Stereo out",
118 .mask
= &ssc_tx_mask
,
121 .name
= "SSC1/I2S PCM Stereo in",
123 .mask
= &ssc_rx_mask
,
128 struct at91_ssc_state
{
138 static struct at91_ssc_info
{
140 struct at91_ssc_periph ssc
;
141 spinlock_t lock
; /* lock for dir_mask */
142 unsigned short dir_mask
; /* 0=unused, 1=playback, 2=capture */
143 unsigned short initialized
; /* 1=SSC has been initialized */
144 unsigned short daifmt
;
145 unsigned short cmr_div
;
146 unsigned short tcmr_period
;
147 unsigned short rcmr_period
;
148 struct at91_pcm_dma_params
*dma_params
[2];
149 struct at91_ssc_state ssc_state
;
151 } ssc_info
[NUM_SSC_DEVICES
] = {
154 .lock
= SPIN_LOCK_UNLOCKED
,
158 #if NUM_SSC_DEVICES == 3
161 .lock
= SPIN_LOCK_UNLOCKED
,
167 .lock
= SPIN_LOCK_UNLOCKED
,
174 static unsigned int at91_i2s_sysclk
;
177 * SSC interrupt handler. Passes PDC interrupts to the DMA
178 * interrupt handler in the PCM driver.
180 static irqreturn_t
at91_i2s_interrupt(int irq
, void *dev_id
)
182 struct at91_ssc_info
*ssc_p
= dev_id
;
183 struct at91_pcm_dma_params
*dma_params
;
187 ssc_sr
= at91_ssc_read(ssc_p
->ssc
.base
+ AT91_SSC_SR
)
188 & at91_ssc_read(ssc_p
->ssc
.base
+ AT91_SSC_IMR
);
191 * Loop through the substreams attached to this SSC. If
192 * a DMA-related interrupt occurred on that substream, call
193 * the DMA interrupt handler function, if one has been
194 * registered in the dma_params structure by the PCM driver.
196 for (i
= 0; i
< ARRAY_SIZE(ssc_p
->dma_params
); i
++) {
197 dma_params
= ssc_p
->dma_params
[i
];
199 if (dma_params
!= NULL
&& dma_params
->dma_intr_handler
!= NULL
&&
201 (dma_params
->mask
->ssc_endx
| dma_params
->mask
->ssc_endbuf
)))
203 dma_params
->dma_intr_handler(ssc_sr
, dma_params
->substream
);
210 * Startup. Only that one substream allowed in each direction.
212 static int at91_i2s_startup(struct snd_pcm_substream
*substream
)
214 struct snd_soc_pcm_runtime
*rtd
= substream
->private_data
;
215 struct at91_ssc_info
*ssc_p
= &ssc_info
[rtd
->dai
->cpu_dai
->id
];
218 DBG("i2s_startup: SSC_SR=0x%08lx\n",
219 at91_ssc_read(ssc_p
->ssc
.base
+ AT91_SSC_SR
));
220 dir_mask
= substream
->stream
== SNDRV_PCM_STREAM_PLAYBACK
? 0x1 : 0x2;
222 spin_lock_irq(&ssc_p
->lock
);
223 if (ssc_p
->dir_mask
& dir_mask
) {
224 spin_unlock_irq(&ssc_p
->lock
);
227 ssc_p
->dir_mask
|= dir_mask
;
228 spin_unlock_irq(&ssc_p
->lock
);
234 * Shutdown. Clear DMA parameters and shutdown the SSC if there
235 * are no other substreams open.
237 static void at91_i2s_shutdown(struct snd_pcm_substream
*substream
)
239 struct snd_soc_pcm_runtime
*rtd
= substream
->private_data
;
240 struct at91_ssc_info
*ssc_p
= &ssc_info
[rtd
->dai
->cpu_dai
->id
];
241 struct at91_pcm_dma_params
*dma_params
;
244 dir
= substream
->stream
== SNDRV_PCM_STREAM_PLAYBACK
? 0 : 1;
245 dma_params
= ssc_p
->dma_params
[dir
];
247 if (dma_params
!= NULL
) {
248 at91_ssc_write(dma_params
->ssc_base
+ AT91_SSC_CR
,
249 dma_params
->mask
->ssc_disable
);
250 DBG("%s disabled SSC_SR=0x%08lx\n", (dir
? "receive" : "transmit"),
251 at91_ssc_read(ssc_p
->ssc
.base
+ AT91_SSC_SR
));
253 dma_params
->ssc_base
= NULL
;
254 dma_params
->substream
= NULL
;
255 ssc_p
->dma_params
[dir
] = NULL
;
260 spin_lock_irq(&ssc_p
->lock
);
261 ssc_p
->dir_mask
&= ~dir_mask
;
262 if (!ssc_p
->dir_mask
) {
263 /* Shutdown the SSC clock. */
264 DBG("Stopping pid %d clock\n", ssc_p
->ssc
.pid
);
265 at91_sys_write(AT91_PMC_PCDR
, 1<<ssc_p
->ssc
.pid
);
267 if (ssc_p
->initialized
) {
268 free_irq(ssc_p
->ssc
.pid
, ssc_p
);
269 ssc_p
->initialized
= 0;
273 at91_ssc_write(ssc_p
->ssc
.base
+ AT91_SSC_CR
, AT91_SSC_SWRST
);
275 /* Clear the SSC dividers */
276 ssc_p
->cmr_div
= ssc_p
->tcmr_period
= ssc_p
->rcmr_period
= 0;
278 spin_unlock_irq(&ssc_p
->lock
);
282 * Record the SSC system clock rate.
284 static int at91_i2s_set_dai_sysclk(struct snd_soc_cpu_dai
*cpu_dai
,
285 int clk_id
, unsigned int freq
, int dir
)
288 * The only clock supplied to the SSC is the AT91 master clock,
289 * which is only used if the SSC is generating BCLK and/or
293 case AT91_SYSCLK_MCK
:
294 at91_i2s_sysclk
= freq
;
304 * Record the DAI format for use in hw_params().
306 static int at91_i2s_set_dai_fmt(struct snd_soc_cpu_dai
*cpu_dai
,
309 struct at91_ssc_info
*ssc_p
= &ssc_info
[cpu_dai
->id
];
311 if ((fmt
& SND_SOC_DAIFMT_FORMAT_MASK
) != SND_SOC_DAIFMT_I2S
)
319 * Record SSC clock dividers for use in hw_params().
321 static int at91_i2s_set_dai_clkdiv(struct snd_soc_cpu_dai
*cpu_dai
,
324 struct at91_ssc_info
*ssc_p
= &ssc_info
[cpu_dai
->id
];
327 case AT91SSC_CMR_DIV
:
329 * The same master clock divider is used for both
330 * transmit and receive, so if a value has already
331 * been set, it must match this value.
333 if (ssc_p
->cmr_div
== 0)
334 ssc_p
->cmr_div
= div
;
336 if (div
!= ssc_p
->cmr_div
)
340 case AT91SSC_TCMR_PERIOD
:
341 ssc_p
->tcmr_period
= div
;
344 case AT91SSC_RCMR_PERIOD
:
345 ssc_p
->rcmr_period
= div
;
358 static int at91_i2s_hw_params(struct snd_pcm_substream
*substream
,
359 struct snd_pcm_hw_params
*params
)
361 struct snd_soc_pcm_runtime
*rtd
= substream
->private_data
;
362 int id
= rtd
->dai
->cpu_dai
->id
;
363 struct at91_ssc_info
*ssc_p
= &ssc_info
[id
];
364 struct at91_pcm_dma_params
*dma_params
;
365 int dir
, channels
, bits
;
366 u32 tfmr
, rfmr
, tcmr
, rcmr
;
371 * Currently, there is only one set of dma params for
372 * each direction. If more are added, this code will
373 * have to be changed to select the proper set.
375 dir
= substream
->stream
== SNDRV_PCM_STREAM_PLAYBACK
? 0 : 1;
377 dma_params
= &ssc_dma_params
[id
][dir
];
378 dma_params
->ssc_base
= ssc_p
->ssc
.base
;
379 dma_params
->substream
= substream
;
381 ssc_p
->dma_params
[dir
] = dma_params
;
384 * The cpu_dai->dma_data field is only used to communicate the
385 * appropriate DMA parameters to the pcm driver hw_params()
386 * function. It should not be used for other purposes
387 * as it is common to all substreams.
389 rtd
->dai
->cpu_dai
->dma_data
= dma_params
;
391 channels
= params_channels(params
);
394 * The SSC only supports up to 16-bit samples in I2S format, due
395 * to the size of the Frame Mode Register FSLEN field. Also, I2S
396 * implies signed data.
399 dma_params
->pdc_xfer_size
= 2;
402 * Compute SSC register settings.
404 switch (ssc_p
->daifmt
) {
405 case SND_SOC_DAIFMT_CBS_CFS
:
407 * SSC provides BCLK and LRC clocks.
409 * The SSC transmit and receive clocks are generated from the
410 * MCK divider, and the BCLK signal is output on the SSC TK line.
412 rcmr
= (( ssc_p
->rcmr_period
<< 24) & AT91_SSC_PERIOD
)
413 | (( 1 << 16) & AT91_SSC_STTDLY
)
414 | (( AT91_SSC_START_FALLING_RF
) & AT91_SSC_START
)
415 | (( AT91_SSC_CK_RISING
) & AT91_SSC_CKI
)
416 | (( AT91_SSC_CKO_NONE
) & AT91_SSC_CKO
)
417 | (( AT91_SSC_CKS_DIV
) & AT91_SSC_CKS
);
419 rfmr
= (( AT91_SSC_FSEDGE_POSITIVE
) & AT91_SSC_FSEDGE
)
420 | (( AT91_SSC_FSOS_NEGATIVE
) & AT91_SSC_FSOS
)
421 | (((bits
- 1) << 16) & AT91_SSC_FSLEN
)
422 | (((channels
- 1) << 8) & AT91_SSC_DATNB
)
423 | (( 1 << 7) & AT91_SSC_MSBF
)
424 | (( 0 << 5) & AT91_SSC_LOOP
)
425 | (((bits
- 1) << 0) & AT91_SSC_DATALEN
);
427 tcmr
= (( ssc_p
->tcmr_period
<< 24) & AT91_SSC_PERIOD
)
428 | (( 1 << 16) & AT91_SSC_STTDLY
)
429 | (( AT91_SSC_START_FALLING_RF
) & AT91_SSC_START
)
430 | (( AT91_SSC_CKI_FALLING
) & AT91_SSC_CKI
)
431 | (( AT91_SSC_CKO_CONTINUOUS
) & AT91_SSC_CKO
)
432 | (( AT91_SSC_CKS_DIV
) & AT91_SSC_CKS
);
434 tfmr
= (( AT91_SSC_FSEDGE_POSITIVE
) & AT91_SSC_FSEDGE
)
435 | (( 0 << 23) & AT91_SSC_FSDEN
)
436 | (( AT91_SSC_FSOS_NEGATIVE
) & AT91_SSC_FSOS
)
437 | (((bits
- 1) << 16) & AT91_SSC_FSLEN
)
438 | (((channels
- 1) << 8) & AT91_SSC_DATNB
)
439 | (( 1 << 7) & AT91_SSC_MSBF
)
440 | (( 0 << 5) & AT91_SSC_DATDEF
)
441 | (((bits
- 1) << 0) & AT91_SSC_DATALEN
);
444 case SND_SOC_DAIFMT_CBM_CFM
:
447 * CODEC supplies BCLK and LRC clocks.
449 * The SSC transmit clock is obtained from the BCLK signal on
450 * on the TK line, and the SSC receive clock is generated from the
453 * For single channel data, one sample is transferred on the falling
454 * edge of the LRC clock. For two channel data, one sample is
455 * transferred on both edges of the LRC clock.
457 start_event
= channels
== 1
458 ? AT91_SSC_START_FALLING_RF
459 : AT91_SSC_START_EDGE_RF
;
461 rcmr
= (( 0 << 24) & AT91_SSC_PERIOD
)
462 | (( 1 << 16) & AT91_SSC_STTDLY
)
463 | (( start_event
) & AT91_SSC_START
)
464 | (( AT91_SSC_CK_RISING
) & AT91_SSC_CKI
)
465 | (( AT91_SSC_CKO_NONE
) & AT91_SSC_CKO
)
466 | (( AT91_SSC_CKS_CLOCK
) & AT91_SSC_CKS
);
468 rfmr
= (( AT91_SSC_FSEDGE_POSITIVE
) & AT91_SSC_FSEDGE
)
469 | (( AT91_SSC_FSOS_NONE
) & AT91_SSC_FSOS
)
470 | (( 0 << 16) & AT91_SSC_FSLEN
)
471 | (( 0 << 8) & AT91_SSC_DATNB
)
472 | (( 1 << 7) & AT91_SSC_MSBF
)
473 | (( 0 << 5) & AT91_SSC_LOOP
)
474 | (((bits
- 1) << 0) & AT91_SSC_DATALEN
);
476 tcmr
= (( 0 << 24) & AT91_SSC_PERIOD
)
477 | (( 1 << 16) & AT91_SSC_STTDLY
)
478 | (( start_event
) & AT91_SSC_START
)
479 | (( AT91_SSC_CKI_FALLING
) & AT91_SSC_CKI
)
480 | (( AT91_SSC_CKO_NONE
) & AT91_SSC_CKO
)
481 | (( AT91_SSC_CKS_PIN
) & AT91_SSC_CKS
);
483 tfmr
= (( AT91_SSC_FSEDGE_POSITIVE
) & AT91_SSC_FSEDGE
)
484 | (( 0 << 23) & AT91_SSC_FSDEN
)
485 | (( AT91_SSC_FSOS_NONE
) & AT91_SSC_FSOS
)
486 | (( 0 << 16) & AT91_SSC_FSLEN
)
487 | (( 0 << 8) & AT91_SSC_DATNB
)
488 | (( 1 << 7) & AT91_SSC_MSBF
)
489 | (( 0 << 5) & AT91_SSC_DATDEF
)
490 | (((bits
- 1) << 0) & AT91_SSC_DATALEN
);
493 case SND_SOC_DAIFMT_CBS_CFM
:
494 case SND_SOC_DAIFMT_CBM_CFS
:
496 printk(KERN_WARNING
"at91-i2s: unsupported DAI format 0x%x.\n",
501 DBG("RCMR=%08x RFMR=%08x TCMR=%08x TFMR=%08x\n", rcmr
, rfmr
, tcmr
, tfmr
);
503 if (!ssc_p
->initialized
) {
505 /* Enable PMC peripheral clock for this SSC */
506 DBG("Starting pid %d clock\n", ssc_p
->ssc
.pid
);
507 at91_sys_write(AT91_PMC_PCER
, 1<<ssc_p
->ssc
.pid
);
509 /* Reset the SSC and its PDC registers */
510 at91_ssc_write(ssc_p
->ssc
.base
+ AT91_SSC_CR
, AT91_SSC_SWRST
);
512 at91_ssc_write(ssc_p
->ssc
.base
+ ATMEL_PDC_RPR
, 0);
513 at91_ssc_write(ssc_p
->ssc
.base
+ ATMEL_PDC_RCR
, 0);
514 at91_ssc_write(ssc_p
->ssc
.base
+ ATMEL_PDC_RNPR
, 0);
515 at91_ssc_write(ssc_p
->ssc
.base
+ ATMEL_PDC_RNCR
, 0);
516 at91_ssc_write(ssc_p
->ssc
.base
+ ATMEL_PDC_TPR
, 0);
517 at91_ssc_write(ssc_p
->ssc
.base
+ ATMEL_PDC_TCR
, 0);
518 at91_ssc_write(ssc_p
->ssc
.base
+ ATMEL_PDC_TNPR
, 0);
519 at91_ssc_write(ssc_p
->ssc
.base
+ ATMEL_PDC_TNCR
, 0);
521 if ((ret
= request_irq(ssc_p
->ssc
.pid
, at91_i2s_interrupt
,
522 0, ssc_p
->name
, ssc_p
)) < 0) {
523 printk(KERN_WARNING
"at91-i2s: request_irq failure\n");
525 DBG("Stopping pid %d clock\n", ssc_p
->ssc
.pid
);
526 at91_sys_write(AT91_PMC_PCER
, 1<<ssc_p
->ssc
.pid
);
530 ssc_p
->initialized
= 1;
533 /* set SSC clock mode register */
534 at91_ssc_write(ssc_p
->ssc
.base
+ AT91_SSC_CMR
, ssc_p
->cmr_div
);
536 /* set receive clock mode and format */
537 at91_ssc_write(ssc_p
->ssc
.base
+ AT91_SSC_RCMR
, rcmr
);
538 at91_ssc_write(ssc_p
->ssc
.base
+ AT91_SSC_RFMR
, rfmr
);
540 /* set transmit clock mode and format */
541 at91_ssc_write(ssc_p
->ssc
.base
+ AT91_SSC_TCMR
, tcmr
);
542 at91_ssc_write(ssc_p
->ssc
.base
+ AT91_SSC_TFMR
, tfmr
);
544 DBG("hw_params: SSC initialized\n");
549 static int at91_i2s_prepare(struct snd_pcm_substream
*substream
)
551 struct snd_soc_pcm_runtime
*rtd
= substream
->private_data
;
552 struct at91_ssc_info
*ssc_p
= &ssc_info
[rtd
->dai
->cpu_dai
->id
];
553 struct at91_pcm_dma_params
*dma_params
;
556 dir
= substream
->stream
== SNDRV_PCM_STREAM_PLAYBACK
? 0 : 1;
557 dma_params
= ssc_p
->dma_params
[dir
];
559 at91_ssc_write(dma_params
->ssc_base
+ AT91_SSC_CR
,
560 dma_params
->mask
->ssc_enable
);
562 DBG("%s enabled SSC_SR=0x%08lx\n", dir
? "receive" : "transmit",
563 at91_ssc_read(dma_params
->ssc_base
+ AT91_SSC_SR
));
569 static int at91_i2s_suspend(struct platform_device
*pdev
,
570 struct snd_soc_cpu_dai
*cpu_dai
)
572 struct at91_ssc_info
*ssc_p
;
577 ssc_p
= &ssc_info
[cpu_dai
->id
];
579 /* Save the status register before disabling transmit and receive. */
580 ssc_p
->ssc_state
.ssc_sr
= at91_ssc_read(ssc_p
->ssc
.base
+ AT91_SSC_SR
);
581 at91_ssc_write(ssc_p
->ssc
.base
+ AT91_SSC_CR
,
582 AT91_SSC_TXDIS
| AT91_SSC_RXDIS
);
584 /* Save the current interrupt mask, then disable unmasked interrupts. */
585 ssc_p
->ssc_state
.ssc_imr
= at91_ssc_read(ssc_p
->ssc
.base
+ AT91_SSC_IMR
);
586 at91_ssc_write(ssc_p
->ssc
.base
+ AT91_SSC_IDR
, ssc_p
->ssc_state
.ssc_imr
);
588 ssc_p
->ssc_state
.ssc_cmr
= at91_ssc_read(ssc_p
->ssc
.base
+ AT91_SSC_CMR
);
589 ssc_p
->ssc_state
.ssc_rcmr
= at91_ssc_read(ssc_p
->ssc
.base
+ AT91_SSC_RCMR
);
590 ssc_p
->ssc_state
.ssc_rfmr
= at91_ssc_read(ssc_p
->ssc
.base
+ AT91_SSC_RFMR
);
591 ssc_p
->ssc_state
.ssc_tcmr
= at91_ssc_read(ssc_p
->ssc
.base
+ AT91_SSC_TCMR
);
592 ssc_p
->ssc_state
.ssc_tfmr
= at91_ssc_read(ssc_p
->ssc
.base
+ AT91_SSC_TFMR
);
597 static int at91_i2s_resume(struct platform_device
*pdev
,
598 struct snd_soc_cpu_dai
*cpu_dai
)
600 struct at91_ssc_info
*ssc_p
;
605 ssc_p
= &ssc_info
[cpu_dai
->id
];
607 at91_ssc_write(ssc_p
->ssc
.base
+ AT91_SSC_TFMR
, ssc_p
->ssc_state
.ssc_tfmr
);
608 at91_ssc_write(ssc_p
->ssc
.base
+ AT91_SSC_TCMR
, ssc_p
->ssc_state
.ssc_tcmr
);
609 at91_ssc_write(ssc_p
->ssc
.base
+ AT91_SSC_RFMR
, ssc_p
->ssc_state
.ssc_rfmr
);
610 at91_ssc_write(ssc_p
->ssc
.base
+ AT91_SSC_RCMR
, ssc_p
->ssc_state
.ssc_rcmr
);
611 at91_ssc_write(ssc_p
->ssc
.base
+ AT91_SSC_CMR
, ssc_p
->ssc_state
.ssc_cmr
);
613 at91_ssc_write(ssc_p
->ssc
.base
+ AT91_SSC_IER
, ssc_p
->ssc_state
.ssc_imr
);
615 at91_ssc_write(ssc_p
->ssc
.base
+ AT91_SSC_CR
,
616 ((ssc_p
->ssc_state
.ssc_sr
& AT91_SSC_RXENA
) ? AT91_SSC_RXEN
: 0) |
617 ((ssc_p
->ssc_state
.ssc_sr
& AT91_SSC_TXENA
) ? AT91_SSC_TXEN
: 0));
623 #define at91_i2s_suspend NULL
624 #define at91_i2s_resume NULL
627 #define AT91_I2S_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
628 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |\
629 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |\
630 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 |\
631 SNDRV_PCM_RATE_96000)
633 struct snd_soc_cpu_dai at91_i2s_dai
[NUM_SSC_DEVICES
] = {
634 { .name
= "at91_ssc0/i2s",
636 .type
= SND_SOC_DAI_I2S
,
637 .suspend
= at91_i2s_suspend
,
638 .resume
= at91_i2s_resume
,
642 .rates
= AT91_I2S_RATES
,
643 .formats
= SNDRV_PCM_FMTBIT_S16_LE
,},
647 .rates
= AT91_I2S_RATES
,
648 .formats
= SNDRV_PCM_FMTBIT_S16_LE
,},
650 .startup
= at91_i2s_startup
,
651 .shutdown
= at91_i2s_shutdown
,
652 .prepare
= at91_i2s_prepare
,
653 .hw_params
= at91_i2s_hw_params
,},
655 .set_sysclk
= at91_i2s_set_dai_sysclk
,
656 .set_fmt
= at91_i2s_set_dai_fmt
,
657 .set_clkdiv
= at91_i2s_set_dai_clkdiv
,},
658 .private_data
= &ssc_info
[0].ssc
,
660 #if NUM_SSC_DEVICES == 3
661 { .name
= "at91_ssc1/i2s",
663 .type
= SND_SOC_DAI_I2S
,
664 .suspend
= at91_i2s_suspend
,
665 .resume
= at91_i2s_resume
,
669 .rates
= AT91_I2S_RATES
,
670 .formats
= SNDRV_PCM_FMTBIT_S16_LE
,},
674 .rates
= AT91_I2S_RATES
,
675 .formats
= SNDRV_PCM_FMTBIT_S16_LE
,},
677 .startup
= at91_i2s_startup
,
678 .shutdown
= at91_i2s_shutdown
,
679 .prepare
= at91_i2s_prepare
,
680 .hw_params
= at91_i2s_hw_params
,},
682 .set_sysclk
= at91_i2s_set_dai_sysclk
,
683 .set_fmt
= at91_i2s_set_dai_fmt
,
684 .set_clkdiv
= at91_i2s_set_dai_clkdiv
,},
685 .private_data
= &ssc_info
[1].ssc
,
687 { .name
= "at91_ssc2/i2s",
689 .type
= SND_SOC_DAI_I2S
,
690 .suspend
= at91_i2s_suspend
,
691 .resume
= at91_i2s_resume
,
695 .rates
= AT91_I2S_RATES
,
696 .formats
= SNDRV_PCM_FMTBIT_S16_LE
,},
700 .rates
= AT91_I2S_RATES
,
701 .formats
= SNDRV_PCM_FMTBIT_S16_LE
,},
703 .startup
= at91_i2s_startup
,
704 .shutdown
= at91_i2s_shutdown
,
705 .prepare
= at91_i2s_prepare
,
706 .hw_params
= at91_i2s_hw_params
,},
708 .set_sysclk
= at91_i2s_set_dai_sysclk
,
709 .set_fmt
= at91_i2s_set_dai_fmt
,
710 .set_clkdiv
= at91_i2s_set_dai_clkdiv
,},
711 .private_data
= &ssc_info
[2].ssc
,
716 EXPORT_SYMBOL_GPL(at91_i2s_dai
);
718 /* Module information */
719 MODULE_AUTHOR("Frank Mandarino, fmandarino@endrelia.com, www.endrelia.com");
720 MODULE_DESCRIPTION("AT91 I2S ASoC Interface");
721 MODULE_LICENSE("GPL");