blob: 9fc0c0388881cdfca722e2504bfd9ae369716af2 [file] [log] [blame]
Frank Mandarino9f0ac6e2006-11-24 15:49:39 +01001/*
2 * at91-i2s.c -- ALSA SoC I2S Audio Layer Platform driver
3 *
4 * Author: Frank Mandarino <fmandarino@endrelia.com>
5 * Endrelia Technologies Inc.
6 *
7 * Based on pxa2xx Platform drivers by
8 * Liam Girdwood <liam.girdwood@wolfsonmicro.com>
9 *
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.
14 *
Frank Mandarino9f0ac6e2006-11-24 15:49:39 +010015 */
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>
Frank Mandarinofa8f8782007-02-12 14:06:22 +010023#include <linux/atmel_pdc.h>
24
Frank Mandarino9f0ac6e2006-11-24 15:49:39 +010025#include <sound/driver.h>
26#include <sound/core.h>
27#include <sound/pcm.h>
28#include <sound/initval.h>
29#include <sound/soc.h>
30
31#include <asm/arch/hardware.h>
32#include <asm/arch/at91_pmc.h>
33#include <asm/arch/at91_ssc.h>
Frank Mandarino9f0ac6e2006-11-24 15:49:39 +010034
35#include "at91-pcm.h"
Frank Mandarino171eb8f2007-02-02 17:18:38 +010036#include "at91-i2s.h"
Frank Mandarino9f0ac6e2006-11-24 15:49:39 +010037
38#if 0
39#define DBG(x...) printk(KERN_DEBUG "at91-i2s:" x)
40#else
41#define DBG(x...)
42#endif
43
44#if defined(CONFIG_ARCH_AT91SAM9260)
45#define NUM_SSC_DEVICES 1
46#else
47#define NUM_SSC_DEVICES 3
48#endif
49
50
Frank Mandarino9f0ac6e2006-11-24 15:49:39 +010051/*
52 * SSC PDC registers required by the PCM DMA engine.
53 */
54static struct at91_pdc_regs pdc_tx_reg = {
Frank Mandarinofa8f8782007-02-12 14:06:22 +010055 .xpr = ATMEL_PDC_TPR,
56 .xcr = ATMEL_PDC_TCR,
57 .xnpr = ATMEL_PDC_TNPR,
58 .xncr = ATMEL_PDC_TNCR,
Frank Mandarino9f0ac6e2006-11-24 15:49:39 +010059};
60
61static struct at91_pdc_regs pdc_rx_reg = {
Frank Mandarinofa8f8782007-02-12 14:06:22 +010062 .xpr = ATMEL_PDC_RPR,
63 .xcr = ATMEL_PDC_RCR,
64 .xnpr = ATMEL_PDC_RNPR,
65 .xncr = ATMEL_PDC_RNCR,
Frank Mandarino9f0ac6e2006-11-24 15:49:39 +010066};
67
68/*
69 * SSC & PDC status bits for transmit and receive.
70 */
71static 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,
Frank Mandarinofa8f8782007-02-12 14:06:22 +010076 .pdc_enable = ATMEL_PDC_TXTEN,
77 .pdc_disable = ATMEL_PDC_TXTDIS,
Frank Mandarino9f0ac6e2006-11-24 15:49:39 +010078};
79
80static 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,
Frank Mandarinofa8f8782007-02-12 14:06:22 +010085 .pdc_enable = ATMEL_PDC_RXTEN,
86 .pdc_disable = ATMEL_PDC_RXTDIS,
Frank Mandarino9f0ac6e2006-11-24 15:49:39 +010087};
88
89
90/*
91 * DMA parameters.
92 */
93static struct at91_pcm_dma_params ssc_dma_params[NUM_SSC_DEVICES][2] = {
94 {{
95 .name = "SSC0/I2S PCM Stereo out",
96 .pdc = &pdc_tx_reg,
97 .mask = &ssc_tx_mask,
98 },
99 {
100 .name = "SSC0/I2S PCM Stereo in",
101 .pdc = &pdc_rx_reg,
102 .mask = &ssc_rx_mask,
103 }},
104#if NUM_SSC_DEVICES == 3
105 {{
106 .name = "SSC1/I2S PCM Stereo out",
107 .pdc = &pdc_tx_reg,
108 .mask = &ssc_tx_mask,
109 },
110 {
111 .name = "SSC1/I2S PCM Stereo in",
112 .pdc = &pdc_rx_reg,
113 .mask = &ssc_rx_mask,
114 }},
115 {{
116 .name = "SSC2/I2S PCM Stereo out",
117 .pdc = &pdc_tx_reg,
118 .mask = &ssc_tx_mask,
119 },
120 {
121 .name = "SSC1/I2S PCM Stereo in",
122 .pdc = &pdc_rx_reg,
123 .mask = &ssc_rx_mask,
124 }},
125#endif
126};
127
Frank Mandarino9f0ac6e2006-11-24 15:49:39 +0100128struct at91_ssc_state {
129 u32 ssc_cmr;
130 u32 ssc_rcmr;
131 u32 ssc_rfmr;
132 u32 ssc_tcmr;
133 u32 ssc_tfmr;
134 u32 ssc_sr;
135 u32 ssc_imr;
136};
137
Frank Mandarino9f0ac6e2006-11-24 15:49:39 +0100138static struct at91_ssc_info {
139 char *name;
140 struct at91_ssc_periph ssc;
141 spinlock_t lock; /* lock for dir_mask */
Frank Mandarino171eb8f2007-02-02 17:18:38 +0100142 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;
Frank Mandarino9f0ac6e2006-11-24 15:49:39 +0100148 struct at91_pcm_dma_params *dma_params[2];
149 struct at91_ssc_state ssc_state;
150
151} ssc_info[NUM_SSC_DEVICES] = {
152 {
153 .name = "ssc0",
154 .lock = SPIN_LOCK_UNLOCKED,
155 .dir_mask = 0,
Frank Mandarino9f0ac6e2006-11-24 15:49:39 +0100156 .initialized = 0,
157 },
158#if NUM_SSC_DEVICES == 3
159 {
160 .name = "ssc1",
161 .lock = SPIN_LOCK_UNLOCKED,
162 .dir_mask = 0,
Frank Mandarino9f0ac6e2006-11-24 15:49:39 +0100163 .initialized = 0,
164 },
165 {
166 .name = "ssc2",
167 .lock = SPIN_LOCK_UNLOCKED,
168 .dir_mask = 0,
Frank Mandarino9f0ac6e2006-11-24 15:49:39 +0100169 .initialized = 0,
170 },
171#endif
172};
173
Frank Mandarino171eb8f2007-02-02 17:18:38 +0100174static unsigned int at91_i2s_sysclk;
Frank Mandarino9f0ac6e2006-11-24 15:49:39 +0100175
Frank Mandarino171eb8f2007-02-02 17:18:38 +0100176/*
177 * SSC interrupt handler. Passes PDC interrupts to the DMA
178 * interrupt handler in the PCM driver.
179 */
Frank Mandarino9f0ac6e2006-11-24 15:49:39 +0100180static irqreturn_t at91_i2s_interrupt(int irq, void *dev_id)
181{
182 struct at91_ssc_info *ssc_p = dev_id;
183 struct at91_pcm_dma_params *dma_params;
184 u32 ssc_sr;
185 int i;
186
187 ssc_sr = at91_ssc_read(ssc_p->ssc.base + AT91_SSC_SR)
188 & at91_ssc_read(ssc_p->ssc.base + AT91_SSC_IMR);
189
190 /*
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.
195 */
196 for (i = 0; i < ARRAY_SIZE(ssc_p->dma_params); i++) {
197 dma_params = ssc_p->dma_params[i];
198
199 if (dma_params != NULL && dma_params->dma_intr_handler != NULL &&
200 (ssc_sr &
201 (dma_params->mask->ssc_endx | dma_params->mask->ssc_endbuf)))
202
203 dma_params->dma_intr_handler(ssc_sr, dma_params->substream);
204 }
205
206 return IRQ_HANDLED;
207}
208
Frank Mandarino171eb8f2007-02-02 17:18:38 +0100209/*
210 * Startup. Only that one substream allowed in each direction.
211 */
Frank Mandarino9f0ac6e2006-11-24 15:49:39 +0100212static int at91_i2s_startup(struct snd_pcm_substream *substream)
213{
214 struct snd_soc_pcm_runtime *rtd = substream->private_data;
Frank Mandarino171eb8f2007-02-02 17:18:38 +0100215 struct at91_ssc_info *ssc_p = &ssc_info[rtd->dai->cpu_dai->id];
Frank Mandarino9f0ac6e2006-11-24 15:49:39 +0100216 int dir_mask;
217
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;
221
222 spin_lock_irq(&ssc_p->lock);
223 if (ssc_p->dir_mask & dir_mask) {
224 spin_unlock_irq(&ssc_p->lock);
225 return -EBUSY;
226 }
227 ssc_p->dir_mask |= dir_mask;
228 spin_unlock_irq(&ssc_p->lock);
229
230 return 0;
231}
232
Frank Mandarino171eb8f2007-02-02 17:18:38 +0100233/*
234 * Shutdown. Clear DMA parameters and shutdown the SSC if there
235 * are no other substreams open.
236 */
Frank Mandarino9f0ac6e2006-11-24 15:49:39 +0100237static void at91_i2s_shutdown(struct snd_pcm_substream *substream)
238{
239 struct snd_soc_pcm_runtime *rtd = substream->private_data;
Frank Mandarino171eb8f2007-02-02 17:18:38 +0100240 struct at91_ssc_info *ssc_p = &ssc_info[rtd->dai->cpu_dai->id];
241 struct at91_pcm_dma_params *dma_params;
Frank Mandarino9f0ac6e2006-11-24 15:49:39 +0100242 int dir, dir_mask;
243
244 dir = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 0 : 1;
Frank Mandarino171eb8f2007-02-02 17:18:38 +0100245 dma_params = ssc_p->dma_params[dir];
Frank Mandarino9f0ac6e2006-11-24 15:49:39 +0100246
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));
252
253 dma_params->ssc_base = NULL;
254 dma_params->substream = NULL;
255 ssc_p->dma_params[dir] = NULL;
256 }
257
258 dir_mask = 1 << dir;
259
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);
266
Frank Mandarino171eb8f2007-02-02 17:18:38 +0100267 if (ssc_p->initialized) {
Frank Mandarino9f0ac6e2006-11-24 15:49:39 +0100268 free_irq(ssc_p->ssc.pid, ssc_p);
Frank Mandarino171eb8f2007-02-02 17:18:38 +0100269 ssc_p->initialized = 0;
270 }
Frank Mandarino9f0ac6e2006-11-24 15:49:39 +0100271
272 /* Reset the SSC */
273 at91_ssc_write(ssc_p->ssc.base + AT91_SSC_CR, AT91_SSC_SWRST);
274
Frank Mandarino171eb8f2007-02-02 17:18:38 +0100275 /* Clear the SSC dividers */
276 ssc_p->cmr_div = ssc_p->tcmr_period = ssc_p->rcmr_period = 0;
Frank Mandarino9f0ac6e2006-11-24 15:49:39 +0100277 }
278 spin_unlock_irq(&ssc_p->lock);
279}
280
Frank Mandarino171eb8f2007-02-02 17:18:38 +0100281/*
282 * Record the SSC system clock rate.
283 */
284static int at91_i2s_set_dai_sysclk(struct snd_soc_cpu_dai *cpu_dai,
285 int clk_id, unsigned int freq, int dir)
Frank Mandarino9f0ac6e2006-11-24 15:49:39 +0100286{
Frank Mandarino171eb8f2007-02-02 17:18:38 +0100287 /*
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
290 * LRC clocks.
291 */
292 switch (clk_id) {
293 case AT91_SYSCLK_MCK:
294 at91_i2s_sysclk = freq;
295 break;
296 default:
297 return -EINVAL;
298 }
Frank Mandarino9f0ac6e2006-11-24 15:49:39 +0100299
300 return 0;
301}
302
Frank Mandarino171eb8f2007-02-02 17:18:38 +0100303/*
304 * Record the DAI format for use in hw_params().
305 */
306static int at91_i2s_set_dai_fmt(struct snd_soc_cpu_dai *cpu_dai,
307 unsigned int fmt)
Frank Mandarino9f0ac6e2006-11-24 15:49:39 +0100308{
Frank Mandarino171eb8f2007-02-02 17:18:38 +0100309 struct at91_ssc_info *ssc_p = &ssc_info[cpu_dai->id];
Frank Mandarino9f0ac6e2006-11-24 15:49:39 +0100310
Frank Mandarino171eb8f2007-02-02 17:18:38 +0100311 if ((fmt & SND_SOC_DAIFMT_FORMAT_MASK) != SND_SOC_DAIFMT_I2S)
312 return -EINVAL;
Frank Mandarino9f0ac6e2006-11-24 15:49:39 +0100313
Frank Mandarino171eb8f2007-02-02 17:18:38 +0100314 ssc_p->daifmt = fmt;
315 return 0;
316}
Frank Mandarino9f0ac6e2006-11-24 15:49:39 +0100317
Frank Mandarino171eb8f2007-02-02 17:18:38 +0100318/*
319 * Record SSC clock dividers for use in hw_params().
320 */
321static int at91_i2s_set_dai_clkdiv(struct snd_soc_cpu_dai *cpu_dai,
322 int div_id, int div)
323{
324 struct at91_ssc_info *ssc_p = &ssc_info[cpu_dai->id];
Frank Mandarino9f0ac6e2006-11-24 15:49:39 +0100325
Frank Mandarino171eb8f2007-02-02 17:18:38 +0100326 switch (div_id) {
327 case AT91SSC_CMR_DIV:
328 /*
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.
332 */
333 if (ssc_p->cmr_div == 0)
334 ssc_p->cmr_div = div;
335 else
336 if (div != ssc_p->cmr_div)
337 return -EBUSY;
338 break;
Frank Mandarino9f0ac6e2006-11-24 15:49:39 +0100339
Frank Mandarino171eb8f2007-02-02 17:18:38 +0100340 case AT91SSC_TCMR_PERIOD:
341 ssc_p->tcmr_period = div;
342 break;
343
344 case AT91SSC_RCMR_PERIOD:
345 ssc_p->rcmr_period = div;
346 break;
347
348 default:
349 return -EINVAL;
350 }
Frank Mandarino9f0ac6e2006-11-24 15:49:39 +0100351
352 return 0;
353}
354
Frank Mandarino171eb8f2007-02-02 17:18:38 +0100355/*
356 * Configure the SSC.
357 */
Frank Mandarino9f0ac6e2006-11-24 15:49:39 +0100358static int at91_i2s_hw_params(struct snd_pcm_substream *substream,
359 struct snd_pcm_hw_params *params)
360{
361 struct snd_soc_pcm_runtime *rtd = substream->private_data;
Frank Mandarino171eb8f2007-02-02 17:18:38 +0100362 int id = rtd->dai->cpu_dai->id;
Frank Mandarino9f0ac6e2006-11-24 15:49:39 +0100363 struct at91_ssc_info *ssc_p = &ssc_info[id];
364 struct at91_pcm_dma_params *dma_params;
Frank Mandarino9f0ac6e2006-11-24 15:49:39 +0100365 int dir, channels, bits;
Frank Mandarino171eb8f2007-02-02 17:18:38 +0100366 u32 tfmr, rfmr, tcmr, rcmr;
367 int start_event;
Frank Mandarino9f0ac6e2006-11-24 15:49:39 +0100368 int ret;
369
370 /*
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.
374 */
375 dir = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 0 : 1;
376
377 dma_params = &ssc_dma_params[id][dir];
378 dma_params->ssc_base = ssc_p->ssc.base;
379 dma_params->substream = substream;
380
381 ssc_p->dma_params[dir] = dma_params;
Frank Mandarino9f0ac6e2006-11-24 15:49:39 +0100382
383 /*
Frank Mandarino171eb8f2007-02-02 17:18:38 +0100384 * 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.
Frank Mandarino9f0ac6e2006-11-24 15:49:39 +0100388 */
Frank Mandarino171eb8f2007-02-02 17:18:38 +0100389 rtd->dai->cpu_dai->dma_data = dma_params;
390
391 channels = params_channels(params);
392
393 /*
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.
397 */
398 bits = 16;
399 dma_params->pdc_xfer_size = 2;
400
401 /*
402 * Compute SSC register settings.
403 */
404 switch (ssc_p->daifmt) {
405 case SND_SOC_DAIFMT_CBS_CFS:
406 /*
407 * SSC provides BCLK and LRC clocks.
408 *
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.
411 */
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);
418
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);
426
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);
433
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);
442 break;
443
444 case SND_SOC_DAIFMT_CBM_CFM:
445
446 /*
447 * CODEC supplies BCLK and LRC clocks.
448 *
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
451 * transmit clock.
452 *
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.
456 */
457 start_event = channels == 1
458 ? AT91_SSC_START_FALLING_RF
459 : AT91_SSC_START_EDGE_RF;
460
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);
467
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);
475
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);
482
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);
491 break;
492
493 case SND_SOC_DAIFMT_CBS_CFM:
494 case SND_SOC_DAIFMT_CBM_CFS:
495 default:
496 printk(KERN_WARNING "at91-i2s: unsupported DAI format 0x%x.\n",
497 ssc_p->daifmt);
498 return -EINVAL;
499 break;
500 }
501 DBG("RCMR=%08x RFMR=%08x TCMR=%08x TFMR=%08x\n", rcmr, rfmr, tcmr, tfmr);
502
503 if (!ssc_p->initialized) {
504
Frank Mandarino9f0ac6e2006-11-24 15:49:39 +0100505 /* 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);
508
Frank Mandarino171eb8f2007-02-02 17:18:38 +0100509 /* Reset the SSC and its PDC registers */
Frank Mandarino9f0ac6e2006-11-24 15:49:39 +0100510 at91_ssc_write(ssc_p->ssc.base + AT91_SSC_CR, AT91_SSC_SWRST);
511
Frank Mandarinofa8f8782007-02-12 14:06:22 +0100512 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);
Frank Mandarino9f0ac6e2006-11-24 15:49:39 +0100520
Frank Mandarino9f0ac6e2006-11-24 15:49:39 +0100521 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");
Frank Mandarino171eb8f2007-02-02 17:18:38 +0100524
525 DBG("Stopping pid %d clock\n", ssc_p->ssc.pid);
526 at91_sys_write(AT91_PMC_PCER, 1<<ssc_p->ssc.pid);
Frank Mandarino9f0ac6e2006-11-24 15:49:39 +0100527 return ret;
528 }
529
Frank Mandarino9f0ac6e2006-11-24 15:49:39 +0100530 ssc_p->initialized = 1;
Frank Mandarino9f0ac6e2006-11-24 15:49:39 +0100531 }
532
Frank Mandarino171eb8f2007-02-02 17:18:38 +0100533 /* set SSC clock mode register */
534 at91_ssc_write(ssc_p->ssc.base + AT91_SSC_CMR, ssc_p->cmr_div);
Frank Mandarino9f0ac6e2006-11-24 15:49:39 +0100535
Frank Mandarino171eb8f2007-02-02 17:18:38 +0100536 /* 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);
539
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);
543
544 DBG("hw_params: SSC initialized\n");
Frank Mandarino9f0ac6e2006-11-24 15:49:39 +0100545 return 0;
546}
547
548
549static int at91_i2s_prepare(struct snd_pcm_substream *substream)
550{
551 struct snd_soc_pcm_runtime *rtd = substream->private_data;
Frank Mandarino171eb8f2007-02-02 17:18:38 +0100552 struct at91_ssc_info *ssc_p = &ssc_info[rtd->dai->cpu_dai->id];
553 struct at91_pcm_dma_params *dma_params;
554 int dir;
555
556 dir = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 0 : 1;
557 dma_params = ssc_p->dma_params[dir];
Frank Mandarino9f0ac6e2006-11-24 15:49:39 +0100558
559 at91_ssc_write(dma_params->ssc_base + AT91_SSC_CR,
560 dma_params->mask->ssc_enable);
561
Frank Mandarino171eb8f2007-02-02 17:18:38 +0100562 DBG("%s enabled SSC_SR=0x%08lx\n", dir ? "receive" : "transmit",
563 at91_ssc_read(dma_params->ssc_base + AT91_SSC_SR));
Frank Mandarino9f0ac6e2006-11-24 15:49:39 +0100564 return 0;
565}
566
567
Frank Mandarino171eb8f2007-02-02 17:18:38 +0100568#ifdef CONFIG_PM
569static int at91_i2s_suspend(struct platform_device *pdev,
570 struct snd_soc_cpu_dai *cpu_dai)
571{
572 struct at91_ssc_info *ssc_p;
573
574 if(!cpu_dai->active)
575 return 0;
576
577 ssc_p = &ssc_info[cpu_dai->id];
578
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);
583
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);
587
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);
593
594 return 0;
595}
596
597static int at91_i2s_resume(struct platform_device *pdev,
598 struct snd_soc_cpu_dai *cpu_dai)
599{
600 struct at91_ssc_info *ssc_p;
601
602 if(!cpu_dai->active)
603 return 0;
604
605 ssc_p = &ssc_info[cpu_dai->id];
606
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);
612
613 at91_ssc_write(ssc_p->ssc.base + AT91_SSC_IER, ssc_p->ssc_state.ssc_imr);
614
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));
618
619 return 0;
620}
621
622#else
623#define at91_i2s_suspend NULL
624#define at91_i2s_resume NULL
625#endif
626
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)
632
Frank Mandarino9f0ac6e2006-11-24 15:49:39 +0100633struct snd_soc_cpu_dai at91_i2s_dai[NUM_SSC_DEVICES] = {
634 { .name = "at91_ssc0/i2s",
635 .id = 0,
636 .type = SND_SOC_DAI_I2S,
637 .suspend = at91_i2s_suspend,
638 .resume = at91_i2s_resume,
Frank Mandarino9f0ac6e2006-11-24 15:49:39 +0100639 .playback = {
640 .channels_min = 1,
Frank Mandarino171eb8f2007-02-02 17:18:38 +0100641 .channels_max = 2,
642 .rates = AT91_I2S_RATES,
643 .formats = SNDRV_PCM_FMTBIT_S16_LE,},
Frank Mandarino9f0ac6e2006-11-24 15:49:39 +0100644 .capture = {
645 .channels_min = 1,
Frank Mandarino171eb8f2007-02-02 17:18:38 +0100646 .channels_max = 2,
647 .rates = AT91_I2S_RATES,
648 .formats = SNDRV_PCM_FMTBIT_S16_LE,},
Frank Mandarino9f0ac6e2006-11-24 15:49:39 +0100649 .ops = {
650 .startup = at91_i2s_startup,
651 .shutdown = at91_i2s_shutdown,
652 .prepare = at91_i2s_prepare,
653 .hw_params = at91_i2s_hw_params,},
Frank Mandarino171eb8f2007-02-02 17:18:38 +0100654 .dai_ops = {
655 .set_sysclk = at91_i2s_set_dai_sysclk,
656 .set_fmt = at91_i2s_set_dai_fmt,
657 .set_clkdiv = at91_i2s_set_dai_clkdiv,},
Frank Mandarino9f0ac6e2006-11-24 15:49:39 +0100658 .private_data = &ssc_info[0].ssc,
659 },
660#if NUM_SSC_DEVICES == 3
661 { .name = "at91_ssc1/i2s",
662 .id = 1,
663 .type = SND_SOC_DAI_I2S,
664 .suspend = at91_i2s_suspend,
665 .resume = at91_i2s_resume,
Frank Mandarino9f0ac6e2006-11-24 15:49:39 +0100666 .playback = {
667 .channels_min = 1,
Frank Mandarino171eb8f2007-02-02 17:18:38 +0100668 .channels_max = 2,
669 .rates = AT91_I2S_RATES,
670 .formats = SNDRV_PCM_FMTBIT_S16_LE,},
Frank Mandarino9f0ac6e2006-11-24 15:49:39 +0100671 .capture = {
672 .channels_min = 1,
Frank Mandarino171eb8f2007-02-02 17:18:38 +0100673 .channels_max = 2,
674 .rates = AT91_I2S_RATES,
675 .formats = SNDRV_PCM_FMTBIT_S16_LE,},
Frank Mandarino9f0ac6e2006-11-24 15:49:39 +0100676 .ops = {
677 .startup = at91_i2s_startup,
678 .shutdown = at91_i2s_shutdown,
679 .prepare = at91_i2s_prepare,
680 .hw_params = at91_i2s_hw_params,},
Frank Mandarino171eb8f2007-02-02 17:18:38 +0100681 .dai_ops = {
682 .set_sysclk = at91_i2s_set_dai_sysclk,
683 .set_fmt = at91_i2s_set_dai_fmt,
684 .set_clkdiv = at91_i2s_set_dai_clkdiv,},
Frank Mandarino9f0ac6e2006-11-24 15:49:39 +0100685 .private_data = &ssc_info[1].ssc,
686 },
687 { .name = "at91_ssc2/i2s",
688 .id = 2,
689 .type = SND_SOC_DAI_I2S,
690 .suspend = at91_i2s_suspend,
691 .resume = at91_i2s_resume,
Frank Mandarino9f0ac6e2006-11-24 15:49:39 +0100692 .playback = {
693 .channels_min = 1,
Frank Mandarino171eb8f2007-02-02 17:18:38 +0100694 .channels_max = 2,
695 .rates = AT91_I2S_RATES,
696 .formats = SNDRV_PCM_FMTBIT_S16_LE,},
Frank Mandarino9f0ac6e2006-11-24 15:49:39 +0100697 .capture = {
698 .channels_min = 1,
Frank Mandarino171eb8f2007-02-02 17:18:38 +0100699 .channels_max = 2,
700 .rates = AT91_I2S_RATES,
701 .formats = SNDRV_PCM_FMTBIT_S16_LE,},
Frank Mandarino9f0ac6e2006-11-24 15:49:39 +0100702 .ops = {
703 .startup = at91_i2s_startup,
704 .shutdown = at91_i2s_shutdown,
705 .prepare = at91_i2s_prepare,
706 .hw_params = at91_i2s_hw_params,},
Frank Mandarino171eb8f2007-02-02 17:18:38 +0100707 .dai_ops = {
708 .set_sysclk = at91_i2s_set_dai_sysclk,
709 .set_fmt = at91_i2s_set_dai_fmt,
710 .set_clkdiv = at91_i2s_set_dai_clkdiv,},
Frank Mandarino9f0ac6e2006-11-24 15:49:39 +0100711 .private_data = &ssc_info[2].ssc,
712 },
713#endif
714};
715
716EXPORT_SYMBOL_GPL(at91_i2s_dai);
717
718/* Module information */
719MODULE_AUTHOR("Frank Mandarino, fmandarino@endrelia.com, www.endrelia.com");
720MODULE_DESCRIPTION("AT91 I2S ASoC Interface");
721MODULE_LICENSE("GPL");