summaryrefslogtreecommitdiff
path: root/firmware/target/arm/imx31/gigabeat-s/pcm-gigabeat-s.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/arm/imx31/gigabeat-s/pcm-gigabeat-s.c')
-rw-r--r--firmware/target/arm/imx31/gigabeat-s/pcm-gigabeat-s.c81
1 files changed, 30 insertions, 51 deletions
diff --git a/firmware/target/arm/imx31/gigabeat-s/pcm-gigabeat-s.c b/firmware/target/arm/imx31/gigabeat-s/pcm-gigabeat-s.c
index 02051fad90..2c65c70360 100644
--- a/firmware/target/arm/imx31/gigabeat-s/pcm-gigabeat-s.c
+++ b/firmware/target/arm/imx31/gigabeat-s/pcm-gigabeat-s.c
@@ -52,9 +52,9 @@ static struct dma_data dma_play_data =
52 52
53static void play_dma_callback(void) 53static void play_dma_callback(void)
54{ 54{
55 unsigned char *start; 55 void *start;
56 size_t size = 0; 56 size_t size;
57 pcm_more_callback_type get_more = pcm_callback_for_more; 57 bool rror;
58 58
59 if (dma_play_data.locked != 0) 59 if (dma_play_data.locked != 0)
60 { 60 {
@@ -63,28 +63,20 @@ static void play_dma_callback(void)
63 return; 63 return;
64 } 64 }
65 65
66 if (dma_play_bd.mode.status & BD_RROR) 66 rror = dma_play_bd.mode.status & BD_RROR;
67 { 67
68 /* Stop on error */ 68 pcm_play_get_more_callback(rror ? NULL : &start, &size);
69 } 69
70 else if (get_more != NULL && (get_more(&start, &size), size != 0)) 70 if (size == 0)
71 {
72 start = (void*)(((unsigned long)start + 3) & ~3);
73 size &= ~3;
74
75 /* Flush any pending cache writes */
76 clean_dcache_range(start, size);
77 dma_play_bd.buf_addr = (void *)addr_virt_to_phys((unsigned long)start);
78 dma_play_bd.mode.count = size;
79 dma_play_bd.mode.command = TRANSFER_16BIT;
80 dma_play_bd.mode.status = BD_DONE | BD_WRAP | BD_INTR;
81 sdma_channel_run(DMA_PLAY_CH_NUM);
82 return; 71 return;
83 }
84 72
85 /* Error, callback missing or no more DMA to do */ 73 /* Flush any pending cache writes */
86 pcm_play_dma_stop(); 74 clean_dcache_range(start, size);
87 pcm_play_dma_stopped_callback(); 75 dma_play_bd.buf_addr = (void *)addr_virt_to_phys((unsigned long)start);
76 dma_play_bd.mode.count = size;
77 dma_play_bd.mode.command = TRANSFER_16BIT;
78 dma_play_bd.mode.status = BD_DONE | BD_WRAP | BD_INTR;
79 sdma_channel_run(DMA_PLAY_CH_NUM);
88} 80}
89 81
90void pcm_play_lock(void) 82void pcm_play_lock(void)
@@ -272,12 +264,6 @@ void pcm_play_dma_start(const void *addr, size_t size)
272 SSI_STCR2 &= ~SSI_STCR_TFEN0; 264 SSI_STCR2 &= ~SSI_STCR_TFEN0;
273 SSI_SCR2 &= ~(SSI_SCR_TE | SSI_SCR_SSIEN); 265 SSI_SCR2 &= ~(SSI_SCR_TE | SSI_SCR_SSIEN);
274 266
275 addr = (void *)(((unsigned long)addr + 3) & ~3);
276 size &= ~3;
277
278 if (size <= 0)
279 return;
280
281 if (!sdma_channel_reset(DMA_PLAY_CH_NUM)) 267 if (!sdma_channel_reset(DMA_PLAY_CH_NUM))
282 return; 268 return;
283 269
@@ -383,8 +369,9 @@ static struct dma_data dma_rec_data =
383 369
384static void rec_dma_callback(void) 370static void rec_dma_callback(void)
385{ 371{
386 pcm_more_callback_type2 more_ready;
387 int status = 0; 372 int status = 0;
373 void *start;
374 size_t size;
388 375
389 if (dma_rec_data.locked != 0) 376 if (dma_rec_data.locked != 0)
390 { 377 {
@@ -395,17 +382,22 @@ static void rec_dma_callback(void)
395 if (dma_rec_bd.mode.status & BD_RROR) 382 if (dma_rec_bd.mode.status & BD_RROR)
396 status = DMA_REC_ERROR_DMA; 383 status = DMA_REC_ERROR_DMA;
397 384
398 more_ready = pcm_callback_more_ready; 385 pcm_rec_more_ready_callback(status, &start, &size);
399 386
400 if (more_ready != NULL && more_ready(status) >= 0) 387 if (size == 0)
401 {
402 sdma_channel_run(DMA_REC_CH_NUM);
403 return; 388 return;
404 }
405 389
406 /* Finished recording */ 390 /* Invalidate - buffer must be coherent */
407 pcm_rec_dma_stop(); 391 dump_dcache_range(start, size);
408 pcm_rec_dma_stopped_callback(); 392
393 start = (void *)addr_virt_to_phys((unsigned long)start);
394
395 dma_rec_bd.buf_addr = start;
396 dma_rec_bd.mode.count = size;
397 dma_rec_bd.mode.command = TRANSFER_16BIT;
398 dma_rec_bd.mode.status = BD_DONE | BD_WRAP | BD_INTR;
399
400 sdma_channel_run(DMA_REC_CH_NUM);
409} 401}
410 402
411void pcm_rec_lock(void) 403void pcm_rec_lock(void)
@@ -432,19 +424,6 @@ void pcm_rec_unlock(void)
432 } 424 }
433} 425}
434 426
435void pcm_rec_dma_record_more(void *start, size_t size)
436{
437 /* Invalidate - buffer must be coherent */
438 dump_dcache_range(start, size);
439
440 start = (void *)addr_virt_to_phys((unsigned long)start);
441
442 dma_rec_bd.buf_addr = start;
443 dma_rec_bd.mode.count = size;
444 dma_rec_bd.mode.command = TRANSFER_16BIT;
445 dma_rec_bd.mode.status = BD_DONE | BD_WRAP | BD_INTR;
446}
447
448void pcm_rec_dma_stop(void) 427void pcm_rec_dma_stop(void)
449{ 428{
450 /* Stop receiving data */ 429 /* Stop receiving data */