1 /* sound/soc/at32/at32-ssc.c
2 * ASoC platform driver for AT32 using SSC as DAI
4 * Copyright (C) 2008 Long Range Systems
5 * Geoffrey Wossum <gwossum@acm.org>
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
11 * Note that this is basically a port of the sound/soc/at91-ssc.c to
12 * the AVR32 kernel. Thanks to Frank Mandarino for that code.
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>
24 #include <linux/atmel_pdc.h>
25 #include <linux/atmel-ssc.h>
27 #include <sound/core.h>
28 #include <sound/pcm.h>
29 #include <sound/pcm_params.h>
30 #include <sound/initval.h>
31 #include <sound/soc.h>
38 /*-------------------------------------------------------------------------*\
40 \*-------------------------------------------------------------------------*/
41 #define NUM_SSC_DEVICES 3
46 #define SSC_DIR_MASK_UNUSED 0
47 #define SSC_DIR_MASK_PLAYBACK 1
48 #define SSC_DIR_MASK_CAPTURE 2
51 * SSC register values that Atmel left out of <linux/atmel-ssc.h>. These
52 * are expected to be used with SSC_BF
54 /* START bit field values */
55 #define SSC_START_CONTINUOUS 0
56 #define SSC_START_TX_RX 1
57 #define SSC_START_LOW_RF 2
58 #define SSC_START_HIGH_RF 3
59 #define SSC_START_FALLING_RF 4
60 #define SSC_START_RISING_RF 5
61 #define SSC_START_LEVEL_RF 6
62 #define SSC_START_EDGE_RF 7
63 #define SSS_START_COMPARE_0 8
65 /* CKI bit field values */
66 #define SSC_CKI_FALLING 0
67 #define SSC_CKI_RISING 1
69 /* CKO bit field values */
70 #define SSC_CKO_NONE 0
71 #define SSC_CKO_CONTINUOUS 1
72 #define SSC_CKO_TRANSFER 2
74 /* CKS bit field values */
76 #define SSC_CKS_CLOCK 1
79 /* FSEDGE bit field values */
80 #define SSC_FSEDGE_POSITIVE 0
81 #define SSC_FSEDGE_NEGATIVE 1
83 /* FSOS bit field values */
84 #define SSC_FSOS_NONE 0
85 #define SSC_FSOS_NEGATIVE 1
86 #define SSC_FSOS_POSITIVE 2
87 #define SSC_FSOS_LOW 3
88 #define SSC_FSOS_HIGH 4
89 #define SSC_FSOS_TOGGLE 5
95 /*-------------------------------------------------------------------------*\
97 \*-------------------------------------------------------------------------*/
99 * SSC PDC registered required by the PCM DMA engine
101 static struct at32_pdc_regs pdc_tx_reg
= {
104 .xnpr
= SSC_PDC_TNPR
,
105 .xncr
= SSC_PDC_TNCR
,
110 static struct at32_pdc_regs pdc_rx_reg
= {
113 .xnpr
= SSC_PDC_RNPR
,
114 .xncr
= SSC_PDC_RNCR
,
120 * SSC and PDC status bits for transmit and receive
122 static struct at32_ssc_mask ssc_tx_mask
= {
123 .ssc_enable
= SSC_BIT(CR_TXEN
),
124 .ssc_disable
= SSC_BIT(CR_TXDIS
),
125 .ssc_endx
= SSC_BIT(SR_ENDTX
),
126 .ssc_endbuf
= SSC_BIT(SR_TXBUFE
),
127 .pdc_enable
= SSC_BIT(PDC_PTCR_TXTEN
),
128 .pdc_disable
= SSC_BIT(PDC_PTCR_TXTDIS
),
133 static struct at32_ssc_mask ssc_rx_mask
= {
134 .ssc_enable
= SSC_BIT(CR_RXEN
),
135 .ssc_disable
= SSC_BIT(CR_RXDIS
),
136 .ssc_endx
= SSC_BIT(SR_ENDRX
),
137 .ssc_endbuf
= SSC_BIT(SR_RXBUFF
),
138 .pdc_enable
= SSC_BIT(PDC_PTCR_RXTEN
),
139 .pdc_disable
= SSC_BIT(PDC_PTCR_RXTDIS
),
145 * DMA parameters for each SSC
147 static struct at32_pcm_dma_params ssc_dma_params
[NUM_SSC_DEVICES
][2] = {
150 .name
= "SSC0 PCM out",
152 .mask
= &ssc_tx_mask
,
155 .name
= "SSC0 PCM in",
157 .mask
= &ssc_rx_mask
,
162 .name
= "SSC1 PCM out",
164 .mask
= &ssc_tx_mask
,
167 .name
= "SSC1 PCM in",
169 .mask
= &ssc_rx_mask
,
174 .name
= "SSC2 PCM out",
176 .mask
= &ssc_tx_mask
,
179 .name
= "SSC2 PCM in",
181 .mask
= &ssc_rx_mask
,
188 static struct at32_ssc_info ssc_info
[NUM_SSC_DEVICES
] = {
191 .lock
= __SPIN_LOCK_UNLOCKED(ssc_info
[0].lock
),
192 .dir_mask
= SSC_DIR_MASK_UNUSED
,
197 .lock
= __SPIN_LOCK_UNLOCKED(ssc_info
[1].lock
),
198 .dir_mask
= SSC_DIR_MASK_UNUSED
,
203 .lock
= __SPIN_LOCK_UNLOCKED(ssc_info
[2].lock
),
204 .dir_mask
= SSC_DIR_MASK_UNUSED
,
212 /*-------------------------------------------------------------------------*\
214 \*-------------------------------------------------------------------------*/
216 * SSC interrupt handler. Passes PDC interrupts to the DMA interrupt
217 * handler in the PCM driver.
219 static irqreturn_t
at32_ssc_interrupt(int irq
, void *dev_id
)
221 struct at32_ssc_info
*ssc_p
= dev_id
;
222 struct at32_pcm_dma_params
*dma_params
;
224 u32 ssc_substream_mask
;
227 ssc_sr
= (ssc_readl(ssc_p
->ssc
->regs
, SR
) &
228 ssc_readl(ssc_p
->ssc
->regs
, IMR
));
231 * Loop through substreams attached to this SSC. If a DMA-related
232 * interrupt occured on that substream, call the DMA interrupt
233 * handler function, if one has been registered in the dma_param
234 * structure by the PCM driver.
236 for (i
= 0; i
< ARRAY_SIZE(ssc_p
->dma_params
); i
++) {
237 dma_params
= ssc_p
->dma_params
[i
];
239 if ((dma_params
!= NULL
) &&
240 (dma_params
->dma_intr_handler
!= NULL
)) {
241 ssc_substream_mask
= (dma_params
->mask
->ssc_endx
|
242 dma_params
->mask
->ssc_endbuf
);
243 if (ssc_sr
& ssc_substream_mask
) {
244 dma_params
->dma_intr_handler(ssc_sr
,
255 /*-------------------------------------------------------------------------*\
257 \*-------------------------------------------------------------------------*/
259 * Startup. Only that one substream allowed in each direction.
261 static int at32_ssc_startup(struct snd_pcm_substream
*substream
)
263 struct snd_soc_pcm_runtime
*rtd
= substream
->private_data
;
264 struct at32_ssc_info
*ssc_p
= &ssc_info
[rtd
->dai
->cpu_dai
->id
];
267 dir_mask
= ((substream
->stream
== SNDRV_PCM_STREAM_PLAYBACK
) ?
268 SSC_DIR_MASK_PLAYBACK
: SSC_DIR_MASK_CAPTURE
);
270 spin_lock_irq(&ssc_p
->lock
);
271 if (ssc_p
->dir_mask
& dir_mask
) {
272 spin_unlock_irq(&ssc_p
->lock
);
275 ssc_p
->dir_mask
|= dir_mask
;
276 spin_unlock_irq(&ssc_p
->lock
);
284 * Shutdown. Clear DMA parameters and shutdown the SSC if there
285 * are no other substreams open.
287 static void at32_ssc_shutdown(struct snd_pcm_substream
*substream
)
289 struct snd_soc_pcm_runtime
*rtd
= substream
->private_data
;
290 struct at32_ssc_info
*ssc_p
= &ssc_info
[rtd
->dai
->cpu_dai
->id
];
291 struct at32_pcm_dma_params
*dma_params
;
294 dma_params
= ssc_p
->dma_params
[substream
->stream
];
296 if (dma_params
!= NULL
) {
297 ssc_writel(dma_params
->ssc
->regs
, CR
,
298 dma_params
->mask
->ssc_disable
);
299 pr_debug("%s disabled SSC_SR=0x%08x\n",
300 (substream
->stream
? "receiver" : "transmit"),
301 ssc_readl(ssc_p
->ssc
->regs
, SR
));
303 dma_params
->ssc
= NULL
;
304 dma_params
->substream
= NULL
;
305 ssc_p
->dma_params
[substream
->stream
] = NULL
;
309 dir_mask
= 1 << substream
->stream
;
310 spin_lock_irq(&ssc_p
->lock
);
311 ssc_p
->dir_mask
&= ~dir_mask
;
312 if (!ssc_p
->dir_mask
) {
313 /* Shutdown the SSC clock */
314 pr_debug("at32-ssc: Stopping user %d clock\n",
316 clk_disable(ssc_p
->ssc
->clk
);
318 if (ssc_p
->initialized
) {
319 free_irq(ssc_p
->ssc
->irq
, ssc_p
);
320 ssc_p
->initialized
= 0;
324 ssc_writel(ssc_p
->ssc
->regs
, CR
, SSC_BIT(CR_SWRST
));
326 /* clear the SSC dividers */
328 ssc_p
->tcmr_period
= 0;
329 ssc_p
->rcmr_period
= 0;
331 spin_unlock_irq(&ssc_p
->lock
);
337 * Set the SSC system clock rate
339 static int at32_ssc_set_dai_sysclk(struct snd_soc_dai
*cpu_dai
,
340 int clk_id
, unsigned int freq
, int dir
)
342 /* TODO: What the heck do I do here? */
349 * Record DAI format for use by hw_params()
351 static int at32_ssc_set_dai_fmt(struct snd_soc_dai
*cpu_dai
,
354 struct at32_ssc_info
*ssc_p
= &ssc_info
[cpu_dai
->id
];
363 * Record SSC clock dividers for use in hw_params()
365 static int at32_ssc_set_dai_clkdiv(struct snd_soc_dai
*cpu_dai
,
368 struct at32_ssc_info
*ssc_p
= &ssc_info
[cpu_dai
->id
];
371 case AT32_SSC_CMR_DIV
:
373 * The same master clock divider is used for both
374 * transmit and receive, so if a value has already
375 * been set, it must match this value
377 if (ssc_p
->cmr_div
== 0)
378 ssc_p
->cmr_div
= div
;
379 else if (div
!= ssc_p
->cmr_div
)
383 case AT32_SSC_TCMR_PERIOD
:
384 ssc_p
->tcmr_period
= div
;
387 case AT32_SSC_RCMR_PERIOD
:
388 ssc_p
->rcmr_period
= div
;
403 static int at32_ssc_hw_params(struct snd_pcm_substream
*substream
,
404 struct snd_pcm_hw_params
*params
)
406 struct snd_soc_pcm_runtime
*rtd
= substream
->private_data
;
407 int id
= rtd
->dai
->cpu_dai
->id
;
408 struct at32_ssc_info
*ssc_p
= &ssc_info
[id
];
409 struct at32_pcm_dma_params
*dma_params
;
411 u32 tfmr
, rfmr
, tcmr
, rcmr
;
417 * Currently, there is only one set of dma_params for each direction.
418 * If more are added, this code will have to be changed to select
421 dma_params
= &ssc_dma_params
[id
][substream
->stream
];
422 dma_params
->ssc
= ssc_p
->ssc
;
423 dma_params
->substream
= substream
;
425 ssc_p
->dma_params
[substream
->stream
] = dma_params
;
429 * The cpu_dai->dma_data field is only used to communicate the
430 * appropriate DMA parameters to the PCM driver's hw_params()
431 * function. It should not be used for other purposes as it
432 * is common to all substreams.
434 rtd
->dai
->cpu_dai
->dma_data
= dma_params
;
436 channels
= params_channels(params
);
440 * Determine sample size in bits and the PDC increment
442 switch (params_format(params
)) {
443 case SNDRV_PCM_FORMAT_S8
:
445 dma_params
->pdc_xfer_size
= 1;
448 case SNDRV_PCM_FORMAT_S16
:
450 dma_params
->pdc_xfer_size
= 2;
453 case SNDRV_PCM_FORMAT_S24
:
455 dma_params
->pdc_xfer_size
= 4;
458 case SNDRV_PCM_FORMAT_S32
:
460 dma_params
->pdc_xfer_size
= 4;
464 pr_warning("at32-ssc: Unsupported PCM format %d",
465 params_format(params
));
468 pr_debug("at32-ssc: bits = %d, pdc_xfer_size = %d, channels = %d\n",
469 bits
, dma_params
->pdc_xfer_size
, channels
);
473 * The SSC only supports up to 16-bit samples in I2S format, due
474 * to the size of the Frame Mode Register FSLEN field.
476 if ((ssc_p
->daifmt
& SND_SOC_DAIFMT_FORMAT_MASK
) == SND_SOC_DAIFMT_I2S
)
478 pr_warning("at32-ssc: "
479 "sample size %d is too large for I2S\n",
486 * Compute the SSC register settings
488 switch (ssc_p
->daifmt
& (SND_SOC_DAIFMT_FORMAT_MASK
|
489 SND_SOC_DAIFMT_MASTER_MASK
)) {
490 case SND_SOC_DAIFMT_I2S
| SND_SOC_DAIFMT_CBS_CFS
:
492 * I2S format, SSC provides BCLK and LRS clocks.
494 * The SSC transmit and receive clocks are generated from the
495 * MCK divider, and the BCLK signal is output on the SSC TK line
497 pr_debug("at32-ssc: SSC mode is I2S BCLK / FRAME master\n");
498 rcmr
= (SSC_BF(RCMR_PERIOD
, ssc_p
->rcmr_period
) |
499 SSC_BF(RCMR_STTDLY
, START_DELAY
) |
500 SSC_BF(RCMR_START
, SSC_START_FALLING_RF
) |
501 SSC_BF(RCMR_CKI
, SSC_CKI_RISING
) |
502 SSC_BF(RCMR_CKO
, SSC_CKO_NONE
) |
503 SSC_BF(RCMR_CKS
, SSC_CKS_DIV
));
505 rfmr
= (SSC_BF(RFMR_FSEDGE
, SSC_FSEDGE_POSITIVE
) |
506 SSC_BF(RFMR_FSOS
, SSC_FSOS_NEGATIVE
) |
507 SSC_BF(RFMR_FSLEN
, bits
- 1) |
508 SSC_BF(RFMR_DATNB
, channels
- 1) |
509 SSC_BIT(RFMR_MSBF
) | SSC_BF(RFMR_DATLEN
, bits
- 1));
511 tcmr
= (SSC_BF(TCMR_PERIOD
, ssc_p
->tcmr_period
) |
512 SSC_BF(TCMR_STTDLY
, START_DELAY
) |
513 SSC_BF(TCMR_START
, SSC_START_FALLING_RF
) |
514 SSC_BF(TCMR_CKI
, SSC_CKI_FALLING
) |
515 SSC_BF(TCMR_CKO
, SSC_CKO_CONTINUOUS
) |
516 SSC_BF(TCMR_CKS
, SSC_CKS_DIV
));
518 tfmr
= (SSC_BF(TFMR_FSEDGE
, SSC_FSEDGE_POSITIVE
) |
519 SSC_BF(TFMR_FSOS
, SSC_FSOS_NEGATIVE
) |
520 SSC_BF(TFMR_FSLEN
, bits
- 1) |
521 SSC_BF(TFMR_DATNB
, channels
- 1) | SSC_BIT(TFMR_MSBF
) |
522 SSC_BF(TFMR_DATLEN
, bits
- 1));
526 case SND_SOC_DAIFMT_I2S
| SND_SOC_DAIFMT_CBM_CFM
:
528 * I2S format, CODEC supplies BCLK and LRC clock.
530 * The SSC transmit clock is obtained from the BCLK signal
531 * on the TK line, and the SSC receive clock is generated from
532 * the transmit clock.
534 * For single channel data, one sample is transferred on the
535 * falling edge of the LRC clock. For two channel data, one
536 * sample is transferred on both edges of the LRC clock.
538 pr_debug("at32-ssc: SSC mode is I2S BCLK / FRAME slave\n");
539 start_event
= ((channels
== 1) ?
540 SSC_START_FALLING_RF
: SSC_START_EDGE_RF
);
542 rcmr
= (SSC_BF(RCMR_STTDLY
, START_DELAY
) |
543 SSC_BF(RCMR_START
, start_event
) |
544 SSC_BF(RCMR_CKI
, SSC_CKI_RISING
) |
545 SSC_BF(RCMR_CKO
, SSC_CKO_NONE
) |
546 SSC_BF(RCMR_CKS
, SSC_CKS_CLOCK
));
548 rfmr
= (SSC_BF(RFMR_FSEDGE
, SSC_FSEDGE_POSITIVE
) |
549 SSC_BF(RFMR_FSOS
, SSC_FSOS_NONE
) |
550 SSC_BIT(RFMR_MSBF
) | SSC_BF(RFMR_DATLEN
, bits
- 1));
552 tcmr
= (SSC_BF(TCMR_STTDLY
, START_DELAY
) |
553 SSC_BF(TCMR_START
, start_event
) |
554 SSC_BF(TCMR_CKI
, SSC_CKI_FALLING
) |
555 SSC_BF(TCMR_CKO
, SSC_CKO_NONE
) |
556 SSC_BF(TCMR_CKS
, SSC_CKS_PIN
));
558 tfmr
= (SSC_BF(TFMR_FSEDGE
, SSC_FSEDGE_POSITIVE
) |
559 SSC_BF(TFMR_FSOS
, SSC_FSOS_NONE
) |
560 SSC_BIT(TFMR_MSBF
) | SSC_BF(TFMR_DATLEN
, bits
- 1));
564 case SND_SOC_DAIFMT_DSP_A
| SND_SOC_DAIFMT_CBS_CFS
:
566 * DSP/PCM Mode A format, SSC provides BCLK and LRC clocks.
568 * The SSC transmit and receive clocks are generated from the
569 * MCK divider, and the BCLK signal is output on the SSC TK line
571 pr_debug("at32-ssc: SSC mode is DSP A BCLK / FRAME master\n");
572 rcmr
= (SSC_BF(RCMR_PERIOD
, ssc_p
->rcmr_period
) |
573 SSC_BF(RCMR_STTDLY
, 1) |
574 SSC_BF(RCMR_START
, SSC_START_RISING_RF
) |
575 SSC_BF(RCMR_CKI
, SSC_CKI_RISING
) |
576 SSC_BF(RCMR_CKO
, SSC_CKO_NONE
) |
577 SSC_BF(RCMR_CKS
, SSC_CKS_DIV
));
579 rfmr
= (SSC_BF(RFMR_FSEDGE
, SSC_FSEDGE_POSITIVE
) |
580 SSC_BF(RFMR_FSOS
, SSC_FSOS_POSITIVE
) |
581 SSC_BF(RFMR_DATNB
, channels
- 1) |
582 SSC_BIT(RFMR_MSBF
) | SSC_BF(RFMR_DATLEN
, bits
- 1));
584 tcmr
= (SSC_BF(TCMR_PERIOD
, ssc_p
->tcmr_period
) |
585 SSC_BF(TCMR_STTDLY
, 1) |
586 SSC_BF(TCMR_START
, SSC_START_RISING_RF
) |
587 SSC_BF(TCMR_CKI
, SSC_CKI_RISING
) |
588 SSC_BF(TCMR_CKO
, SSC_CKO_CONTINUOUS
) |
589 SSC_BF(TCMR_CKS
, SSC_CKS_DIV
));
591 tfmr
= (SSC_BF(TFMR_FSEDGE
, SSC_FSEDGE_POSITIVE
) |
592 SSC_BF(TFMR_FSOS
, SSC_FSOS_POSITIVE
) |
593 SSC_BF(TFMR_DATNB
, channels
- 1) |
594 SSC_BIT(TFMR_MSBF
) | SSC_BF(TFMR_DATLEN
, bits
- 1));
598 case SND_SOC_DAIFMT_DSP_A
| SND_SOC_DAIFMT_CBM_CFM
:
600 pr_warning("at32-ssc: unsupported DAI format 0x%x\n",
605 pr_debug("at32-ssc: RCMR=%08x RFMR=%08x TCMR=%08x TFMR=%08x\n",
606 rcmr
, rfmr
, tcmr
, tfmr
);
609 if (!ssc_p
->initialized
) {
610 /* enable peripheral clock */
611 pr_debug("at32-ssc: Starting clock\n");
612 clk_enable(ssc_p
->ssc
->clk
);
614 /* Reset the SSC and its PDC registers */
615 ssc_writel(ssc_p
->ssc
->regs
, CR
, SSC_BIT(CR_SWRST
));
617 ssc_writel(ssc_p
->ssc
->regs
, PDC_RPR
, 0);
618 ssc_writel(ssc_p
->ssc
->regs
, PDC_RCR
, 0);
619 ssc_writel(ssc_p
->ssc
->regs
, PDC_RNPR
, 0);
620 ssc_writel(ssc_p
->ssc
->regs
, PDC_RNCR
, 0);
622 ssc_writel(ssc_p
->ssc
->regs
, PDC_TPR
, 0);
623 ssc_writel(ssc_p
->ssc
->regs
, PDC_TCR
, 0);
624 ssc_writel(ssc_p
->ssc
->regs
, PDC_TNPR
, 0);
625 ssc_writel(ssc_p
->ssc
->regs
, PDC_TNCR
, 0);
627 ret
= request_irq(ssc_p
->ssc
->irq
, at32_ssc_interrupt
, 0,
630 pr_warning("at32-ssc: request irq failed (%d)\n", ret
);
631 pr_debug("at32-ssc: Stopping clock\n");
632 clk_disable(ssc_p
->ssc
->clk
);
636 ssc_p
->initialized
= 1;
639 /* Set SSC clock mode register */
640 ssc_writel(ssc_p
->ssc
->regs
, CMR
, ssc_p
->cmr_div
);
642 /* set receive clock mode and format */
643 ssc_writel(ssc_p
->ssc
->regs
, RCMR
, rcmr
);
644 ssc_writel(ssc_p
->ssc
->regs
, RFMR
, rfmr
);
646 /* set transmit clock mode and format */
647 ssc_writel(ssc_p
->ssc
->regs
, TCMR
, tcmr
);
648 ssc_writel(ssc_p
->ssc
->regs
, TFMR
, tfmr
);
650 pr_debug("at32-ssc: SSC initialized\n");
656 static int at32_ssc_prepare(struct snd_pcm_substream
*substream
)
658 struct snd_soc_pcm_runtime
*rtd
= substream
->private_data
;
659 struct at32_ssc_info
*ssc_p
= &ssc_info
[rtd
->dai
->cpu_dai
->id
];
660 struct at32_pcm_dma_params
*dma_params
;
662 dma_params
= ssc_p
->dma_params
[substream
->stream
];
664 ssc_writel(dma_params
->ssc
->regs
, CR
, dma_params
->mask
->ssc_enable
);
672 static int at32_ssc_suspend(struct platform_device
*pdev
,
673 struct snd_soc_dai
*cpu_dai
)
675 struct at32_ssc_info
*ssc_p
;
677 if (!cpu_dai
->active
)
680 ssc_p
= &ssc_info
[cpu_dai
->id
];
682 /* Save the status register before disabling transmit and receive */
683 ssc_p
->ssc_state
.ssc_sr
= ssc_readl(ssc_p
->ssc
->regs
, SR
);
684 ssc_writel(ssc_p
->ssc
->regs
, CR
, SSC_BIT(CR_TXDIS
) | SSC_BIT(CR_RXDIS
));
686 /* Save the current interrupt mask, then disable unmasked interrupts */
687 ssc_p
->ssc_state
.ssc_imr
= ssc_readl(ssc_p
->ssc
->regs
, IMR
);
688 ssc_writel(ssc_p
->ssc
->regs
, IDR
, ssc_p
->ssc_state
.ssc_imr
);
690 ssc_p
->ssc_state
.ssc_cmr
= ssc_readl(ssc_p
->ssc
->regs
, CMR
);
691 ssc_p
->ssc_state
.ssc_rcmr
= ssc_readl(ssc_p
->ssc
->regs
, RCMR
);
692 ssc_p
->ssc_state
.ssc_rfmr
= ssc_readl(ssc_p
->ssc
->regs
, RFMR
);
693 ssc_p
->ssc_state
.ssc_tcmr
= ssc_readl(ssc_p
->ssc
->regs
, TCMR
);
694 ssc_p
->ssc_state
.ssc_tfmr
= ssc_readl(ssc_p
->ssc
->regs
, TFMR
);
701 static int at32_ssc_resume(struct platform_device
*pdev
,
702 struct snd_soc_dai
*cpu_dai
)
704 struct at32_ssc_info
*ssc_p
;
707 if (!cpu_dai
->active
)
710 ssc_p
= &ssc_info
[cpu_dai
->id
];
712 /* restore SSC register settings */
713 ssc_writel(ssc_p
->ssc
->regs
, TFMR
, ssc_p
->ssc_state
.ssc_tfmr
);
714 ssc_writel(ssc_p
->ssc
->regs
, TCMR
, ssc_p
->ssc_state
.ssc_tcmr
);
715 ssc_writel(ssc_p
->ssc
->regs
, RFMR
, ssc_p
->ssc_state
.ssc_rfmr
);
716 ssc_writel(ssc_p
->ssc
->regs
, RCMR
, ssc_p
->ssc_state
.ssc_rcmr
);
717 ssc_writel(ssc_p
->ssc
->regs
, CMR
, ssc_p
->ssc_state
.ssc_cmr
);
719 /* re-enable interrupts */
720 ssc_writel(ssc_p
->ssc
->regs
, IER
, ssc_p
->ssc_state
.ssc_imr
);
722 /* Re-enable recieve and transmit as appropriate */
725 (ssc_p
->ssc_state
.ssc_sr
& SSC_BIT(SR_RXEN
)) ? SSC_BIT(CR_RXEN
) : 0;
727 (ssc_p
->ssc_state
.ssc_sr
& SSC_BIT(SR_TXEN
)) ? SSC_BIT(CR_TXEN
) : 0;
728 ssc_writel(ssc_p
->ssc
->regs
, CR
, cr
);
732 #else /* CONFIG_PM */
733 # define at32_ssc_suspend NULL
734 # define at32_ssc_resume NULL
735 #endif /* CONFIG_PM */
738 #define AT32_SSC_RATES \
739 (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | SNDRV_PCM_RATE_16000 | \
740 SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \
741 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000)
744 #define AT32_SSC_FORMATS \
745 (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16 | \
746 SNDRV_PCM_FMTBIT_S24 | SNDRV_PCM_FMTBIT_S32)
749 struct snd_soc_dai at32_ssc_dai
[NUM_SSC_DEVICES
] = {
753 .type
= SND_SOC_DAI_PCM
,
754 .suspend
= at32_ssc_suspend
,
755 .resume
= at32_ssc_resume
,
759 .rates
= AT32_SSC_RATES
,
760 .formats
= AT32_SSC_FORMATS
,
765 .rates
= AT32_SSC_RATES
,
766 .formats
= AT32_SSC_FORMATS
,
769 .startup
= at32_ssc_startup
,
770 .shutdown
= at32_ssc_shutdown
,
771 .prepare
= at32_ssc_prepare
,
772 .hw_params
= at32_ssc_hw_params
,
775 .set_sysclk
= at32_ssc_set_dai_sysclk
,
776 .set_fmt
= at32_ssc_set_dai_fmt
,
777 .set_clkdiv
= at32_ssc_set_dai_clkdiv
,
779 .private_data
= &ssc_info
[0],
784 .type
= SND_SOC_DAI_PCM
,
785 .suspend
= at32_ssc_suspend
,
786 .resume
= at32_ssc_resume
,
790 .rates
= AT32_SSC_RATES
,
791 .formats
= AT32_SSC_FORMATS
,
796 .rates
= AT32_SSC_RATES
,
797 .formats
= AT32_SSC_FORMATS
,
800 .startup
= at32_ssc_startup
,
801 .shutdown
= at32_ssc_shutdown
,
802 .prepare
= at32_ssc_prepare
,
803 .hw_params
= at32_ssc_hw_params
,
806 .set_sysclk
= at32_ssc_set_dai_sysclk
,
807 .set_fmt
= at32_ssc_set_dai_fmt
,
808 .set_clkdiv
= at32_ssc_set_dai_clkdiv
,
810 .private_data
= &ssc_info
[1],
815 .type
= SND_SOC_DAI_PCM
,
816 .suspend
= at32_ssc_suspend
,
817 .resume
= at32_ssc_resume
,
821 .rates
= AT32_SSC_RATES
,
822 .formats
= AT32_SSC_FORMATS
,
827 .rates
= AT32_SSC_RATES
,
828 .formats
= AT32_SSC_FORMATS
,
831 .startup
= at32_ssc_startup
,
832 .shutdown
= at32_ssc_shutdown
,
833 .prepare
= at32_ssc_prepare
,
834 .hw_params
= at32_ssc_hw_params
,
837 .set_sysclk
= at32_ssc_set_dai_sysclk
,
838 .set_fmt
= at32_ssc_set_dai_fmt
,
839 .set_clkdiv
= at32_ssc_set_dai_clkdiv
,
841 .private_data
= &ssc_info
[2],
844 EXPORT_SYMBOL_GPL(at32_ssc_dai
);
847 MODULE_AUTHOR("Geoffrey Wossum <gwossum@acm.org>");
848 MODULE_DESCRIPTION("AT32 SSC ASoC Interface");
849 MODULE_LICENSE("GPL");