2 * at91-ssc.c -- ALSA SoC AT91 SSC 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/pcm_params.h>
29 #include <sound/initval.h>
30 #include <sound/soc.h>
32 #include <asm/arch/hardware.h>
33 #include <asm/arch/at91_pmc.h>
34 #include <asm/arch/at91_ssc.h>
40 #define DBG(x...) printk(KERN_DEBUG "at91-ssc:" x)
45 #if defined(CONFIG_ARCH_AT91SAM9260)
46 #define NUM_SSC_DEVICES 1
48 #define NUM_SSC_DEVICES 3
53 * SSC PDC registers required by the PCM DMA engine.
55 static struct at91_pdc_regs pdc_tx_reg
= {
58 .xnpr
= ATMEL_PDC_TNPR
,
59 .xncr
= ATMEL_PDC_TNCR
,
62 static struct at91_pdc_regs pdc_rx_reg
= {
65 .xnpr
= ATMEL_PDC_RNPR
,
66 .xncr
= ATMEL_PDC_RNCR
,
70 * SSC & PDC status bits for transmit and receive.
72 static struct at91_ssc_mask ssc_tx_mask
= {
73 .ssc_enable
= AT91_SSC_TXEN
,
74 .ssc_disable
= AT91_SSC_TXDIS
,
75 .ssc_endx
= AT91_SSC_ENDTX
,
76 .ssc_endbuf
= AT91_SSC_TXBUFE
,
77 .pdc_enable
= ATMEL_PDC_TXTEN
,
78 .pdc_disable
= ATMEL_PDC_TXTDIS
,
81 static struct at91_ssc_mask ssc_rx_mask
= {
82 .ssc_enable
= AT91_SSC_RXEN
,
83 .ssc_disable
= AT91_SSC_RXDIS
,
84 .ssc_endx
= AT91_SSC_ENDRX
,
85 .ssc_endbuf
= AT91_SSC_RXBUFF
,
86 .pdc_enable
= ATMEL_PDC_RXTEN
,
87 .pdc_disable
= ATMEL_PDC_RXTDIS
,
94 static struct at91_pcm_dma_params ssc_dma_params
[NUM_SSC_DEVICES
][2] = {
96 .name
= "SSC0 PCM out",
101 .name
= "SSC0 PCM in",
103 .mask
= &ssc_rx_mask
,
105 #if NUM_SSC_DEVICES == 3
107 .name
= "SSC1 PCM out",
109 .mask
= &ssc_tx_mask
,
112 .name
= "SSC1 PCM in",
114 .mask
= &ssc_rx_mask
,
117 .name
= "SSC2 PCM out",
119 .mask
= &ssc_tx_mask
,
122 .name
= "SSC2 PCM in",
124 .mask
= &ssc_rx_mask
,
129 struct at91_ssc_state
{
139 static struct at91_ssc_info
{
141 struct at91_ssc_periph ssc
;
142 spinlock_t lock
; /* lock for dir_mask */
143 unsigned short dir_mask
; /* 0=unused, 1=playback, 2=capture */
144 unsigned short initialized
; /* 1=SSC has been initialized */
145 unsigned short daifmt
;
146 unsigned short cmr_div
;
147 unsigned short tcmr_period
;
148 unsigned short rcmr_period
;
149 struct at91_pcm_dma_params
*dma_params
[2];
150 struct at91_ssc_state ssc_state
;
152 } ssc_info
[NUM_SSC_DEVICES
] = {
155 .lock
= __SPIN_LOCK_UNLOCKED(ssc_info
[0].lock
),
159 #if NUM_SSC_DEVICES == 3
162 .lock
= __SPIN_LOCK_UNLOCKED(ssc_info
[1].lock
),
168 .lock
= __SPIN_LOCK_UNLOCKED(ssc_info
[2].lock
),
175 static unsigned int at91_ssc_sysclk
;
178 * SSC interrupt handler. Passes PDC interrupts to the DMA
179 * interrupt handler in the PCM driver.
181 static irqreturn_t
at91_ssc_interrupt(int irq
, void *dev_id
)
183 struct at91_ssc_info
*ssc_p
= dev_id
;
184 struct at91_pcm_dma_params
*dma_params
;
188 ssc_sr
= at91_ssc_read(ssc_p
->ssc
.base
+ AT91_SSC_SR
)
189 & at91_ssc_read(ssc_p
->ssc
.base
+ AT91_SSC_IMR
);
192 * Loop through the substreams attached to this SSC. If
193 * a DMA-related interrupt occurred on that substream, call
194 * the DMA interrupt handler function, if one has been
195 * registered in the dma_params structure by the PCM driver.
197 for (i
= 0; i
< ARRAY_SIZE(ssc_p
->dma_params
); i
++) {
198 dma_params
= ssc_p
->dma_params
[i
];
200 if (dma_params
!= NULL
&& dma_params
->dma_intr_handler
!= NULL
&&
202 (dma_params
->mask
->ssc_endx
| dma_params
->mask
->ssc_endbuf
)))
204 dma_params
->dma_intr_handler(ssc_sr
, dma_params
->substream
);
211 * Startup. Only that one substream allowed in each direction.
213 static int at91_ssc_startup(struct snd_pcm_substream
*substream
)
215 struct snd_soc_pcm_runtime
*rtd
= substream
->private_data
;
216 struct at91_ssc_info
*ssc_p
= &ssc_info
[rtd
->dai
->cpu_dai
->id
];
219 DBG("ssc_startup: SSC_SR=0x%08lx\n",
220 at91_ssc_read(ssc_p
->ssc
.base
+ AT91_SSC_SR
));
221 dir_mask
= substream
->stream
== SNDRV_PCM_STREAM_PLAYBACK
? 0x1 : 0x2;
223 spin_lock_irq(&ssc_p
->lock
);
224 if (ssc_p
->dir_mask
& dir_mask
) {
225 spin_unlock_irq(&ssc_p
->lock
);
228 ssc_p
->dir_mask
|= dir_mask
;
229 spin_unlock_irq(&ssc_p
->lock
);
235 * Shutdown. Clear DMA parameters and shutdown the SSC if there
236 * are no other substreams open.
238 static void at91_ssc_shutdown(struct snd_pcm_substream
*substream
)
240 struct snd_soc_pcm_runtime
*rtd
= substream
->private_data
;
241 struct at91_ssc_info
*ssc_p
= &ssc_info
[rtd
->dai
->cpu_dai
->id
];
242 struct at91_pcm_dma_params
*dma_params
;
245 dir
= substream
->stream
== SNDRV_PCM_STREAM_PLAYBACK
? 0 : 1;
246 dma_params
= ssc_p
->dma_params
[dir
];
248 if (dma_params
!= NULL
) {
249 at91_ssc_write(dma_params
->ssc_base
+ AT91_SSC_CR
,
250 dma_params
->mask
->ssc_disable
);
251 DBG("%s disabled SSC_SR=0x%08lx\n", (dir
? "receive" : "transmit"),
252 at91_ssc_read(ssc_p
->ssc
.base
+ AT91_SSC_SR
));
254 dma_params
->ssc_base
= NULL
;
255 dma_params
->substream
= NULL
;
256 ssc_p
->dma_params
[dir
] = NULL
;
261 spin_lock_irq(&ssc_p
->lock
);
262 ssc_p
->dir_mask
&= ~dir_mask
;
263 if (!ssc_p
->dir_mask
) {
264 /* Shutdown the SSC clock. */
265 DBG("Stopping pid %d clock\n", ssc_p
->ssc
.pid
);
266 at91_sys_write(AT91_PMC_PCDR
, 1<<ssc_p
->ssc
.pid
);
268 if (ssc_p
->initialized
) {
269 free_irq(ssc_p
->ssc
.pid
, ssc_p
);
270 ssc_p
->initialized
= 0;
274 at91_ssc_write(ssc_p
->ssc
.base
+ AT91_SSC_CR
, AT91_SSC_SWRST
);
276 /* Clear the SSC dividers */
277 ssc_p
->cmr_div
= ssc_p
->tcmr_period
= ssc_p
->rcmr_period
= 0;
279 spin_unlock_irq(&ssc_p
->lock
);
283 * Record the SSC system clock rate.
285 static int at91_ssc_set_dai_sysclk(struct snd_soc_cpu_dai
*cpu_dai
,
286 int clk_id
, unsigned int freq
, int dir
)
289 * The only clock supplied to the SSC is the AT91 master clock,
290 * which is only used if the SSC is generating BCLK and/or
294 case AT91_SYSCLK_MCK
:
295 at91_ssc_sysclk
= freq
;
305 * Record the DAI format for use in hw_params().
307 static int at91_ssc_set_dai_fmt(struct snd_soc_cpu_dai
*cpu_dai
,
310 struct at91_ssc_info
*ssc_p
= &ssc_info
[cpu_dai
->id
];
317 * Record SSC clock dividers for use in hw_params().
319 static int at91_ssc_set_dai_clkdiv(struct snd_soc_cpu_dai
*cpu_dai
,
322 struct at91_ssc_info
*ssc_p
= &ssc_info
[cpu_dai
->id
];
325 case AT91SSC_CMR_DIV
:
327 * The same master clock divider is used for both
328 * transmit and receive, so if a value has already
329 * been set, it must match this value.
331 if (ssc_p
->cmr_div
== 0)
332 ssc_p
->cmr_div
= div
;
334 if (div
!= ssc_p
->cmr_div
)
338 case AT91SSC_TCMR_PERIOD
:
339 ssc_p
->tcmr_period
= div
;
342 case AT91SSC_RCMR_PERIOD
:
343 ssc_p
->rcmr_period
= div
;
356 static int at91_ssc_hw_params(struct snd_pcm_substream
*substream
,
357 struct snd_pcm_hw_params
*params
)
359 struct snd_soc_pcm_runtime
*rtd
= substream
->private_data
;
360 int id
= rtd
->dai
->cpu_dai
->id
;
361 struct at91_ssc_info
*ssc_p
= &ssc_info
[id
];
362 struct at91_pcm_dma_params
*dma_params
;
363 int dir
, channels
, bits
;
364 u32 tfmr
, rfmr
, tcmr
, rcmr
;
369 * Currently, there is only one set of dma params for
370 * each direction. If more are added, this code will
371 * have to be changed to select the proper set.
373 dir
= substream
->stream
== SNDRV_PCM_STREAM_PLAYBACK
? 0 : 1;
375 dma_params
= &ssc_dma_params
[id
][dir
];
376 dma_params
->ssc_base
= ssc_p
->ssc
.base
;
377 dma_params
->substream
= substream
;
379 ssc_p
->dma_params
[dir
] = dma_params
;
382 * The cpu_dai->dma_data field is only used to communicate the
383 * appropriate DMA parameters to the pcm driver hw_params()
384 * function. It should not be used for other purposes
385 * as it is common to all substreams.
387 rtd
->dai
->cpu_dai
->dma_data
= dma_params
;
389 channels
= params_channels(params
);
392 * Determine sample size in bits and the PDC increment.
394 switch(params_format(params
)) {
395 case SNDRV_PCM_FORMAT_S8
:
397 dma_params
->pdc_xfer_size
= 1;
399 case SNDRV_PCM_FORMAT_S16_LE
:
401 dma_params
->pdc_xfer_size
= 2;
403 case SNDRV_PCM_FORMAT_S24_LE
:
405 dma_params
->pdc_xfer_size
= 4;
407 case SNDRV_PCM_FORMAT_S32_LE
:
409 dma_params
->pdc_xfer_size
= 4;
412 printk(KERN_WARNING
"at91-ssc: unsupported PCM format");
417 * The SSC only supports up to 16-bit samples in I2S format, due
418 * to the size of the Frame Mode Register FSLEN field.
420 if ((ssc_p
->daifmt
& SND_SOC_DAIFMT_FORMAT_MASK
) == SND_SOC_DAIFMT_I2S
423 "at91-ssc: sample size %d is too large for I2S\n", bits
);
428 * Compute SSC register settings.
430 switch (ssc_p
->daifmt
431 & (SND_SOC_DAIFMT_FORMAT_MASK
| SND_SOC_DAIFMT_MASTER_MASK
)) {
433 case SND_SOC_DAIFMT_I2S
| SND_SOC_DAIFMT_CBS_CFS
:
435 * I2S format, SSC provides BCLK and LRC clocks.
437 * The SSC transmit and receive clocks are generated from the
438 * MCK divider, and the BCLK signal is output on the SSC TK line.
440 rcmr
= (( ssc_p
->rcmr_period
<< 24) & AT91_SSC_PERIOD
)
441 | (( 1 << 16) & AT91_SSC_STTDLY
)
442 | (( AT91_SSC_START_FALLING_RF
) & AT91_SSC_START
)
443 | (( AT91_SSC_CK_RISING
) & AT91_SSC_CKI
)
444 | (( AT91_SSC_CKO_NONE
) & AT91_SSC_CKO
)
445 | (( AT91_SSC_CKS_DIV
) & AT91_SSC_CKS
);
447 rfmr
= (( AT91_SSC_FSEDGE_POSITIVE
) & AT91_SSC_FSEDGE
)
448 | (( AT91_SSC_FSOS_NEGATIVE
) & AT91_SSC_FSOS
)
449 | (((bits
- 1) << 16) & AT91_SSC_FSLEN
)
450 | (((channels
- 1) << 8) & AT91_SSC_DATNB
)
451 | (( 1 << 7) & AT91_SSC_MSBF
)
452 | (( 0 << 5) & AT91_SSC_LOOP
)
453 | (((bits
- 1) << 0) & AT91_SSC_DATALEN
);
455 tcmr
= (( ssc_p
->tcmr_period
<< 24) & AT91_SSC_PERIOD
)
456 | (( 1 << 16) & AT91_SSC_STTDLY
)
457 | (( AT91_SSC_START_FALLING_RF
) & AT91_SSC_START
)
458 | (( AT91_SSC_CKI_FALLING
) & AT91_SSC_CKI
)
459 | (( AT91_SSC_CKO_CONTINUOUS
) & AT91_SSC_CKO
)
460 | (( AT91_SSC_CKS_DIV
) & AT91_SSC_CKS
);
462 tfmr
= (( AT91_SSC_FSEDGE_POSITIVE
) & AT91_SSC_FSEDGE
)
463 | (( 0 << 23) & AT91_SSC_FSDEN
)
464 | (( AT91_SSC_FSOS_NEGATIVE
) & AT91_SSC_FSOS
)
465 | (((bits
- 1) << 16) & AT91_SSC_FSLEN
)
466 | (((channels
- 1) << 8) & AT91_SSC_DATNB
)
467 | (( 1 << 7) & AT91_SSC_MSBF
)
468 | (( 0 << 5) & AT91_SSC_DATDEF
)
469 | (((bits
- 1) << 0) & AT91_SSC_DATALEN
);
472 case SND_SOC_DAIFMT_I2S
| SND_SOC_DAIFMT_CBM_CFM
:
474 * I2S format, CODEC supplies BCLK and LRC clocks.
476 * The SSC transmit clock is obtained from the BCLK signal on
477 * on the TK line, and the SSC receive clock is generated from the
480 * For single channel data, one sample is transferred on the falling
481 * edge of the LRC clock. For two channel data, one sample is
482 * transferred on both edges of the LRC clock.
484 start_event
= channels
== 1
485 ? AT91_SSC_START_FALLING_RF
486 : AT91_SSC_START_EDGE_RF
;
488 rcmr
= (( 0 << 24) & AT91_SSC_PERIOD
)
489 | (( 1 << 16) & AT91_SSC_STTDLY
)
490 | (( start_event
) & AT91_SSC_START
)
491 | (( AT91_SSC_CK_RISING
) & AT91_SSC_CKI
)
492 | (( AT91_SSC_CKO_NONE
) & AT91_SSC_CKO
)
493 | (( AT91_SSC_CKS_CLOCK
) & AT91_SSC_CKS
);
495 rfmr
= (( AT91_SSC_FSEDGE_POSITIVE
) & AT91_SSC_FSEDGE
)
496 | (( AT91_SSC_FSOS_NONE
) & AT91_SSC_FSOS
)
497 | (( 0 << 16) & AT91_SSC_FSLEN
)
498 | (( 0 << 8) & AT91_SSC_DATNB
)
499 | (( 1 << 7) & AT91_SSC_MSBF
)
500 | (( 0 << 5) & AT91_SSC_LOOP
)
501 | (((bits
- 1) << 0) & AT91_SSC_DATALEN
);
503 tcmr
= (( 0 << 24) & AT91_SSC_PERIOD
)
504 | (( 1 << 16) & AT91_SSC_STTDLY
)
505 | (( start_event
) & AT91_SSC_START
)
506 | (( AT91_SSC_CKI_FALLING
) & AT91_SSC_CKI
)
507 | (( AT91_SSC_CKO_NONE
) & AT91_SSC_CKO
)
508 | (( AT91_SSC_CKS_PIN
) & AT91_SSC_CKS
);
510 tfmr
= (( AT91_SSC_FSEDGE_POSITIVE
) & AT91_SSC_FSEDGE
)
511 | (( 0 << 23) & AT91_SSC_FSDEN
)
512 | (( AT91_SSC_FSOS_NONE
) & AT91_SSC_FSOS
)
513 | (( 0 << 16) & AT91_SSC_FSLEN
)
514 | (( 0 << 8) & AT91_SSC_DATNB
)
515 | (( 1 << 7) & AT91_SSC_MSBF
)
516 | (( 0 << 5) & AT91_SSC_DATDEF
)
517 | (((bits
- 1) << 0) & AT91_SSC_DATALEN
);
520 case SND_SOC_DAIFMT_DSP_A
| SND_SOC_DAIFMT_CBS_CFS
:
522 * DSP/PCM Mode A format, SSC provides BCLK and LRC clocks.
524 * The SSC transmit and receive clocks are generated from the
525 * MCK divider, and the BCLK signal is output on the SSC TK line.
527 rcmr
= (( ssc_p
->rcmr_period
<< 24) & AT91_SSC_PERIOD
)
528 | (( 1 << 16) & AT91_SSC_STTDLY
)
529 | (( AT91_SSC_START_RISING_RF
) & AT91_SSC_START
)
530 | (( AT91_SSC_CK_RISING
) & AT91_SSC_CKI
)
531 | (( AT91_SSC_CKO_NONE
) & AT91_SSC_CKO
)
532 | (( AT91_SSC_CKS_DIV
) & AT91_SSC_CKS
);
534 rfmr
= (( AT91_SSC_FSEDGE_POSITIVE
) & AT91_SSC_FSEDGE
)
535 | (( AT91_SSC_FSOS_POSITIVE
) & AT91_SSC_FSOS
)
536 | (( 0 << 16) & AT91_SSC_FSLEN
)
537 | (((channels
- 1) << 8) & AT91_SSC_DATNB
)
538 | (( 1 << 7) & AT91_SSC_MSBF
)
539 | (( 0 << 5) & AT91_SSC_LOOP
)
540 | (((bits
- 1) << 0) & AT91_SSC_DATALEN
);
542 tcmr
= (( ssc_p
->tcmr_period
<< 24) & AT91_SSC_PERIOD
)
543 | (( 1 << 16) & AT91_SSC_STTDLY
)
544 | (( AT91_SSC_START_RISING_RF
) & AT91_SSC_START
)
545 | (( AT91_SSC_CK_RISING
) & AT91_SSC_CKI
)
546 | (( AT91_SSC_CKO_CONTINUOUS
) & AT91_SSC_CKO
)
547 | (( AT91_SSC_CKS_DIV
) & AT91_SSC_CKS
);
549 tfmr
= (( AT91_SSC_FSEDGE_POSITIVE
) & AT91_SSC_FSEDGE
)
550 | (( 0 << 23) & AT91_SSC_FSDEN
)
551 | (( AT91_SSC_FSOS_POSITIVE
) & AT91_SSC_FSOS
)
552 | (( 0 << 16) & AT91_SSC_FSLEN
)
553 | (((channels
- 1) << 8) & AT91_SSC_DATNB
)
554 | (( 1 << 7) & AT91_SSC_MSBF
)
555 | (( 0 << 5) & AT91_SSC_DATDEF
)
556 | (((bits
- 1) << 0) & AT91_SSC_DATALEN
);
562 case SND_SOC_DAIFMT_DSP_A
| SND_SOC_DAIFMT_CBM_CFM
:
564 printk(KERN_WARNING
"at91-ssc: unsupported DAI format 0x%x.\n",
569 DBG("RCMR=%08x RFMR=%08x TCMR=%08x TFMR=%08x\n", rcmr
, rfmr
, tcmr
, tfmr
);
571 if (!ssc_p
->initialized
) {
573 /* Enable PMC peripheral clock for this SSC */
574 DBG("Starting pid %d clock\n", ssc_p
->ssc
.pid
);
575 at91_sys_write(AT91_PMC_PCER
, 1<<ssc_p
->ssc
.pid
);
577 /* Reset the SSC and its PDC registers */
578 at91_ssc_write(ssc_p
->ssc
.base
+ AT91_SSC_CR
, AT91_SSC_SWRST
);
580 at91_ssc_write(ssc_p
->ssc
.base
+ ATMEL_PDC_RPR
, 0);
581 at91_ssc_write(ssc_p
->ssc
.base
+ ATMEL_PDC_RCR
, 0);
582 at91_ssc_write(ssc_p
->ssc
.base
+ ATMEL_PDC_RNPR
, 0);
583 at91_ssc_write(ssc_p
->ssc
.base
+ ATMEL_PDC_RNCR
, 0);
584 at91_ssc_write(ssc_p
->ssc
.base
+ ATMEL_PDC_TPR
, 0);
585 at91_ssc_write(ssc_p
->ssc
.base
+ ATMEL_PDC_TCR
, 0);
586 at91_ssc_write(ssc_p
->ssc
.base
+ ATMEL_PDC_TNPR
, 0);
587 at91_ssc_write(ssc_p
->ssc
.base
+ ATMEL_PDC_TNCR
, 0);
589 if ((ret
= request_irq(ssc_p
->ssc
.pid
, at91_ssc_interrupt
,
590 0, ssc_p
->name
, ssc_p
)) < 0) {
591 printk(KERN_WARNING
"at91-ssc: request_irq failure\n");
593 DBG("Stopping pid %d clock\n", ssc_p
->ssc
.pid
);
594 at91_sys_write(AT91_PMC_PCER
, 1<<ssc_p
->ssc
.pid
);
598 ssc_p
->initialized
= 1;
601 /* set SSC clock mode register */
602 at91_ssc_write(ssc_p
->ssc
.base
+ AT91_SSC_CMR
, ssc_p
->cmr_div
);
604 /* set receive clock mode and format */
605 at91_ssc_write(ssc_p
->ssc
.base
+ AT91_SSC_RCMR
, rcmr
);
606 at91_ssc_write(ssc_p
->ssc
.base
+ AT91_SSC_RFMR
, rfmr
);
608 /* set transmit clock mode and format */
609 at91_ssc_write(ssc_p
->ssc
.base
+ AT91_SSC_TCMR
, tcmr
);
610 at91_ssc_write(ssc_p
->ssc
.base
+ AT91_SSC_TFMR
, tfmr
);
612 DBG("hw_params: SSC initialized\n");
617 static int at91_ssc_prepare(struct snd_pcm_substream
*substream
)
619 struct snd_soc_pcm_runtime
*rtd
= substream
->private_data
;
620 struct at91_ssc_info
*ssc_p
= &ssc_info
[rtd
->dai
->cpu_dai
->id
];
621 struct at91_pcm_dma_params
*dma_params
;
624 dir
= substream
->stream
== SNDRV_PCM_STREAM_PLAYBACK
? 0 : 1;
625 dma_params
= ssc_p
->dma_params
[dir
];
627 at91_ssc_write(dma_params
->ssc_base
+ AT91_SSC_CR
,
628 dma_params
->mask
->ssc_enable
);
630 DBG("%s enabled SSC_SR=0x%08lx\n", dir
? "receive" : "transmit",
631 at91_ssc_read(dma_params
->ssc_base
+ AT91_SSC_SR
));
637 static int at91_ssc_suspend(struct platform_device
*pdev
,
638 struct snd_soc_cpu_dai
*cpu_dai
)
640 struct at91_ssc_info
*ssc_p
;
645 ssc_p
= &ssc_info
[cpu_dai
->id
];
647 /* Save the status register before disabling transmit and receive. */
648 ssc_p
->ssc_state
.ssc_sr
= at91_ssc_read(ssc_p
->ssc
.base
+ AT91_SSC_SR
);
649 at91_ssc_write(ssc_p
->ssc
.base
+ AT91_SSC_CR
,
650 AT91_SSC_TXDIS
| AT91_SSC_RXDIS
);
652 /* Save the current interrupt mask, then disable unmasked interrupts. */
653 ssc_p
->ssc_state
.ssc_imr
= at91_ssc_read(ssc_p
->ssc
.base
+ AT91_SSC_IMR
);
654 at91_ssc_write(ssc_p
->ssc
.base
+ AT91_SSC_IDR
, ssc_p
->ssc_state
.ssc_imr
);
656 ssc_p
->ssc_state
.ssc_cmr
= at91_ssc_read(ssc_p
->ssc
.base
+ AT91_SSC_CMR
);
657 ssc_p
->ssc_state
.ssc_rcmr
= at91_ssc_read(ssc_p
->ssc
.base
+ AT91_SSC_RCMR
);
658 ssc_p
->ssc_state
.ssc_rfmr
= at91_ssc_read(ssc_p
->ssc
.base
+ AT91_SSC_RFMR
);
659 ssc_p
->ssc_state
.ssc_tcmr
= at91_ssc_read(ssc_p
->ssc
.base
+ AT91_SSC_TCMR
);
660 ssc_p
->ssc_state
.ssc_tfmr
= at91_ssc_read(ssc_p
->ssc
.base
+ AT91_SSC_TFMR
);
665 static int at91_ssc_resume(struct platform_device
*pdev
,
666 struct snd_soc_cpu_dai
*cpu_dai
)
668 struct at91_ssc_info
*ssc_p
;
673 ssc_p
= &ssc_info
[cpu_dai
->id
];
675 at91_ssc_write(ssc_p
->ssc
.base
+ AT91_SSC_TFMR
, ssc_p
->ssc_state
.ssc_tfmr
);
676 at91_ssc_write(ssc_p
->ssc
.base
+ AT91_SSC_TCMR
, ssc_p
->ssc_state
.ssc_tcmr
);
677 at91_ssc_write(ssc_p
->ssc
.base
+ AT91_SSC_RFMR
, ssc_p
->ssc_state
.ssc_rfmr
);
678 at91_ssc_write(ssc_p
->ssc
.base
+ AT91_SSC_RCMR
, ssc_p
->ssc_state
.ssc_rcmr
);
679 at91_ssc_write(ssc_p
->ssc
.base
+ AT91_SSC_CMR
, ssc_p
->ssc_state
.ssc_cmr
);
681 at91_ssc_write(ssc_p
->ssc
.base
+ AT91_SSC_IER
, ssc_p
->ssc_state
.ssc_imr
);
683 at91_ssc_write(ssc_p
->ssc
.base
+ AT91_SSC_CR
,
684 ((ssc_p
->ssc_state
.ssc_sr
& AT91_SSC_RXENA
) ? AT91_SSC_RXEN
: 0) |
685 ((ssc_p
->ssc_state
.ssc_sr
& AT91_SSC_TXENA
) ? AT91_SSC_TXEN
: 0));
691 #define at91_ssc_suspend NULL
692 #define at91_ssc_resume NULL
695 #define AT91_SSC_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
696 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |\
697 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |\
698 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 |\
699 SNDRV_PCM_RATE_96000)
701 #define AT91_SSC_FORMATS (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE |\
702 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
704 struct snd_soc_cpu_dai at91_ssc_dai
[NUM_SSC_DEVICES
] = {
705 { .name
= "at91-ssc0",
707 .type
= SND_SOC_DAI_PCM
,
708 .suspend
= at91_ssc_suspend
,
709 .resume
= at91_ssc_resume
,
713 .rates
= AT91_SSC_RATES
,
714 .formats
= AT91_SSC_FORMATS
,},
718 .rates
= AT91_SSC_RATES
,
719 .formats
= AT91_SSC_FORMATS
,},
721 .startup
= at91_ssc_startup
,
722 .shutdown
= at91_ssc_shutdown
,
723 .prepare
= at91_ssc_prepare
,
724 .hw_params
= at91_ssc_hw_params
,},
726 .set_sysclk
= at91_ssc_set_dai_sysclk
,
727 .set_fmt
= at91_ssc_set_dai_fmt
,
728 .set_clkdiv
= at91_ssc_set_dai_clkdiv
,},
729 .private_data
= &ssc_info
[0].ssc
,
731 #if NUM_SSC_DEVICES == 3
732 { .name
= "at91-ssc1",
734 .type
= SND_SOC_DAI_PCM
,
735 .suspend
= at91_ssc_suspend
,
736 .resume
= at91_ssc_resume
,
740 .rates
= AT91_SSC_RATES
,
741 .formats
= AT91_SSC_FORMATS
,},
745 .rates
= AT91_SSC_RATES
,
746 .formats
= AT91_SSC_FORMATS
,},
748 .startup
= at91_ssc_startup
,
749 .shutdown
= at91_ssc_shutdown
,
750 .prepare
= at91_ssc_prepare
,
751 .hw_params
= at91_ssc_hw_params
,},
753 .set_sysclk
= at91_ssc_set_dai_sysclk
,
754 .set_fmt
= at91_ssc_set_dai_fmt
,
755 .set_clkdiv
= at91_ssc_set_dai_clkdiv
,},
756 .private_data
= &ssc_info
[1].ssc
,
758 { .name
= "at91-ssc2",
760 .type
= SND_SOC_DAI_PCM
,
761 .suspend
= at91_ssc_suspend
,
762 .resume
= at91_ssc_resume
,
766 .rates
= AT91_SSC_RATES
,
767 .formats
= AT91_SSC_FORMATS
,},
771 .rates
= AT91_SSC_RATES
,
772 .formats
= AT91_SSC_FORMATS
,},
774 .startup
= at91_ssc_startup
,
775 .shutdown
= at91_ssc_shutdown
,
776 .prepare
= at91_ssc_prepare
,
777 .hw_params
= at91_ssc_hw_params
,},
779 .set_sysclk
= at91_ssc_set_dai_sysclk
,
780 .set_fmt
= at91_ssc_set_dai_fmt
,
781 .set_clkdiv
= at91_ssc_set_dai_clkdiv
,},
782 .private_data
= &ssc_info
[2].ssc
,
787 EXPORT_SYMBOL_GPL(at91_ssc_dai
);
789 /* Module information */
790 MODULE_AUTHOR("Frank Mandarino, fmandarino@endrelia.com, www.endrelia.com");
791 MODULE_DESCRIPTION("AT91 SSC ASoC Interface");
792 MODULE_LICENSE("GPL");