2 * Freescale MPC5200 PSC DMA
3 * ALSA SoC Platform driver
5 * Copyright (C) 2008 Secret Lab Technologies Ltd.
6 * Copyright (C) 2009 Jon Smirl, Digispeaker
9 #include <linux/module.h>
10 #include <linux/of_device.h>
12 #include <sound/soc.h>
14 #include <sysdev/bestcomm/bestcomm.h>
15 #include <sysdev/bestcomm/gen_bd.h>
16 #include <asm/mpc52xx_psc.h>
18 #include "mpc5200_dma.h"
23 static irqreturn_t
psc_dma_status_irq(int irq
, void *_psc_dma
)
25 struct psc_dma
*psc_dma
= _psc_dma
;
26 struct mpc52xx_psc __iomem
*regs
= psc_dma
->psc_regs
;
29 isr
= in_be16(®s
->mpc52xx_psc_isr
);
31 /* Playback underrun error */
32 if (psc_dma
->playback
.active
&& (isr
& MPC52xx_PSC_IMR_TXEMP
))
33 psc_dma
->stats
.underrun_count
++;
35 /* Capture overrun error */
36 if (psc_dma
->capture
.active
&& (isr
& MPC52xx_PSC_IMR_ORERR
))
37 psc_dma
->stats
.overrun_count
++;
39 out_8(®s
->command
, MPC52xx_PSC_RST_ERR_STAT
);
45 * psc_dma_bcom_enqueue_next_buffer - Enqueue another audio buffer
46 * @s: pointer to stream private data structure
48 * Enqueues another audio period buffer into the bestcomm queue.
50 * Note: The routine must only be called when there is space available in
51 * the queue. Otherwise the enqueue will fail and the audio ring buffer
52 * will get out of sync
54 static void psc_dma_bcom_enqueue_next_buffer(struct psc_dma_stream
*s
)
58 /* Prepare and enqueue the next buffer descriptor */
59 bd
= bcom_prepare_next_buffer(s
->bcom_task
);
60 bd
->status
= s
->period_bytes
;
61 bd
->data
[0] = s
->period_next_pt
;
62 bcom_submit_next_buffer(s
->bcom_task
, NULL
);
64 /* Update for next period */
65 s
->period_next_pt
+= s
->period_bytes
;
66 if (s
->period_next_pt
>= s
->period_end
)
67 s
->period_next_pt
= s
->period_start
;
70 static void psc_dma_bcom_enqueue_tx(struct psc_dma_stream
*s
)
72 while (s
->appl_ptr
< s
->runtime
->control
->appl_ptr
) {
74 if (bcom_queue_full(s
->bcom_task
))
77 s
->appl_ptr
+= s
->period_size
;
79 psc_dma_bcom_enqueue_next_buffer(s
);
83 /* Bestcomm DMA irq handler */
84 static irqreturn_t
psc_dma_bcom_irq_tx(int irq
, void *_psc_dma_stream
)
86 struct psc_dma_stream
*s
= _psc_dma_stream
;
88 spin_lock(&s
->psc_dma
->lock
);
89 /* For each finished period, dequeue the completed period buffer
90 * and enqueue a new one in it's place. */
91 while (bcom_buffer_done(s
->bcom_task
)) {
92 bcom_retrieve_buffer(s
->bcom_task
, NULL
, NULL
);
94 s
->period_current_pt
+= s
->period_bytes
;
95 if (s
->period_current_pt
>= s
->period_end
)
96 s
->period_current_pt
= s
->period_start
;
98 psc_dma_bcom_enqueue_tx(s
);
99 spin_unlock(&s
->psc_dma
->lock
);
101 /* If the stream is active, then also inform the PCM middle layer
102 * of the period finished event. */
104 snd_pcm_period_elapsed(s
->stream
);
109 static irqreturn_t
psc_dma_bcom_irq_rx(int irq
, void *_psc_dma_stream
)
111 struct psc_dma_stream
*s
= _psc_dma_stream
;
113 spin_lock(&s
->psc_dma
->lock
);
114 /* For each finished period, dequeue the completed period buffer
115 * and enqueue a new one in it's place. */
116 while (bcom_buffer_done(s
->bcom_task
)) {
117 bcom_retrieve_buffer(s
->bcom_task
, NULL
, NULL
);
119 s
->period_current_pt
+= s
->period_bytes
;
120 if (s
->period_current_pt
>= s
->period_end
)
121 s
->period_current_pt
= s
->period_start
;
123 psc_dma_bcom_enqueue_next_buffer(s
);
125 spin_unlock(&s
->psc_dma
->lock
);
127 /* If the stream is active, then also inform the PCM middle layer
128 * of the period finished event. */
130 snd_pcm_period_elapsed(s
->stream
);
135 static int psc_dma_hw_free(struct snd_pcm_substream
*substream
)
137 snd_pcm_set_runtime_buffer(substream
, NULL
);
142 * psc_dma_trigger: start and stop the DMA transfer.
144 * This function is called by ALSA to start, stop, pause, and resume the DMA
147 static int psc_dma_trigger(struct snd_pcm_substream
*substream
, int cmd
)
149 struct snd_soc_pcm_runtime
*rtd
= substream
->private_data
;
150 struct psc_dma
*psc_dma
= rtd
->dai
->cpu_dai
->private_data
;
151 struct snd_pcm_runtime
*runtime
= substream
->runtime
;
152 struct psc_dma_stream
*s
;
153 struct mpc52xx_psc __iomem
*regs
= psc_dma
->psc_regs
;
158 if (substream
->pstr
->stream
== SNDRV_PCM_STREAM_CAPTURE
)
159 s
= &psc_dma
->capture
;
161 s
= &psc_dma
->playback
;
163 dev_dbg(psc_dma
->dev
, "psc_dma_trigger(substream=%p, cmd=%i)"
165 substream
, cmd
, substream
->pstr
->stream
);
168 case SNDRV_PCM_TRIGGER_START
:
169 s
->period_bytes
= frames_to_bytes(runtime
,
170 runtime
->period_size
);
171 s
->period_start
= virt_to_phys(runtime
->dma_area
);
172 s
->period_end
= s
->period_start
+
173 (s
->period_bytes
* runtime
->periods
);
174 s
->period_next_pt
= s
->period_start
;
175 s
->period_current_pt
= s
->period_start
;
176 s
->period_size
= runtime
->period_size
;
179 /* track appl_ptr so that we have a better chance of detecting
180 * end of stream and not over running it.
182 s
->runtime
= runtime
;
183 s
->appl_ptr
= s
->runtime
->control
->appl_ptr
-
184 (runtime
->period_size
* runtime
->periods
);
186 /* Fill up the bestcomm bd queue and enable DMA.
187 * This will begin filling the PSC's fifo.
189 spin_lock_irqsave(&psc_dma
->lock
, flags
);
191 if (substream
->pstr
->stream
== SNDRV_PCM_STREAM_CAPTURE
) {
192 bcom_gen_bd_rx_reset(s
->bcom_task
);
193 for (i
= 0; i
< runtime
->periods
; i
++)
194 if (!bcom_queue_full(s
->bcom_task
))
195 psc_dma_bcom_enqueue_next_buffer(s
);
197 bcom_gen_bd_tx_reset(s
->bcom_task
);
198 psc_dma_bcom_enqueue_tx(s
);
201 bcom_enable(s
->bcom_task
);
202 spin_unlock_irqrestore(&psc_dma
->lock
, flags
);
204 out_8(®s
->command
, MPC52xx_PSC_RST_ERR_STAT
);
208 case SNDRV_PCM_TRIGGER_STOP
:
211 spin_lock_irqsave(&psc_dma
->lock
, flags
);
212 bcom_disable(s
->bcom_task
);
213 if (substream
->pstr
->stream
== SNDRV_PCM_STREAM_CAPTURE
)
214 bcom_gen_bd_rx_reset(s
->bcom_task
);
216 bcom_gen_bd_tx_reset(s
->bcom_task
);
217 spin_unlock_irqrestore(&psc_dma
->lock
, flags
);
222 dev_dbg(psc_dma
->dev
, "invalid command\n");
226 /* Update interrupt enable settings */
228 if (psc_dma
->playback
.active
)
229 imr
|= MPC52xx_PSC_IMR_TXEMP
;
230 if (psc_dma
->capture
.active
)
231 imr
|= MPC52xx_PSC_IMR_ORERR
;
232 out_be16(®s
->isr_imr
.imr
, psc_dma
->imr
| imr
);
238 /* ---------------------------------------------------------------------
239 * The PSC DMA 'ASoC platform' driver
241 * Can be referenced by an 'ASoC machine' driver
242 * This driver only deals with the audio bus; it doesn't have any
243 * interaction with the attached codec
246 static const struct snd_pcm_hardware psc_dma_hardware
= {
247 .info
= SNDRV_PCM_INFO_MMAP
| SNDRV_PCM_INFO_MMAP_VALID
|
248 SNDRV_PCM_INFO_INTERLEAVED
| SNDRV_PCM_INFO_BLOCK_TRANSFER
|
249 SNDRV_PCM_INFO_BATCH
,
250 .formats
= SNDRV_PCM_FMTBIT_S8
| SNDRV_PCM_FMTBIT_S16_BE
|
251 SNDRV_PCM_FMTBIT_S24_BE
| SNDRV_PCM_FMTBIT_S32_BE
,
256 .period_bytes_max
= 1024 * 1024,
257 .period_bytes_min
= 32,
260 .buffer_bytes_max
= 2 * 1024 * 1024,
264 static int psc_dma_open(struct snd_pcm_substream
*substream
)
266 struct snd_pcm_runtime
*runtime
= substream
->runtime
;
267 struct snd_soc_pcm_runtime
*rtd
= substream
->private_data
;
268 struct psc_dma
*psc_dma
= rtd
->dai
->cpu_dai
->private_data
;
269 struct psc_dma_stream
*s
;
272 dev_dbg(psc_dma
->dev
, "psc_dma_open(substream=%p)\n", substream
);
274 if (substream
->pstr
->stream
== SNDRV_PCM_STREAM_CAPTURE
)
275 s
= &psc_dma
->capture
;
277 s
= &psc_dma
->playback
;
279 snd_soc_set_runtime_hwparams(substream
, &psc_dma_hardware
);
281 rc
= snd_pcm_hw_constraint_integer(runtime
,
282 SNDRV_PCM_HW_PARAM_PERIODS
);
284 dev_err(substream
->pcm
->card
->dev
, "invalid buffer size\n");
288 s
->stream
= substream
;
292 static int psc_dma_close(struct snd_pcm_substream
*substream
)
294 struct snd_soc_pcm_runtime
*rtd
= substream
->private_data
;
295 struct psc_dma
*psc_dma
= rtd
->dai
->cpu_dai
->private_data
;
296 struct psc_dma_stream
*s
;
298 dev_dbg(psc_dma
->dev
, "psc_dma_close(substream=%p)\n", substream
);
300 if (substream
->pstr
->stream
== SNDRV_PCM_STREAM_CAPTURE
)
301 s
= &psc_dma
->capture
;
303 s
= &psc_dma
->playback
;
305 if (!psc_dma
->playback
.active
&&
306 !psc_dma
->capture
.active
) {
308 /* Disable all interrupts and reset the PSC */
309 out_be16(&psc_dma
->psc_regs
->isr_imr
.imr
, psc_dma
->imr
);
310 out_8(&psc_dma
->psc_regs
->command
, 4 << 4); /* reset error */
316 static snd_pcm_uframes_t
317 psc_dma_pointer(struct snd_pcm_substream
*substream
)
319 struct snd_soc_pcm_runtime
*rtd
= substream
->private_data
;
320 struct psc_dma
*psc_dma
= rtd
->dai
->cpu_dai
->private_data
;
321 struct psc_dma_stream
*s
;
324 if (substream
->pstr
->stream
== SNDRV_PCM_STREAM_CAPTURE
)
325 s
= &psc_dma
->capture
;
327 s
= &psc_dma
->playback
;
329 count
= s
->period_current_pt
- s
->period_start
;
331 return bytes_to_frames(substream
->runtime
, count
);
335 psc_dma_hw_params(struct snd_pcm_substream
*substream
,
336 struct snd_pcm_hw_params
*params
)
338 snd_pcm_set_runtime_buffer(substream
, &substream
->dma_buffer
);
343 static struct snd_pcm_ops psc_dma_ops
= {
344 .open
= psc_dma_open
,
345 .close
= psc_dma_close
,
346 .hw_free
= psc_dma_hw_free
,
347 .ioctl
= snd_pcm_lib_ioctl
,
348 .pointer
= psc_dma_pointer
,
349 .trigger
= psc_dma_trigger
,
350 .hw_params
= psc_dma_hw_params
,
353 static u64 psc_dma_dmamask
= 0xffffffff;
354 static int psc_dma_new(struct snd_card
*card
, struct snd_soc_dai
*dai
,
357 struct snd_soc_pcm_runtime
*rtd
= pcm
->private_data
;
358 struct psc_dma
*psc_dma
= rtd
->dai
->cpu_dai
->private_data
;
359 size_t size
= psc_dma_hardware
.buffer_bytes_max
;
362 dev_dbg(rtd
->socdev
->dev
, "psc_dma_new(card=%p, dai=%p, pcm=%p)\n",
365 if (!card
->dev
->dma_mask
)
366 card
->dev
->dma_mask
= &psc_dma_dmamask
;
367 if (!card
->dev
->coherent_dma_mask
)
368 card
->dev
->coherent_dma_mask
= 0xffffffff;
370 if (pcm
->streams
[0].substream
) {
371 rc
= snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV
, pcm
->card
->dev
,
372 size
, &pcm
->streams
[0].substream
->dma_buffer
);
374 goto playback_alloc_err
;
377 if (pcm
->streams
[1].substream
) {
378 rc
= snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV
, pcm
->card
->dev
,
379 size
, &pcm
->streams
[1].substream
->dma_buffer
);
381 goto capture_alloc_err
;
384 if (rtd
->socdev
->card
->codec
->ac97
)
385 rtd
->socdev
->card
->codec
->ac97
->private_data
= psc_dma
;
390 if (pcm
->streams
[0].substream
)
391 snd_dma_free_pages(&pcm
->streams
[0].substream
->dma_buffer
);
394 dev_err(card
->dev
, "Cannot allocate buffer(s)\n");
399 static void psc_dma_free(struct snd_pcm
*pcm
)
401 struct snd_soc_pcm_runtime
*rtd
= pcm
->private_data
;
402 struct snd_pcm_substream
*substream
;
405 dev_dbg(rtd
->socdev
->dev
, "psc_dma_free(pcm=%p)\n", pcm
);
407 for (stream
= 0; stream
< 2; stream
++) {
408 substream
= pcm
->streams
[stream
].substream
;
410 snd_dma_free_pages(&substream
->dma_buffer
);
411 substream
->dma_buffer
.area
= NULL
;
412 substream
->dma_buffer
.addr
= 0;
417 struct snd_soc_platform mpc5200_audio_dma_platform
= {
418 .name
= "mpc5200-psc-audio",
419 .pcm_ops
= &psc_dma_ops
,
420 .pcm_new
= &psc_dma_new
,
421 .pcm_free
= &psc_dma_free
,
423 EXPORT_SYMBOL_GPL(mpc5200_audio_dma_platform
);
425 int mpc5200_audio_dma_create(struct of_device
*op
)
428 struct psc_dma
*psc_dma
;
434 /* Fetch the registers and IRQ of the PSC */
435 irq
= irq_of_parse_and_map(op
->node
, 0);
436 if (of_address_to_resource(op
->node
, 0, &res
)) {
437 dev_err(&op
->dev
, "Missing reg property\n");
440 regs
= ioremap(res
.start
, 1 + res
.end
- res
.start
);
442 dev_err(&op
->dev
, "Could not map registers\n");
446 /* Allocate and initialize the driver private data */
447 psc_dma
= kzalloc(sizeof *psc_dma
, GFP_KERNEL
);
454 prop
= of_get_property(op
->node
, "cell-index", &size
);
455 if (!prop
|| size
< sizeof *prop
)
458 spin_lock_init(&psc_dma
->lock
);
459 mutex_init(&psc_dma
->mutex
);
460 psc_dma
->id
= be32_to_cpu(*prop
);
462 psc_dma
->psc_regs
= regs
;
463 psc_dma
->fifo_regs
= regs
+ sizeof *psc_dma
->psc_regs
;
464 psc_dma
->dev
= &op
->dev
;
465 psc_dma
->playback
.psc_dma
= psc_dma
;
466 psc_dma
->capture
.psc_dma
= psc_dma
;
467 snprintf(psc_dma
->name
, sizeof psc_dma
->name
, "PSC%u", psc_dma
->id
);
469 /* Find the address of the fifo data registers and setup the
471 fifo
= res
.start
+ offsetof(struct mpc52xx_psc
, buffer
.buffer_32
);
472 psc_dma
->capture
.bcom_task
=
473 bcom_psc_gen_bd_rx_init(psc_dma
->id
, 10, fifo
, 512);
474 psc_dma
->playback
.bcom_task
=
475 bcom_psc_gen_bd_tx_init(psc_dma
->id
, 10, fifo
);
476 if (!psc_dma
->capture
.bcom_task
||
477 !psc_dma
->playback
.bcom_task
) {
478 dev_err(&op
->dev
, "Could not allocate bestcomm tasks\n");
484 /* Disable all interrupts and reset the PSC */
485 out_be16(&psc_dma
->psc_regs
->isr_imr
.imr
, psc_dma
->imr
);
487 out_8(&psc_dma
->psc_regs
->command
, MPC52xx_PSC_RST_RX
);
488 /* reset transmitter */
489 out_8(&psc_dma
->psc_regs
->command
, MPC52xx_PSC_RST_TX
);
491 out_8(&psc_dma
->psc_regs
->command
, MPC52xx_PSC_RST_ERR_STAT
);
493 out_8(&psc_dma
->psc_regs
->command
, MPC52xx_PSC_SEL_MODE_REG_1
);
495 /* Set up mode register;
496 * First write: RxRdy (FIFO Alarm) generates rx FIFO irq
497 * Second write: register Normal mode for non loopback
499 out_8(&psc_dma
->psc_regs
->mode
, 0);
500 out_8(&psc_dma
->psc_regs
->mode
, 0);
502 /* Set the TX and RX fifo alarm thresholds */
503 out_be16(&psc_dma
->fifo_regs
->rfalarm
, 0x100);
504 out_8(&psc_dma
->fifo_regs
->rfcntl
, 0x4);
505 out_be16(&psc_dma
->fifo_regs
->tfalarm
, 0x100);
506 out_8(&psc_dma
->fifo_regs
->tfcntl
, 0x7);
508 /* Lookup the IRQ numbers */
509 psc_dma
->playback
.irq
=
510 bcom_get_task_irq(psc_dma
->playback
.bcom_task
);
511 psc_dma
->capture
.irq
=
512 bcom_get_task_irq(psc_dma
->capture
.bcom_task
);
514 rc
= request_irq(psc_dma
->irq
, &psc_dma_status_irq
, IRQF_SHARED
,
515 "psc-dma-status", psc_dma
);
516 rc
|= request_irq(psc_dma
->capture
.irq
,
517 &psc_dma_bcom_irq_rx
, IRQF_SHARED
,
518 "psc-dma-capture", &psc_dma
->capture
);
519 rc
|= request_irq(psc_dma
->playback
.irq
,
520 &psc_dma_bcom_irq_tx
, IRQF_SHARED
,
521 "psc-dma-playback", &psc_dma
->playback
);
523 free_irq(psc_dma
->irq
, psc_dma
);
524 free_irq(psc_dma
->capture
.irq
,
526 free_irq(psc_dma
->playback
.irq
,
531 /* Save what we've done so it can be found again later */
532 dev_set_drvdata(&op
->dev
, psc_dma
);
534 /* Tell the ASoC OF helpers about it */
535 return snd_soc_register_platform(&mpc5200_audio_dma_platform
);
537 EXPORT_SYMBOL_GPL(mpc5200_audio_dma_create
);
539 int mpc5200_audio_dma_destroy(struct of_device
*op
)
541 struct psc_dma
*psc_dma
= dev_get_drvdata(&op
->dev
);
543 dev_dbg(&op
->dev
, "mpc5200_audio_dma_destroy()\n");
545 snd_soc_unregister_platform(&mpc5200_audio_dma_platform
);
547 bcom_gen_bd_rx_release(psc_dma
->capture
.bcom_task
);
548 bcom_gen_bd_tx_release(psc_dma
->playback
.bcom_task
);
551 free_irq(psc_dma
->irq
, psc_dma
);
552 free_irq(psc_dma
->capture
.irq
, &psc_dma
->capture
);
553 free_irq(psc_dma
->playback
.irq
, &psc_dma
->playback
);
555 iounmap(psc_dma
->psc_regs
);
557 dev_set_drvdata(&op
->dev
, NULL
);
561 EXPORT_SYMBOL_GPL(mpc5200_audio_dma_destroy
);
563 MODULE_AUTHOR("Grant Likely <grant.likely@secretlab.ca>");
564 MODULE_DESCRIPTION("Freescale MPC5200 PSC in DMA mode ASoC Driver");
565 MODULE_LICENSE("GPL");