treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 156
[linux-block.git] / sound / soc / atmel / atmel_ssc_dai.c
CommitLineData
1a59d1b8 1// SPDX-License-Identifier: GPL-2.0-or-later
6c742509
SG
2/*
3 * atmel_ssc_dai.c -- ALSA SoC ATMEL SSC Audio Layer Platform driver
4 *
5 * Copyright (C) 2005 SAN People
6 * Copyright (C) 2008 Atmel
7 *
8 * Author: Sedji Gaouaou <sedji.gaouaou@atmel.com>
9 * ATMEL CORP.
10 *
11 * Based on at91-ssc.c by
12 * Frank Mandarino <fmandarino@endrelia.com>
13 * Based on pxa2xx Platform drivers by
64ca0404 14 * Liam Girdwood <lrg@slimlogic.co.uk>
6c742509
SG
15 */
16
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>
24
25#include <linux/atmel-ssc.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>
31
6c742509
SG
32#include "atmel-pcm.h"
33#include "atmel_ssc_dai.h"
34
35
6c742509 36#define NUM_SSC_DEVICES 3
6c742509
SG
37
38/*
39 * SSC PDC registers required by the PCM DMA engine.
40 */
41static struct atmel_pdc_regs pdc_tx_reg = {
42 .xpr = ATMEL_PDC_TPR,
43 .xcr = ATMEL_PDC_TCR,
44 .xnpr = ATMEL_PDC_TNPR,
45 .xncr = ATMEL_PDC_TNCR,
46};
47
48static struct atmel_pdc_regs pdc_rx_reg = {
49 .xpr = ATMEL_PDC_RPR,
50 .xcr = ATMEL_PDC_RCR,
51 .xnpr = ATMEL_PDC_RNPR,
52 .xncr = ATMEL_PDC_RNCR,
53};
54
55/*
56 * SSC & PDC status bits for transmit and receive.
57 */
58static struct atmel_ssc_mask ssc_tx_mask = {
59 .ssc_enable = SSC_BIT(CR_TXEN),
60 .ssc_disable = SSC_BIT(CR_TXDIS),
61 .ssc_endx = SSC_BIT(SR_ENDTX),
62 .ssc_endbuf = SSC_BIT(SR_TXBUFE),
f1b0dd8b 63 .ssc_error = SSC_BIT(SR_OVRUN),
6c742509
SG
64 .pdc_enable = ATMEL_PDC_TXTEN,
65 .pdc_disable = ATMEL_PDC_TXTDIS,
66};
67
68static struct atmel_ssc_mask ssc_rx_mask = {
69 .ssc_enable = SSC_BIT(CR_RXEN),
70 .ssc_disable = SSC_BIT(CR_RXDIS),
71 .ssc_endx = SSC_BIT(SR_ENDRX),
72 .ssc_endbuf = SSC_BIT(SR_RXBUFF),
f1b0dd8b 73 .ssc_error = SSC_BIT(SR_OVRUN),
6c742509
SG
74 .pdc_enable = ATMEL_PDC_RXTEN,
75 .pdc_disable = ATMEL_PDC_RXTDIS,
76};
77
78
79/*
80 * DMA parameters.
81 */
82static struct atmel_pcm_dma_params ssc_dma_params[NUM_SSC_DEVICES][2] = {
83 {{
84 .name = "SSC0 PCM out",
85 .pdc = &pdc_tx_reg,
86 .mask = &ssc_tx_mask,
87 },
88 {
89 .name = "SSC0 PCM in",
90 .pdc = &pdc_rx_reg,
91 .mask = &ssc_rx_mask,
92 } },
6c742509
SG
93 {{
94 .name = "SSC1 PCM out",
95 .pdc = &pdc_tx_reg,
96 .mask = &ssc_tx_mask,
97 },
98 {
99 .name = "SSC1 PCM in",
100 .pdc = &pdc_rx_reg,
101 .mask = &ssc_rx_mask,
102 } },
103 {{
104 .name = "SSC2 PCM out",
105 .pdc = &pdc_tx_reg,
106 .mask = &ssc_tx_mask,
107 },
108 {
109 .name = "SSC2 PCM in",
110 .pdc = &pdc_rx_reg,
111 .mask = &ssc_rx_mask,
112 } },
6c742509
SG
113};
114
115
116static struct atmel_ssc_info ssc_info[NUM_SSC_DEVICES] = {
117 {
118 .name = "ssc0",
119 .lock = __SPIN_LOCK_UNLOCKED(ssc_info[0].lock),
120 .dir_mask = SSC_DIR_MASK_UNUSED,
121 .initialized = 0,
122 },
6c742509
SG
123 {
124 .name = "ssc1",
125 .lock = __SPIN_LOCK_UNLOCKED(ssc_info[1].lock),
126 .dir_mask = SSC_DIR_MASK_UNUSED,
127 .initialized = 0,
128 },
129 {
130 .name = "ssc2",
131 .lock = __SPIN_LOCK_UNLOCKED(ssc_info[2].lock),
132 .dir_mask = SSC_DIR_MASK_UNUSED,
133 .initialized = 0,
134 },
6c742509
SG
135};
136
137
138/*
139 * SSC interrupt handler. Passes PDC interrupts to the DMA
140 * interrupt handler in the PCM driver.
141 */
142static irqreturn_t atmel_ssc_interrupt(int irq, void *dev_id)
143{
144 struct atmel_ssc_info *ssc_p = dev_id;
145 struct atmel_pcm_dma_params *dma_params;
146 u32 ssc_sr;
147 u32 ssc_substream_mask;
148 int i;
149
150 ssc_sr = (unsigned long)ssc_readl(ssc_p->ssc->regs, SR)
151 & (unsigned long)ssc_readl(ssc_p->ssc->regs, IMR);
152
153 /*
154 * Loop through the substreams attached to this SSC. If
155 * a DMA-related interrupt occurred on that substream, call
156 * the DMA interrupt handler function, if one has been
157 * registered in the dma_params structure by the PCM driver.
158 */
159 for (i = 0; i < ARRAY_SIZE(ssc_p->dma_params); i++) {
160 dma_params = ssc_p->dma_params[i];
161
162 if ((dma_params != NULL) &&
163 (dma_params->dma_intr_handler != NULL)) {
164 ssc_substream_mask = (dma_params->mask->ssc_endx |
165 dma_params->mask->ssc_endbuf);
166 if (ssc_sr & ssc_substream_mask) {
167 dma_params->dma_intr_handler(ssc_sr,
168 dma_params->
169 substream);
170 }
171 }
172 }
173
174 return IRQ_HANDLED;
175}
176
b6d6c6e9
PR
177/*
178 * When the bit clock is input, limit the maximum rate according to the
179 * Serial Clock Ratio Considerations section from the SSC documentation:
180 *
181 * The Transmitter and the Receiver can be programmed to operate
182 * with the clock signals provided on either the TK or RK pins.
183 * This allows the SSC to support many slave-mode data transfers.
184 * In this case, the maximum clock speed allowed on the RK pin is:
185 * - Peripheral clock divided by 2 if Receiver Frame Synchro is input
186 * - Peripheral clock divided by 3 if Receiver Frame Synchro is output
187 * In addition, the maximum clock speed allowed on the TK pin is:
188 * - Peripheral clock divided by 6 if Transmit Frame Synchro is input
189 * - Peripheral clock divided by 2 if Transmit Frame Synchro is output
190 *
191 * When the bit clock is output, limit the rate according to the
192 * SSC divider restrictions.
193 */
194static int atmel_ssc_hw_rule_rate(struct snd_pcm_hw_params *params,
195 struct snd_pcm_hw_rule *rule)
196{
197 struct atmel_ssc_info *ssc_p = rule->private;
198 struct ssc_device *ssc = ssc_p->ssc;
199 struct snd_interval *i = hw_param_interval(params, rule->var);
200 struct snd_interval t;
201 struct snd_ratnum r = {
202 .den_min = 1,
203 .den_max = 4095,
204 .den_step = 1,
205 };
206 unsigned int num = 0, den = 0;
207 int frame_size;
208 int mck_div = 2;
209 int ret;
210
211 frame_size = snd_soc_params_to_frame_size(params);
212 if (frame_size < 0)
213 return frame_size;
214
215 switch (ssc_p->daifmt & SND_SOC_DAIFMT_MASTER_MASK) {
216 case SND_SOC_DAIFMT_CBM_CFS:
217 if ((ssc_p->dir_mask & SSC_DIR_MASK_CAPTURE)
218 && ssc->clk_from_rk_pin)
219 /* Receiver Frame Synchro (i.e. capture)
220 * is output (format is _CFS) and the RK pin
221 * is used for input (format is _CBM_).
222 */
223 mck_div = 3;
224 break;
225
226 case SND_SOC_DAIFMT_CBM_CFM:
227 if ((ssc_p->dir_mask & SSC_DIR_MASK_PLAYBACK)
228 && !ssc->clk_from_rk_pin)
229 /* Transmit Frame Synchro (i.e. playback)
230 * is input (format is _CFM) and the TK pin
231 * is used for input (format _CBM_ but not
232 * using the RK pin).
233 */
234 mck_div = 6;
235 break;
236 }
237
238 switch (ssc_p->daifmt & SND_SOC_DAIFMT_MASTER_MASK) {
239 case SND_SOC_DAIFMT_CBS_CFS:
240 r.num = ssc_p->mck_rate / mck_div / frame_size;
241
242 ret = snd_interval_ratnum(i, 1, &r, &num, &den);
243 if (ret >= 0 && den && rule->var == SNDRV_PCM_HW_PARAM_RATE) {
244 params->rate_num = num;
245 params->rate_den = den;
246 }
247 break;
248
249 case SND_SOC_DAIFMT_CBM_CFS:
250 case SND_SOC_DAIFMT_CBM_CFM:
251 t.min = 8000;
252 t.max = ssc_p->mck_rate / mck_div / frame_size;
253 t.openmin = t.openmax = 0;
254 t.integer = 0;
255 ret = snd_interval_refine(i, &t);
256 break;
257
258 default:
259 ret = -EINVAL;
260 break;
261 }
262
263 return ret;
264}
6c742509
SG
265
266/*-------------------------------------------------------------------------*\
267 * DAI functions
268\*-------------------------------------------------------------------------*/
269/*
270 * Startup. Only that one substream allowed in each direction.
271 */
dee89c4d
MB
272static int atmel_ssc_startup(struct snd_pcm_substream *substream,
273 struct snd_soc_dai *dai)
6c742509 274{
c706f2e5
SW
275 struct platform_device *pdev = to_platform_device(dai->dev);
276 struct atmel_ssc_info *ssc_p = &ssc_info[pdev->id];
01f00d55
BS
277 struct atmel_pcm_dma_params *dma_params;
278 int dir, dir_mask;
b6d6c6e9 279 int ret;
6c742509 280
56113f6e 281 pr_debug("atmel_ssc_startup: SSC_SR=0x%x\n",
6c742509
SG
282 ssc_readl(ssc_p->ssc->regs, SR));
283
cbaadf0f
BS
284 /* Enable PMC peripheral clock for this SSC */
285 pr_debug("atmel_ssc_dai: Starting clock\n");
286 clk_enable(ssc_p->ssc->clk);
b6d6c6e9 287 ssc_p->mck_rate = clk_get_rate(ssc_p->ssc->clk);
cbaadf0f 288
3e103a65
CH
289 /* Reset the SSC unless initialized to keep it in a clean state */
290 if (!ssc_p->initialized)
291 ssc_writel(ssc_p->ssc->regs, CR, SSC_BIT(CR_SWRST));
cbaadf0f 292
01f00d55
BS
293 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
294 dir = 0;
6c742509 295 dir_mask = SSC_DIR_MASK_PLAYBACK;
01f00d55
BS
296 } else {
297 dir = 1;
6c742509 298 dir_mask = SSC_DIR_MASK_CAPTURE;
01f00d55
BS
299 }
300
b6d6c6e9
PR
301 ret = snd_pcm_hw_rule_add(substream->runtime, 0,
302 SNDRV_PCM_HW_PARAM_RATE,
303 atmel_ssc_hw_rule_rate,
304 ssc_p,
305 SNDRV_PCM_HW_PARAM_FRAME_BITS,
306 SNDRV_PCM_HW_PARAM_CHANNELS, -1);
307 if (ret < 0) {
308 dev_err(dai->dev, "Failed to specify rate rule: %d\n", ret);
309 return ret;
310 }
311
e401029e 312 dma_params = &ssc_dma_params[pdev->id][dir];
01f00d55
BS
313 dma_params->ssc = ssc_p->ssc;
314 dma_params->substream = substream;
315
316 ssc_p->dma_params[dir] = dma_params;
317
318 snd_soc_dai_set_dma_data(dai, substream, dma_params);
6c742509
SG
319
320 spin_lock_irq(&ssc_p->lock);
321 if (ssc_p->dir_mask & dir_mask) {
322 spin_unlock_irq(&ssc_p->lock);
323 return -EBUSY;
324 }
325 ssc_p->dir_mask |= dir_mask;
326 spin_unlock_irq(&ssc_p->lock);
327
328 return 0;
329}
330
331/*
332 * Shutdown. Clear DMA parameters and shutdown the SSC if there
333 * are no other substreams open.
334 */
dee89c4d
MB
335static void atmel_ssc_shutdown(struct snd_pcm_substream *substream,
336 struct snd_soc_dai *dai)
6c742509 337{
c706f2e5
SW
338 struct platform_device *pdev = to_platform_device(dai->dev);
339 struct atmel_ssc_info *ssc_p = &ssc_info[pdev->id];
6c742509
SG
340 struct atmel_pcm_dma_params *dma_params;
341 int dir, dir_mask;
342
343 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
344 dir = 0;
345 else
346 dir = 1;
347
348 dma_params = ssc_p->dma_params[dir];
349
350 if (dma_params != NULL) {
6c742509
SG
351 dma_params->ssc = NULL;
352 dma_params->substream = NULL;
353 ssc_p->dma_params[dir] = NULL;
354 }
355
356 dir_mask = 1 << dir;
357
358 spin_lock_irq(&ssc_p->lock);
359 ssc_p->dir_mask &= ~dir_mask;
360 if (!ssc_p->dir_mask) {
361 if (ssc_p->initialized) {
6c742509
SG
362 free_irq(ssc_p->ssc->irq, ssc_p);
363 ssc_p->initialized = 0;
364 }
365
366 /* Reset the SSC */
367 ssc_writel(ssc_p->ssc->regs, CR, SSC_BIT(CR_SWRST));
368 /* Clear the SSC dividers */
369 ssc_p->cmr_div = ssc_p->tcmr_period = ssc_p->rcmr_period = 0;
a85787ed 370 ssc_p->forced_divider = 0;
6c742509
SG
371 }
372 spin_unlock_irq(&ssc_p->lock);
cbaadf0f
BS
373
374 /* Shutdown the SSC clock. */
375 pr_debug("atmel_ssc_dai: Stopping clock\n");
376 clk_disable(ssc_p->ssc->clk);
6c742509
SG
377}
378
379
380/*
381 * Record the DAI format for use in hw_params().
382 */
383static int atmel_ssc_set_dai_fmt(struct snd_soc_dai *cpu_dai,
384 unsigned int fmt)
385{
c706f2e5
SW
386 struct platform_device *pdev = to_platform_device(cpu_dai->dev);
387 struct atmel_ssc_info *ssc_p = &ssc_info[pdev->id];
6c742509
SG
388
389 ssc_p->daifmt = fmt;
390 return 0;
391}
392
393/*
394 * Record SSC clock dividers for use in hw_params().
395 */
396static int atmel_ssc_set_dai_clkdiv(struct snd_soc_dai *cpu_dai,
397 int div_id, int div)
398{
c706f2e5
SW
399 struct platform_device *pdev = to_platform_device(cpu_dai->dev);
400 struct atmel_ssc_info *ssc_p = &ssc_info[pdev->id];
6c742509
SG
401
402 switch (div_id) {
403 case ATMEL_SSC_CMR_DIV:
404 /*
405 * The same master clock divider is used for both
406 * transmit and receive, so if a value has already
407 * been set, it must match this value.
408 */
eb58960e
PR
409 if (ssc_p->dir_mask !=
410 (SSC_DIR_MASK_PLAYBACK | SSC_DIR_MASK_CAPTURE))
411 ssc_p->cmr_div = div;
412 else if (ssc_p->cmr_div == 0)
6c742509
SG
413 ssc_p->cmr_div = div;
414 else
415 if (div != ssc_p->cmr_div)
416 return -EBUSY;
a85787ed 417 ssc_p->forced_divider |= BIT(ATMEL_SSC_CMR_DIV);
6c742509
SG
418 break;
419
420 case ATMEL_SSC_TCMR_PERIOD:
421 ssc_p->tcmr_period = div;
a85787ed 422 ssc_p->forced_divider |= BIT(ATMEL_SSC_TCMR_PERIOD);
6c742509
SG
423 break;
424
425 case ATMEL_SSC_RCMR_PERIOD:
426 ssc_p->rcmr_period = div;
a85787ed 427 ssc_p->forced_divider |= BIT(ATMEL_SSC_RCMR_PERIOD);
6c742509
SG
428 break;
429
430 default:
431 return -EINVAL;
432 }
433
434 return 0;
435}
436
a85787ed
PR
437/* Is the cpu-dai master of the frame clock? */
438static int atmel_ssc_cfs(struct atmel_ssc_info *ssc_p)
439{
440 switch (ssc_p->daifmt & SND_SOC_DAIFMT_MASTER_MASK) {
441 case SND_SOC_DAIFMT_CBM_CFS:
442 case SND_SOC_DAIFMT_CBS_CFS:
443 return 1;
444 }
445 return 0;
446}
447
448/* Is the cpu-dai master of the bit clock? */
449static int atmel_ssc_cbs(struct atmel_ssc_info *ssc_p)
450{
451 switch (ssc_p->daifmt & SND_SOC_DAIFMT_MASTER_MASK) {
452 case SND_SOC_DAIFMT_CBS_CFM:
453 case SND_SOC_DAIFMT_CBS_CFS:
454 return 1;
455 }
456 return 0;
457}
458
6c742509
SG
459/*
460 * Configure the SSC.
461 */
462static int atmel_ssc_hw_params(struct snd_pcm_substream *substream,
dee89c4d
MB
463 struct snd_pcm_hw_params *params,
464 struct snd_soc_dai *dai)
6c742509 465{
c706f2e5
SW
466 struct platform_device *pdev = to_platform_device(dai->dev);
467 int id = pdev->id;
6c742509 468 struct atmel_ssc_info *ssc_p = &ssc_info[id];
048d4ff8 469 struct ssc_device *ssc = ssc_p->ssc;
6c742509
SG
470 struct atmel_pcm_dma_params *dma_params;
471 int dir, channels, bits;
472 u32 tfmr, rfmr, tcmr, rcmr;
6c742509 473 int ret;
dfaf5356 474 int fslen, fslen_ext;
a85787ed
PR
475 u32 cmr_div;
476 u32 tcmr_period;
477 u32 rcmr_period;
6c742509
SG
478
479 /*
480 * Currently, there is only one set of dma params for
481 * each direction. If more are added, this code will
482 * have to be changed to select the proper set.
483 */
484 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
485 dir = 0;
486 else
487 dir = 1;
488
a85787ed
PR
489 /*
490 * If the cpu dai should provide BCLK, but noone has provided the
491 * divider needed for that to work, fall back to something sensible.
492 */
493 cmr_div = ssc_p->cmr_div;
494 if (!(ssc_p->forced_divider & BIT(ATMEL_SSC_CMR_DIV)) &&
495 atmel_ssc_cbs(ssc_p)) {
496 int bclk_rate = snd_soc_params_to_bclk(params);
497
498 if (bclk_rate < 0) {
499 dev_err(dai->dev, "unable to calculate cmr_div: %d\n",
500 bclk_rate);
501 return bclk_rate;
502 }
503
504 cmr_div = DIV_ROUND_CLOSEST(ssc_p->mck_rate, 2 * bclk_rate);
505 }
506
507 /*
508 * If the cpu dai should provide LRCLK, but noone has provided the
509 * dividers needed for that to work, fall back to something sensible.
510 */
511 tcmr_period = ssc_p->tcmr_period;
512 rcmr_period = ssc_p->rcmr_period;
513 if (atmel_ssc_cfs(ssc_p)) {
514 int frame_size = snd_soc_params_to_frame_size(params);
515
516 if (frame_size < 0) {
517 dev_err(dai->dev,
518 "unable to calculate tx/rx cmr_period: %d\n",
519 frame_size);
520 return frame_size;
521 }
522
523 if (!(ssc_p->forced_divider & BIT(ATMEL_SSC_TCMR_PERIOD)))
524 tcmr_period = frame_size / 2 - 1;
525 if (!(ssc_p->forced_divider & BIT(ATMEL_SSC_RCMR_PERIOD)))
526 rcmr_period = frame_size / 2 - 1;
527 }
528
01f00d55 529 dma_params = ssc_p->dma_params[dir];
6c742509
SG
530
531 channels = params_channels(params);
532
533 /*
534 * Determine sample size in bits and the PDC increment.
535 */
536 switch (params_format(params)) {
537 case SNDRV_PCM_FORMAT_S8:
538 bits = 8;
539 dma_params->pdc_xfer_size = 1;
540 break;
541 case SNDRV_PCM_FORMAT_S16_LE:
542 bits = 16;
543 dma_params->pdc_xfer_size = 2;
544 break;
545 case SNDRV_PCM_FORMAT_S24_LE:
546 bits = 24;
547 dma_params->pdc_xfer_size = 4;
548 break;
549 case SNDRV_PCM_FORMAT_S32_LE:
550 bits = 32;
551 dma_params->pdc_xfer_size = 4;
552 break;
553 default:
554 printk(KERN_WARNING "atmel_ssc_dai: unsupported PCM format");
555 return -EINVAL;
556 }
557
6c742509
SG
558 /*
559 * Compute SSC register settings.
560 */
561 switch (ssc_p->daifmt
562 & (SND_SOC_DAIFMT_FORMAT_MASK | SND_SOC_DAIFMT_MASTER_MASK)) {
563
564 case SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS:
565 /*
566 * I2S format, SSC provides BCLK and LRC clocks.
567 *
568 * The SSC transmit and receive clocks are generated
569 * from the MCK divider, and the BCLK signal
570 * is output on the SSC TK line.
571 */
dfaf5356
BS
572
573 if (bits > 16 && !ssc->pdata->has_fslen_ext) {
574 dev_err(dai->dev,
575 "sample size %d is too large for SSC device\n",
576 bits);
577 return -EINVAL;
578 }
579
580 fslen_ext = (bits - 1) / 16;
581 fslen = (bits - 1) % 16;
582
a85787ed 583 rcmr = SSC_BF(RCMR_PERIOD, rcmr_period)
6c742509
SG
584 | SSC_BF(RCMR_STTDLY, START_DELAY)
585 | SSC_BF(RCMR_START, SSC_START_FALLING_RF)
586 | SSC_BF(RCMR_CKI, SSC_CKI_RISING)
587 | SSC_BF(RCMR_CKO, SSC_CKO_NONE)
588 | SSC_BF(RCMR_CKS, SSC_CKS_DIV);
589
dfaf5356
BS
590 rfmr = SSC_BF(RFMR_FSLEN_EXT, fslen_ext)
591 | SSC_BF(RFMR_FSEDGE, SSC_FSEDGE_POSITIVE)
6c742509 592 | SSC_BF(RFMR_FSOS, SSC_FSOS_NEGATIVE)
dfaf5356 593 | SSC_BF(RFMR_FSLEN, fslen)
6c742509
SG
594 | SSC_BF(RFMR_DATNB, (channels - 1))
595 | SSC_BIT(RFMR_MSBF)
596 | SSC_BF(RFMR_LOOP, 0)
597 | SSC_BF(RFMR_DATLEN, (bits - 1));
598
a85787ed 599 tcmr = SSC_BF(TCMR_PERIOD, tcmr_period)
6c742509
SG
600 | SSC_BF(TCMR_STTDLY, START_DELAY)
601 | SSC_BF(TCMR_START, SSC_START_FALLING_RF)
602 | SSC_BF(TCMR_CKI, SSC_CKI_FALLING)
603 | SSC_BF(TCMR_CKO, SSC_CKO_CONTINUOUS)
604 | SSC_BF(TCMR_CKS, SSC_CKS_DIV);
605
dfaf5356
BS
606 tfmr = SSC_BF(TFMR_FSLEN_EXT, fslen_ext)
607 | SSC_BF(TFMR_FSEDGE, SSC_FSEDGE_POSITIVE)
6c742509
SG
608 | SSC_BF(TFMR_FSDEN, 0)
609 | SSC_BF(TFMR_FSOS, SSC_FSOS_NEGATIVE)
dfaf5356 610 | SSC_BF(TFMR_FSLEN, fslen)
6c742509
SG
611 | SSC_BF(TFMR_DATNB, (channels - 1))
612 | SSC_BIT(TFMR_MSBF)
613 | SSC_BF(TFMR_DATDEF, 0)
614 | SSC_BF(TFMR_DATLEN, (bits - 1));
615 break;
616
617 case SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM:
67d1aed0 618 /* I2S format, CODEC supplies BCLK and LRC clocks. */
6c742509
SG
619 rcmr = SSC_BF(RCMR_PERIOD, 0)
620 | SSC_BF(RCMR_STTDLY, START_DELAY)
a43bd7e1 621 | SSC_BF(RCMR_START, SSC_START_FALLING_RF)
6c742509
SG
622 | SSC_BF(RCMR_CKI, SSC_CKI_RISING)
623 | SSC_BF(RCMR_CKO, SSC_CKO_NONE)
048d4ff8
BS
624 | SSC_BF(RCMR_CKS, ssc->clk_from_rk_pin ?
625 SSC_CKS_PIN : SSC_CKS_CLOCK);
6c742509
SG
626
627 rfmr = SSC_BF(RFMR_FSEDGE, SSC_FSEDGE_POSITIVE)
628 | SSC_BF(RFMR_FSOS, SSC_FSOS_NONE)
629 | SSC_BF(RFMR_FSLEN, 0)
a43bd7e1 630 | SSC_BF(RFMR_DATNB, (channels - 1))
6c742509
SG
631 | SSC_BIT(RFMR_MSBF)
632 | SSC_BF(RFMR_LOOP, 0)
633 | SSC_BF(RFMR_DATLEN, (bits - 1));
634
635 tcmr = SSC_BF(TCMR_PERIOD, 0)
636 | SSC_BF(TCMR_STTDLY, START_DELAY)
a43bd7e1 637 | SSC_BF(TCMR_START, SSC_START_FALLING_RF)
6c742509
SG
638 | SSC_BF(TCMR_CKI, SSC_CKI_FALLING)
639 | SSC_BF(TCMR_CKO, SSC_CKO_NONE)
048d4ff8
BS
640 | SSC_BF(TCMR_CKS, ssc->clk_from_rk_pin ?
641 SSC_CKS_CLOCK : SSC_CKS_PIN);
6c742509
SG
642
643 tfmr = SSC_BF(TFMR_FSEDGE, SSC_FSEDGE_POSITIVE)
644 | SSC_BF(TFMR_FSDEN, 0)
645 | SSC_BF(TFMR_FSOS, SSC_FSOS_NONE)
646 | SSC_BF(TFMR_FSLEN, 0)
a43bd7e1 647 | SSC_BF(TFMR_DATNB, (channels - 1))
6c742509
SG
648 | SSC_BIT(TFMR_MSBF)
649 | SSC_BF(TFMR_DATDEF, 0)
650 | SSC_BF(TFMR_DATLEN, (bits - 1));
651 break;
652
eb527149
PR
653 case SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFS:
654 /* I2S format, CODEC supplies BCLK, SSC supplies LRCLK. */
655 if (bits > 16 && !ssc->pdata->has_fslen_ext) {
656 dev_err(dai->dev,
657 "sample size %d is too large for SSC device\n",
658 bits);
659 return -EINVAL;
660 }
661
662 fslen_ext = (bits - 1) / 16;
663 fslen = (bits - 1) % 16;
664
a85787ed 665 rcmr = SSC_BF(RCMR_PERIOD, rcmr_period)
eb527149
PR
666 | SSC_BF(RCMR_STTDLY, START_DELAY)
667 | SSC_BF(RCMR_START, SSC_START_FALLING_RF)
668 | SSC_BF(RCMR_CKI, SSC_CKI_RISING)
669 | SSC_BF(RCMR_CKO, SSC_CKO_NONE)
670 | SSC_BF(RCMR_CKS, ssc->clk_from_rk_pin ?
671 SSC_CKS_PIN : SSC_CKS_CLOCK);
672
673 rfmr = SSC_BF(RFMR_FSLEN_EXT, fslen_ext)
674 | SSC_BF(RFMR_FSEDGE, SSC_FSEDGE_POSITIVE)
675 | SSC_BF(RFMR_FSOS, SSC_FSOS_NEGATIVE)
676 | SSC_BF(RFMR_FSLEN, fslen)
677 | SSC_BF(RFMR_DATNB, (channels - 1))
678 | SSC_BIT(RFMR_MSBF)
679 | SSC_BF(RFMR_LOOP, 0)
680 | SSC_BF(RFMR_DATLEN, (bits - 1));
681
a85787ed 682 tcmr = SSC_BF(TCMR_PERIOD, tcmr_period)
eb527149
PR
683 | SSC_BF(TCMR_STTDLY, START_DELAY)
684 | SSC_BF(TCMR_START, SSC_START_FALLING_RF)
685 | SSC_BF(TCMR_CKI, SSC_CKI_FALLING)
686 | SSC_BF(TCMR_CKO, SSC_CKO_NONE)
687 | SSC_BF(TCMR_CKS, ssc->clk_from_rk_pin ?
688 SSC_CKS_CLOCK : SSC_CKS_PIN);
689
690 tfmr = SSC_BF(TFMR_FSLEN_EXT, fslen_ext)
691 | SSC_BF(TFMR_FSEDGE, SSC_FSEDGE_NEGATIVE)
692 | SSC_BF(TFMR_FSDEN, 0)
693 | SSC_BF(TFMR_FSOS, SSC_FSOS_NEGATIVE)
694 | SSC_BF(TFMR_FSLEN, fslen)
695 | SSC_BF(TFMR_DATNB, (channels - 1))
6c742509
SG
696 | SSC_BIT(TFMR_MSBF)
697 | SSC_BF(TFMR_DATDEF, 0)
698 | SSC_BF(TFMR_DATLEN, (bits - 1));
699 break;
700
701 case SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_CBS_CFS:
702 /*
703 * DSP/PCM Mode A format, SSC provides BCLK and LRC clocks.
704 *
705 * The SSC transmit and receive clocks are generated from the
706 * MCK divider, and the BCLK signal is output
707 * on the SSC TK line.
708 */
a85787ed 709 rcmr = SSC_BF(RCMR_PERIOD, rcmr_period)
6c742509
SG
710 | SSC_BF(RCMR_STTDLY, 1)
711 | SSC_BF(RCMR_START, SSC_START_RISING_RF)
80833ff0 712 | SSC_BF(RCMR_CKI, SSC_CKI_RISING)
6c742509
SG
713 | SSC_BF(RCMR_CKO, SSC_CKO_NONE)
714 | SSC_BF(RCMR_CKS, SSC_CKS_DIV);
715
716 rfmr = SSC_BF(RFMR_FSEDGE, SSC_FSEDGE_POSITIVE)
717 | SSC_BF(RFMR_FSOS, SSC_FSOS_POSITIVE)
718 | SSC_BF(RFMR_FSLEN, 0)
719 | SSC_BF(RFMR_DATNB, (channels - 1))
720 | SSC_BIT(RFMR_MSBF)
721 | SSC_BF(RFMR_LOOP, 0)
722 | SSC_BF(RFMR_DATLEN, (bits - 1));
723
a85787ed 724 tcmr = SSC_BF(TCMR_PERIOD, tcmr_period)
6c742509
SG
725 | SSC_BF(TCMR_STTDLY, 1)
726 | SSC_BF(TCMR_START, SSC_START_RISING_RF)
20cf2603 727 | SSC_BF(TCMR_CKI, SSC_CKI_FALLING)
6c742509
SG
728 | SSC_BF(TCMR_CKO, SSC_CKO_CONTINUOUS)
729 | SSC_BF(TCMR_CKS, SSC_CKS_DIV);
730
731 tfmr = SSC_BF(TFMR_FSEDGE, SSC_FSEDGE_POSITIVE)
732 | SSC_BF(TFMR_FSDEN, 0)
733 | SSC_BF(TFMR_FSOS, SSC_FSOS_POSITIVE)
734 | SSC_BF(TFMR_FSLEN, 0)
735 | SSC_BF(TFMR_DATNB, (channels - 1))
736 | SSC_BIT(TFMR_MSBF)
737 | SSC_BF(TFMR_DATDEF, 0)
738 | SSC_BF(TFMR_DATLEN, (bits - 1));
739 break;
740
741 case SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_CBM_CFM:
f6a75d95
ZP
742 /*
743 * DSP/PCM Mode A format, CODEC supplies BCLK and LRC clocks.
744 *
f6a75d95
ZP
745 * Data is transferred on first BCLK after LRC pulse rising
746 * edge.If stereo, the right channel data is contiguous with
747 * the left channel data.
748 */
749 rcmr = SSC_BF(RCMR_PERIOD, 0)
750 | SSC_BF(RCMR_STTDLY, START_DELAY)
751 | SSC_BF(RCMR_START, SSC_START_RISING_RF)
80833ff0 752 | SSC_BF(RCMR_CKI, SSC_CKI_RISING)
f6a75d95 753 | SSC_BF(RCMR_CKO, SSC_CKO_NONE)
048d4ff8
BS
754 | SSC_BF(RCMR_CKS, ssc->clk_from_rk_pin ?
755 SSC_CKS_PIN : SSC_CKS_CLOCK);
f6a75d95
ZP
756
757 rfmr = SSC_BF(RFMR_FSEDGE, SSC_FSEDGE_POSITIVE)
758 | SSC_BF(RFMR_FSOS, SSC_FSOS_NONE)
759 | SSC_BF(RFMR_FSLEN, 0)
760 | SSC_BF(RFMR_DATNB, (channels - 1))
761 | SSC_BIT(RFMR_MSBF)
762 | SSC_BF(RFMR_LOOP, 0)
763 | SSC_BF(RFMR_DATLEN, (bits - 1));
764
765 tcmr = SSC_BF(TCMR_PERIOD, 0)
766 | SSC_BF(TCMR_STTDLY, START_DELAY)
767 | SSC_BF(TCMR_START, SSC_START_RISING_RF)
768 | SSC_BF(TCMR_CKI, SSC_CKI_FALLING)
769 | SSC_BF(TCMR_CKO, SSC_CKO_NONE)
048d4ff8
BS
770 | SSC_BF(RCMR_CKS, ssc->clk_from_rk_pin ?
771 SSC_CKS_CLOCK : SSC_CKS_PIN);
f6a75d95
ZP
772
773 tfmr = SSC_BF(TFMR_FSEDGE, SSC_FSEDGE_POSITIVE)
774 | SSC_BF(TFMR_FSDEN, 0)
775 | SSC_BF(TFMR_FSOS, SSC_FSOS_NONE)
776 | SSC_BF(TFMR_FSLEN, 0)
777 | SSC_BF(TFMR_DATNB, (channels - 1))
778 | SSC_BIT(TFMR_MSBF)
779 | SSC_BF(TFMR_DATDEF, 0)
780 | SSC_BF(TFMR_DATLEN, (bits - 1));
781 break;
782
6c742509
SG
783 default:
784 printk(KERN_WARNING "atmel_ssc_dai: unsupported DAI format 0x%x\n",
785 ssc_p->daifmt);
786 return -EINVAL;
6c742509
SG
787 }
788 pr_debug("atmel_ssc_hw_params: "
789 "RCMR=%08x RFMR=%08x TCMR=%08x TFMR=%08x\n",
790 rcmr, rfmr, tcmr, tfmr);
791
792 if (!ssc_p->initialized) {
3fd5b30c
BS
793 if (!ssc_p->ssc->pdata->use_dma) {
794 ssc_writel(ssc_p->ssc->regs, PDC_RPR, 0);
795 ssc_writel(ssc_p->ssc->regs, PDC_RCR, 0);
796 ssc_writel(ssc_p->ssc->regs, PDC_RNPR, 0);
797 ssc_writel(ssc_p->ssc->regs, PDC_RNCR, 0);
798
799 ssc_writel(ssc_p->ssc->regs, PDC_TPR, 0);
800 ssc_writel(ssc_p->ssc->regs, PDC_TCR, 0);
801 ssc_writel(ssc_p->ssc->regs, PDC_TNPR, 0);
802 ssc_writel(ssc_p->ssc->regs, PDC_TNCR, 0);
803 }
6c742509
SG
804
805 ret = request_irq(ssc_p->ssc->irq, atmel_ssc_interrupt, 0,
806 ssc_p->name, ssc_p);
807 if (ret < 0) {
808 printk(KERN_WARNING
809 "atmel_ssc_dai: request_irq failure\n");
7bdeac2e 810 pr_debug("Atmel_ssc_dai: Stopping clock\n");
6c742509
SG
811 clk_disable(ssc_p->ssc->clk);
812 return ret;
813 }
814
815 ssc_p->initialized = 1;
816 }
817
818 /* set SSC clock mode register */
a85787ed 819 ssc_writel(ssc_p->ssc->regs, CMR, cmr_div);
6c742509
SG
820
821 /* set receive clock mode and format */
822 ssc_writel(ssc_p->ssc->regs, RCMR, rcmr);
823 ssc_writel(ssc_p->ssc->regs, RFMR, rfmr);
824
825 /* set transmit clock mode and format */
826 ssc_writel(ssc_p->ssc->regs, TCMR, tcmr);
827 ssc_writel(ssc_p->ssc->regs, TFMR, tfmr);
828
829 pr_debug("atmel_ssc_dai,hw_params: SSC initialized\n");
830 return 0;
831}
832
833
dee89c4d
MB
834static int atmel_ssc_prepare(struct snd_pcm_substream *substream,
835 struct snd_soc_dai *dai)
6c742509 836{
c706f2e5
SW
837 struct platform_device *pdev = to_platform_device(dai->dev);
838 struct atmel_ssc_info *ssc_p = &ssc_info[pdev->id];
6c742509
SG
839 struct atmel_pcm_dma_params *dma_params;
840 int dir;
841
842 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
843 dir = 0;
844 else
845 dir = 1;
846
847 dma_params = ssc_p->dma_params[dir];
848
a8f1f100 849 ssc_writel(ssc_p->ssc->regs, CR, dma_params->mask->ssc_disable);
e0111434 850 ssc_writel(ssc_p->ssc->regs, IDR, dma_params->mask->ssc_error);
6c742509
SG
851
852 pr_debug("%s enabled SSC_SR=0x%08x\n",
853 dir ? "receive" : "transmit",
854 ssc_readl(ssc_p->ssc->regs, SR));
855 return 0;
856}
857
a8f1f100
BS
858static int atmel_ssc_trigger(struct snd_pcm_substream *substream,
859 int cmd, struct snd_soc_dai *dai)
860{
c706f2e5
SW
861 struct platform_device *pdev = to_platform_device(dai->dev);
862 struct atmel_ssc_info *ssc_p = &ssc_info[pdev->id];
a8f1f100
BS
863 struct atmel_pcm_dma_params *dma_params;
864 int dir;
865
866 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
867 dir = 0;
868 else
869 dir = 1;
870
871 dma_params = ssc_p->dma_params[dir];
872
873 switch (cmd) {
874 case SNDRV_PCM_TRIGGER_START:
875 case SNDRV_PCM_TRIGGER_RESUME:
876 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
877 ssc_writel(ssc_p->ssc->regs, CR, dma_params->mask->ssc_enable);
878 break;
879 default:
880 ssc_writel(ssc_p->ssc->regs, CR, dma_params->mask->ssc_disable);
881 break;
882 }
883
884 return 0;
885}
6c742509
SG
886
887#ifdef CONFIG_PM
dc7d7b83 888static int atmel_ssc_suspend(struct snd_soc_dai *cpu_dai)
6c742509
SG
889{
890 struct atmel_ssc_info *ssc_p;
c706f2e5 891 struct platform_device *pdev = to_platform_device(cpu_dai->dev);
6c742509
SG
892
893 if (!cpu_dai->active)
894 return 0;
895
c706f2e5 896 ssc_p = &ssc_info[pdev->id];
6c742509
SG
897
898 /* Save the status register before disabling transmit and receive */
899 ssc_p->ssc_state.ssc_sr = ssc_readl(ssc_p->ssc->regs, SR);
900 ssc_writel(ssc_p->ssc->regs, CR, SSC_BIT(CR_TXDIS) | SSC_BIT(CR_RXDIS));
901
902 /* Save the current interrupt mask, then disable unmasked interrupts */
903 ssc_p->ssc_state.ssc_imr = ssc_readl(ssc_p->ssc->regs, IMR);
904 ssc_writel(ssc_p->ssc->regs, IDR, ssc_p->ssc_state.ssc_imr);
905
906 ssc_p->ssc_state.ssc_cmr = ssc_readl(ssc_p->ssc->regs, CMR);
907 ssc_p->ssc_state.ssc_rcmr = ssc_readl(ssc_p->ssc->regs, RCMR);
908 ssc_p->ssc_state.ssc_rfmr = ssc_readl(ssc_p->ssc->regs, RFMR);
909 ssc_p->ssc_state.ssc_tcmr = ssc_readl(ssc_p->ssc->regs, TCMR);
910 ssc_p->ssc_state.ssc_tfmr = ssc_readl(ssc_p->ssc->regs, TFMR);
911
912 return 0;
913}
914
915
916
dc7d7b83 917static int atmel_ssc_resume(struct snd_soc_dai *cpu_dai)
6c742509
SG
918{
919 struct atmel_ssc_info *ssc_p;
c706f2e5 920 struct platform_device *pdev = to_platform_device(cpu_dai->dev);
6c742509
SG
921 u32 cr;
922
923 if (!cpu_dai->active)
924 return 0;
925
c706f2e5 926 ssc_p = &ssc_info[pdev->id];
6c742509
SG
927
928 /* restore SSC register settings */
929 ssc_writel(ssc_p->ssc->regs, TFMR, ssc_p->ssc_state.ssc_tfmr);
930 ssc_writel(ssc_p->ssc->regs, TCMR, ssc_p->ssc_state.ssc_tcmr);
931 ssc_writel(ssc_p->ssc->regs, RFMR, ssc_p->ssc_state.ssc_rfmr);
932 ssc_writel(ssc_p->ssc->regs, RCMR, ssc_p->ssc_state.ssc_rcmr);
933 ssc_writel(ssc_p->ssc->regs, CMR, ssc_p->ssc_state.ssc_cmr);
934
935 /* re-enable interrupts */
936 ssc_writel(ssc_p->ssc->regs, IER, ssc_p->ssc_state.ssc_imr);
937
25985edc 938 /* Re-enable receive and transmit as appropriate */
6c742509
SG
939 cr = 0;
940 cr |=
941 (ssc_p->ssc_state.ssc_sr & SSC_BIT(SR_RXEN)) ? SSC_BIT(CR_RXEN) : 0;
942 cr |=
943 (ssc_p->ssc_state.ssc_sr & SSC_BIT(SR_TXEN)) ? SSC_BIT(CR_TXEN) : 0;
944 ssc_writel(ssc_p->ssc->regs, CR, cr);
945
946 return 0;
947}
948#else /* CONFIG_PM */
949# define atmel_ssc_suspend NULL
950# define atmel_ssc_resume NULL
951#endif /* CONFIG_PM */
952
6c742509
SG
953#define ATMEL_SSC_FORMATS (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE |\
954 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
955
85e7652d 956static const struct snd_soc_dai_ops atmel_ssc_dai_ops = {
6335d055
EM
957 .startup = atmel_ssc_startup,
958 .shutdown = atmel_ssc_shutdown,
959 .prepare = atmel_ssc_prepare,
a8f1f100 960 .trigger = atmel_ssc_trigger,
6335d055
EM
961 .hw_params = atmel_ssc_hw_params,
962 .set_fmt = atmel_ssc_set_dai_fmt,
963 .set_clkdiv = atmel_ssc_set_dai_clkdiv,
964};
965
be681a82 966static struct snd_soc_dai_driver atmel_ssc_dai = {
6c742509
SG
967 .suspend = atmel_ssc_suspend,
968 .resume = atmel_ssc_resume,
969 .playback = {
970 .channels_min = 1,
971 .channels_max = 2,
b6d6c6e9
PR
972 .rates = SNDRV_PCM_RATE_CONTINUOUS,
973 .rate_min = 8000,
974 .rate_max = 384000,
6c742509
SG
975 .formats = ATMEL_SSC_FORMATS,},
976 .capture = {
977 .channels_min = 1,
978 .channels_max = 2,
b6d6c6e9
PR
979 .rates = SNDRV_PCM_RATE_CONTINUOUS,
980 .rate_min = 8000,
981 .rate_max = 384000,
6c742509 982 .formats = ATMEL_SSC_FORMATS,},
6335d055 983 .ops = &atmel_ssc_dai_ops,
6c742509 984};
6c742509 985
a2c662c0
KM
986static const struct snd_soc_component_driver atmel_ssc_component = {
987 .name = "atmel-ssc",
988};
989
be681a82 990static int asoc_ssc_init(struct device *dev)
f0fba2ad 991{
c0380478 992 struct ssc_device *ssc = dev_get_drvdata(dev);
be681a82
BS
993 int ret;
994
e14614dc 995 ret = devm_snd_soc_register_component(dev, &atmel_ssc_component,
a2c662c0 996 &atmel_ssc_dai, 1);
be681a82
BS
997 if (ret) {
998 dev_err(dev, "Could not register DAI: %d\n", ret);
e14614dc 999 return ret;
be681a82
BS
1000 }
1001
3951e4aa
BS
1002 if (ssc->pdata->use_dma)
1003 ret = atmel_pcm_dma_platform_register(dev);
1004 else
1005 ret = atmel_pcm_pdc_platform_register(dev);
1006
be681a82
BS
1007 if (ret) {
1008 dev_err(dev, "Could not register PCM: %d\n", ret);
e14614dc 1009 return ret;
1d198f26 1010 }
f0fba2ad 1011
f0fba2ad 1012 return 0;
be681a82 1013}
f0fba2ad 1014
be681a82
BS
1015static void asoc_ssc_exit(struct device *dev)
1016{
c0380478 1017 struct ssc_device *ssc = dev_get_drvdata(dev);
3951e4aa
BS
1018
1019 if (ssc->pdata->use_dma)
1020 atmel_pcm_dma_platform_unregister(dev);
1021 else
1022 atmel_pcm_pdc_platform_unregister(dev);
be681a82 1023}
f0fba2ad 1024
abfa4eae
MB
1025/**
1026 * atmel_ssc_set_audio - Allocate the specified SSC for audio use.
1027 */
1028int atmel_ssc_set_audio(int ssc_id)
1029{
1030 struct ssc_device *ssc;
abfa4eae
MB
1031 int ret;
1032
abfa4eae
MB
1033 /* If we can grab the SSC briefly to parent the DAI device off it */
1034 ssc = ssc_request(ssc_id);
be681a82
BS
1035 if (IS_ERR(ssc)) {
1036 pr_err("Unable to parent ASoC SSC DAI on SSC: %ld\n",
abfa4eae 1037 PTR_ERR(ssc));
be681a82
BS
1038 return PTR_ERR(ssc);
1039 } else {
1040 ssc_info[ssc_id].ssc = ssc;
840d8e5e 1041 }
abfa4eae 1042
be681a82 1043 ret = asoc_ssc_init(&ssc->pdev->dev);
abfa4eae
MB
1044
1045 return ret;
1046}
1047EXPORT_SYMBOL_GPL(atmel_ssc_set_audio);
1048
be681a82
BS
1049void atmel_ssc_put_audio(int ssc_id)
1050{
1051 struct ssc_device *ssc = ssc_info[ssc_id].ssc;
1052
be681a82 1053 asoc_ssc_exit(&ssc->pdev->dev);
69706028 1054 ssc_free(ssc);
be681a82
BS
1055}
1056EXPORT_SYMBOL_GPL(atmel_ssc_put_audio);
3f4b783c 1057
6c742509
SG
1058/* Module information */
1059MODULE_AUTHOR("Sedji Gaouaou, sedji.gaouaou@atmel.com, www.atmel.com");
1060MODULE_DESCRIPTION("ATMEL SSC ASoC Interface");
1061MODULE_LICENSE("GPL");