diff options
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.c | 81 |
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 | ||
53 | static void play_dma_callback(void) | 53 | static 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 | ||
90 | void pcm_play_lock(void) | 82 | void 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 | ||
384 | static void rec_dma_callback(void) | 370 | static 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 | ||
411 | void pcm_rec_lock(void) | 403 | void pcm_rec_lock(void) |
@@ -432,19 +424,6 @@ void pcm_rec_unlock(void) | |||
432 | } | 424 | } |
433 | } | 425 | } |
434 | 426 | ||
435 | void 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 | |||
448 | void pcm_rec_dma_stop(void) | 427 | void pcm_rec_dma_stop(void) |
449 | { | 428 | { |
450 | /* Stop receiving data */ | 429 | /* Stop receiving data */ |