From d56999890f2aacf197d9ae4383313271499509a9 Mon Sep 17 00:00:00 2001 From: Michael Sevakis Date: Mon, 24 May 2010 16:42:32 +0000 Subject: Make PCM->driver interface about as simple as it will get. Registered callback, zero data, alignment and stops are handled entirely inside pcm.c; driver merely calls fixed pcm.c callback. Remove pcm_record_more and do it just like playback; the original reason behind it isn't very practical in general. Everything checks out on supported targets. There wer some compat changes I can't check out on many unsupoorted but if there's a problem it will be a minor oops. Plugins become incompatible due to recording tweak-- full update. Sorted API. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@26253 a1c6a512-1295-4272-9138-f99709370657 --- firmware/target/arm/as3525/pcm-as3525.c | 43 ++++------- .../target/arm/imx31/gigabeat-s/pcm-gigabeat-s.c | 81 ++++++++------------- firmware/target/arm/pcm-pp.c | 83 +++++----------------- firmware/target/arm/pcm-telechips.c | 43 +++-------- firmware/target/arm/pnx0101/pcm-pnx0101.c | 7 +- .../target/arm/s3c2440/gigabeat-fx/pcm-meg-fx.c | 34 ++++----- .../target/arm/s3c2440/mini2440/pcm-mini2440.c | 34 ++++----- firmware/target/arm/s5l8700/pcm-s5l8700.c | 22 ++---- .../target/arm/tms320dm320/mrobe-500/pcm-mr500.c | 15 +--- 9 files changed, 105 insertions(+), 257 deletions(-) (limited to 'firmware/target/arm') diff --git a/firmware/target/arm/as3525/pcm-as3525.c b/firmware/target/arm/as3525/pcm-as3525.c index cefca0fbe5..a2e3cfbf9f 100644 --- a/firmware/target/arm/as3525/pcm-as3525.c +++ b/firmware/target/arm/as3525/pcm-as3525.c @@ -74,18 +74,13 @@ static void dma_callback(void) { if(!dma_size) { - register pcm_more_callback_type get_more = pcm_callback_for_more; - if(get_more) - get_more(&dma_start_addr, &dma_size); - } + pcm_play_get_more_callback(&dma_start_addr, &dma_size); - if(!dma_size) - { - pcm_play_dma_stop(); - pcm_play_dma_stopped_callback(); + if (!dma_size) + return; } - else - play_start_pcm(); + + play_start_pcm(); } void pcm_play_dma_start(const void *addr, size_t size) @@ -275,31 +270,19 @@ static void rec_dma_callback(void) if(!rec_dma_size) { - register pcm_more_callback_type2 more_ready = pcm_callback_more_ready; - if (!more_ready || more_ready(0) < 0) - { - /* Finished recording */ - pcm_rec_dma_stop(); - pcm_rec_dma_stopped_callback(); - return; - } - } - - rec_dma_start(); -} - + pcm_rec_more_ready_callback(0, &rec_dma_start_addr, &rec_dma_size); -void pcm_rec_dma_record_more(void *start, size_t size) -{ - dump_dcache_range(start, size); - rec_dma_start_addr = start; + if(rec_dma_size != 0) + { + dump_dcache_range(rec_dma_start_addr, rec_dma_size); #if CONFIG_CPU == AS3525 - mono_samples = AS3525_UNCACHED_ADDR(start); + mono_samples = AS3525_UNCACHED_ADDR(rec_dma_start_addr); #endif - rec_dma_size = size; + rec_dma_start(); + } + } } - void pcm_rec_dma_stop(void) { dma_disable_channel(1); 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 = static void play_dma_callback(void) { - unsigned char *start; - size_t size = 0; - pcm_more_callback_type get_more = pcm_callback_for_more; + void *start; + size_t size; + bool rror; if (dma_play_data.locked != 0) { @@ -63,28 +63,20 @@ static void play_dma_callback(void) return; } - if (dma_play_bd.mode.status & BD_RROR) - { - /* Stop on error */ - } - else if (get_more != NULL && (get_more(&start, &size), size != 0)) - { - start = (void*)(((unsigned long)start + 3) & ~3); - size &= ~3; - - /* Flush any pending cache writes */ - clean_dcache_range(start, size); - dma_play_bd.buf_addr = (void *)addr_virt_to_phys((unsigned long)start); - dma_play_bd.mode.count = size; - dma_play_bd.mode.command = TRANSFER_16BIT; - dma_play_bd.mode.status = BD_DONE | BD_WRAP | BD_INTR; - sdma_channel_run(DMA_PLAY_CH_NUM); + rror = dma_play_bd.mode.status & BD_RROR; + + pcm_play_get_more_callback(rror ? NULL : &start, &size); + + if (size == 0) return; - } - /* Error, callback missing or no more DMA to do */ - pcm_play_dma_stop(); - pcm_play_dma_stopped_callback(); + /* Flush any pending cache writes */ + clean_dcache_range(start, size); + dma_play_bd.buf_addr = (void *)addr_virt_to_phys((unsigned long)start); + dma_play_bd.mode.count = size; + dma_play_bd.mode.command = TRANSFER_16BIT; + dma_play_bd.mode.status = BD_DONE | BD_WRAP | BD_INTR; + sdma_channel_run(DMA_PLAY_CH_NUM); } void pcm_play_lock(void) @@ -272,12 +264,6 @@ void pcm_play_dma_start(const void *addr, size_t size) SSI_STCR2 &= ~SSI_STCR_TFEN0; SSI_SCR2 &= ~(SSI_SCR_TE | SSI_SCR_SSIEN); - addr = (void *)(((unsigned long)addr + 3) & ~3); - size &= ~3; - - if (size <= 0) - return; - if (!sdma_channel_reset(DMA_PLAY_CH_NUM)) return; @@ -383,8 +369,9 @@ static struct dma_data dma_rec_data = static void rec_dma_callback(void) { - pcm_more_callback_type2 more_ready; int status = 0; + void *start; + size_t size; if (dma_rec_data.locked != 0) { @@ -395,17 +382,22 @@ static void rec_dma_callback(void) if (dma_rec_bd.mode.status & BD_RROR) status = DMA_REC_ERROR_DMA; - more_ready = pcm_callback_more_ready; + pcm_rec_more_ready_callback(status, &start, &size); - if (more_ready != NULL && more_ready(status) >= 0) - { - sdma_channel_run(DMA_REC_CH_NUM); + if (size == 0) return; - } - /* Finished recording */ - pcm_rec_dma_stop(); - pcm_rec_dma_stopped_callback(); + /* Invalidate - buffer must be coherent */ + dump_dcache_range(start, size); + + start = (void *)addr_virt_to_phys((unsigned long)start); + + dma_rec_bd.buf_addr = start; + dma_rec_bd.mode.count = size; + dma_rec_bd.mode.command = TRANSFER_16BIT; + dma_rec_bd.mode.status = BD_DONE | BD_WRAP | BD_INTR; + + sdma_channel_run(DMA_REC_CH_NUM); } void pcm_rec_lock(void) @@ -432,19 +424,6 @@ void pcm_rec_unlock(void) } } -void pcm_rec_dma_record_more(void *start, size_t size) -{ - /* Invalidate - buffer must be coherent */ - dump_dcache_range(start, size); - - start = (void *)addr_virt_to_phys((unsigned long)start); - - dma_rec_bd.buf_addr = start; - dma_rec_bd.mode.count = size; - dma_rec_bd.mode.command = TRANSFER_16BIT; - dma_rec_bd.mode.status = BD_DONE | BD_WRAP | BD_INTR; -} - void pcm_rec_dma_stop(void) { /* Stop receiving data */ diff --git a/firmware/target/arm/pcm-pp.c b/firmware/target/arm/pcm-pp.c index e0b603c81f..6289b4c730 100644 --- a/firmware/target/arm/pcm-pp.c +++ b/firmware/target/arm/pcm-pp.c @@ -115,7 +115,6 @@ void pcm_dma_apply_settings(void) /* NOTE: direct stack use forbidden by GCC stack handling bug for FIQ */ void ICODE_ATTR __attribute__((interrupt("FIQ"))) fiq_playback(void) { - register pcm_more_callback_type get_more; register size_t size; DMA0_STATUS; /* Clear any pending interrupt */ @@ -141,15 +140,12 @@ void ICODE_ATTR __attribute__((interrupt("FIQ"))) fiq_playback(void) } /* Buffer empty. Try to get more. */ - get_more = pcm_callback_for_more; - if (get_more) { - get_more((unsigned char **)&dma_play_data.addr, &dma_play_data.size); - dma_play_data.addr = (dma_play_data.addr + 2) & ~3; - dma_play_data.size &= ~3; - } + pcm_play_get_more_callback((void **)&dma_play_data.addr, + &dma_play_data.size); if (dma_play_data.size == 0) { - break; + /* No more data */ + return; } if (dma_play_data.addr < UNCACHED_BASE_ADDR) { @@ -158,10 +154,6 @@ void ICODE_ATTR __attribute__((interrupt("FIQ"))) fiq_playback(void) cpucache_flush(); } } - - /* Callback missing or no more DMA to do */ - pcm_play_dma_stop(); - pcm_play_dma_stopped_callback(); } #else /* ASM optimised FIQ handler. Checks for the minimum allowed loop cycles by @@ -247,28 +239,16 @@ void fiq_playback(void) #endif ".more_data: \n" - "ldr r2, =pcm_callback_for_more \n" - "ldr r2, [r2] \n" /* get callback address */ - "cmp r2, #0 \n" /* check for null pointer */ - "beq .stop \n" /* callback removed, stop */ - "stmia r11, { r8-r9 } \n" /* save internal copies of variables back */ + "ldr r2, =pcm_play_get_more_callback \n" "mov r0, r11 \n" /* r0 = &p */ "add r1, r11, #4 \n" /* r1 = &size */ - "mov lr, pc \n" /* call pcm_callback_for_more */ + "mov lr, pc \n" /* call pcm_play_get_more_callback */ "bx r2 \n" - "ldmia r11, { r8-r9 } \n" /* reload p and size */ - "cmp r9, #0 \n" /* did we actually get more data? */ - "bne .check_fifo \n" - - ".stop: \n" /* call termination routines */ - "ldr r12, =pcm_play_dma_stop \n" - "mov lr, pc \n" - "bx r12 \n" - "ldr r12, =pcm_play_dma_stopped_callback \n" - "mov lr, pc \n" - "bx r12 \n" - - ".exit: \n" /* (r8=0 if stopping, look above) */ + "ldmia r11, { r8-r9 } \n" /* load new p and size */ + "cmp r9, #0 \n" + "bne .check_fifo \n" /* size != 0? refill */ + + ".exit: \n" /* (r9=0 if stopping, look above) */ "stmia r11, { r8-r9 } \n" /* save p and size */ "ldmfd sp!, { r0-r3, lr } \n" "subs pc, lr, #4 \n" /* FIQ specific return sequence */ @@ -284,8 +264,6 @@ void fiq_playback(void) __attribute__((interrupt ("FIQ"))) ICODE_ATTR; /* NOTE: direct stack use forbidden by GCC stack handling bug for FIQ */ void fiq_playback(void) { - register pcm_more_callback_type get_more; - #if CONFIG_CPU == PP5002 inl(0xcf001040); #endif @@ -305,16 +283,11 @@ void fiq_playback(void) } /* p is empty, get some more data */ - get_more = pcm_callback_for_more; - if (get_more) { - get_more((unsigned char**)&dma_play_data.addr, - &dma_play_data.size); - } + pcm_play_get_more_callback((void **)&dma_play_data.addr, + &dma_play_data.size); } while (dma_play_data.size); - /* No more data, so disable the FIFO/interrupt */ - pcm_play_dma_stop(); - pcm_play_dma_stopped_callback(); + /* No more data */ } #endif /* ASM / C selection */ #endif /* CPU_PP502x */ @@ -589,7 +562,6 @@ void fiq_record(void) ICODE_ATTR __attribute__((interrupt ("FIQ"))); #if defined(SANSA_C200) || defined(SANSA_E200) void fiq_record(void) { - register pcm_more_callback_type2 more_ready; register int32_t value; if (audio_channels == 2) { @@ -648,20 +620,13 @@ void fiq_record(void) } } - more_ready = pcm_callback_more_ready; - - if (more_ready == NULL || more_ready(0) < 0) { - /* Finished recording */ - pcm_rec_dma_stop(); - pcm_rec_dma_stopped_callback(); - } + pcm_rec_more_ready_callback(0, (void *)&dma_rec_data.addr, + &dma_rec_data.size); } #else void fiq_record(void) { - register pcm_more_callback_type2 more_ready; - while (dma_rec_data.size > 0) { if (IIS_RX_FULL_COUNT < 2) { return; @@ -676,24 +641,12 @@ void fiq_record(void) dma_rec_data.size -= 4; } - more_ready = pcm_callback_more_ready; - - if (more_ready == NULL || more_ready(0) < 0) { - /* Finished recording */ - pcm_rec_dma_stop(); - pcm_rec_dma_stopped_callback(); - } + pcm_rec_more_ready_callback(0, (void *)&dma_rec_data.addr, + &dma_rec_data.size); } #endif /* SANSA_E200 */ -/* Continue transferring data in */ -void pcm_rec_dma_record_more(void *start, size_t size) -{ - dma_rec_data.addr = (unsigned long)start; /* Start of RX buffer */ - dma_rec_data.size = size; /* Bytes to transfer */ -} - void pcm_rec_dma_stop(void) { /* disable interrupt */ diff --git a/firmware/target/arm/pcm-telechips.c b/firmware/target/arm/pcm-telechips.c index 3ce038ffcd..d718ca38ac 100644 --- a/firmware/target/arm/pcm-telechips.c +++ b/firmware/target/arm/pcm-telechips.c @@ -233,12 +233,6 @@ const void * pcm_rec_dma_get_peak_buffer(void) { return NULL; } - -void pcm_record_more(void *start, size_t size) -{ - (void) start; - (void) size; -} #endif #if defined(CPU_TCC77X) || defined(CPU_TCC780X) @@ -289,21 +283,14 @@ void fiq_handler(void) ".more_data: \n" "stmfd sp!, { r0-r3, lr } \n" /* stack scratch regs and lr */ - "ldr r2, =pcm_callback_for_more \n" - "ldr r2, [r2] \n" /* get callback address */ - "cmp r2, #0 \n" /* check for null pointer */ - "movne r0, r11 \n" /* r0 = &p */ - "addne r1, r11, #4 \n" /* r1 = &size */ - "blxne r2 \n" /* call pcm_callback_for_more */ - "ldmia r11, { r8-r9 } \n" /* reload p and size */ - "cmp r9, #0x10 \n" /* did we actually get more data? */ - "ldmgefd sp!, { r0-r3, lr } \n" - "bge .fill_fifo \n" /* yes: fill the fifo */ - "ldr r12, =pcm_play_dma_stop \n" - "blx r12 \n" /* no: stop playback */ - "ldr r12, =pcm_play_dma_stopped_callback \n" - "blx r12 \n" + "ldr r2, =pcm_play_get_more_callback \n" + "mov r0, r11 \n" /* r0 = &p */ + "add r1, r11, #4 \n" /* r1 = &size */ + "blx r2 \n" /* call pcm_play_get_more_callback */ + "ldmia r11, { r8-r9 } \n" /* load new p and size */ + "cmp r9, #0x10 \n" /* did we actually get enough data? */ "ldmfd sp!, { r0-r3, lr } \n" + "bpl .fill_fifo \n" /* not stop and enough? refill */ "b .exit \n" ".ltorg \n" ); @@ -315,17 +302,11 @@ void fiq_handler(void) asm volatile( "stmfd sp!, {r0-r7, ip, lr} \n" /* Store context */ "sub sp, sp, #8 \n"); /* Reserve stack */ - register pcm_more_callback_type get_more; - if (dma_play_data.size < 16) { /* p is empty, get some more data */ - get_more = pcm_callback_for_more; - if (get_more) - { - get_more((unsigned char**)&dma_play_data.p, - &dma_play_data.size); - } + pcm_play_get_more_callback((void**)&dma_play_data.p, + &dma_play_data.size); } if (dma_play_data.size >= 16) @@ -341,12 +322,6 @@ void fiq_handler(void) dma_play_data.size -= 16; } - else - { - /* No more data, so disable the FIFO/interrupt */ - pcm_play_dma_stop(); - pcm_play_dma_stopped_callback(); - } /* Clear FIQ status */ CREQ = DAI_TX_IRQ_MASK | DAI_RX_IRQ_MASK; diff --git a/firmware/target/arm/pnx0101/pcm-pnx0101.c b/firmware/target/arm/pnx0101/pcm-pnx0101.c index fe1e05b79a..9d4ffbd773 100644 --- a/firmware/target/arm/pnx0101/pcm-pnx0101.c +++ b/firmware/target/arm/pnx0101/pcm-pnx0101.c @@ -104,13 +104,10 @@ static inline void fill_dma_buf(int offset) p = tmp_p; if (l >= lend) return; - else if (pcm_callback_for_more) - pcm_callback_for_more((unsigned char**)&p, - &p_size); + + pcm_play_get_more_callback((void**)&p, &p_size); } while (p_size); - - pcm_play_dma_stopped_callback(); } if (l < lend) diff --git a/firmware/target/arm/s3c2440/gigabeat-fx/pcm-meg-fx.c b/firmware/target/arm/s3c2440/gigabeat-fx/pcm-meg-fx.c index bb1b2d9eaa..e9f55479c7 100644 --- a/firmware/target/arm/s3c2440/gigabeat-fx/pcm-meg-fx.c +++ b/firmware/target/arm/s3c2440/gigabeat-fx/pcm-meg-fx.c @@ -214,35 +214,27 @@ void pcm_play_dma_pause(bool pause) void fiq_handler(void) { - static unsigned char *start; - static size_t size; - register pcm_more_callback_type get_more; /* No stack for this */ + static void *start; + static size_t size; /* clear any pending interrupt */ SRCPND = DMA2_MASK; /* Buffer empty. Try to get more. */ - get_more = pcm_callback_for_more; - size = 0; + pcm_play_get_more_callback(&start, &size); - if (get_more == NULL || (get_more(&start, &size), size == 0)) - { - /* Callback missing or no more DMA to do */ - pcm_play_dma_stop(); - pcm_play_dma_stopped_callback(); - } - else - { - /* Flush any pending cache writes */ - clean_dcache_range(start, size); + if (size == 0) + return; - /* set the new DMA values */ - DCON2 = DMA_CONTROL_SETUP | (size >> 1); - DISRC2 = (unsigned int)start + 0x30000000; + /* Flush any pending cache writes */ + clean_dcache_range(start, size); - /* Re-Activate the channel */ - DMASKTRIG2 = 0x2; - } + /* set the new DMA values */ + DCON2 = DMA_CONTROL_SETUP | (size >> 1); + DISRC2 = (unsigned int)start + 0x30000000; + + /* Re-Activate the channel */ + DMASKTRIG2 = 0x2; } size_t pcm_get_bytes_waiting(void) diff --git a/firmware/target/arm/s3c2440/mini2440/pcm-mini2440.c b/firmware/target/arm/s3c2440/mini2440/pcm-mini2440.c index 486a235614..30db29c42c 100644 --- a/firmware/target/arm/s3c2440/mini2440/pcm-mini2440.c +++ b/firmware/target/arm/s3c2440/mini2440/pcm-mini2440.c @@ -254,35 +254,27 @@ void pcm_play_dma_pause(bool pause) void fiq_handler(void) { - static unsigned char *start; - static size_t size; - register pcm_more_callback_type get_more; /* No stack for this */ + static void *start; + static size_t size; /* clear any pending interrupt */ SRCPND = DMA2_MASK; /* Buffer empty. Try to get more. */ - get_more = pcm_callback_for_more; - size = 0; + pcm_play_get_more_callback(&start, &size); - if (get_more == NULL || (get_more(&start, &size), size == 0)) - { - /* Callback missing or no more DMA to do */ - pcm_play_dma_stop(); - pcm_play_dma_stopped_callback(); - } - else - { - /* Flush any pending cache writes */ - clean_dcache_range(start, size); + if (size == 0) + return; - /* set the new DMA values */ - DCON2 = DMA_CONTROL_SETUP | (size >> 1); - DISRC2 = (unsigned int)start + 0x30000000; + /* Flush any pending cache writes */ + clean_dcache_range(start, size); - /* Re-Activate the channel */ - DMASKTRIG2 = 0x2; - } + /* set the new DMA values */ + DCON2 = DMA_CONTROL_SETUP | (size >> 1); + DISRC2 = (unsigned int)start + 0x30000000; + + /* Re-Activate the channel */ + DMASKTRIG2 = 0x2; } size_t pcm_get_bytes_waiting(void) diff --git a/firmware/target/arm/s5l8700/pcm-s5l8700.c b/firmware/target/arm/s5l8700/pcm-s5l8700.c index 7798f41d11..4d24b327af 100644 --- a/firmware/target/arm/s5l8700/pcm-s5l8700.c +++ b/firmware/target/arm/s5l8700/pcm-s5l8700.c @@ -102,11 +102,11 @@ static const void* dma_callback(void) { if (dmamode) { - unsigned char *dma_start_addr; - register pcm_more_callback_type get_more = pcm_callback_for_more; - if (get_more) + void *dma_start_addr; + pcm_play_get_more_callback(&dma_start_addr, &nextsize); + + if (nextsize != 0) { - get_more(&dma_start_addr, &nextsize); if (nextsize >= 4096) { dblbufsize = (nextsize >> 4) & ~3; @@ -148,7 +148,6 @@ void fiq_handler(void) "mov r10, #0x00000400 \n" /* INT_DMA */ "str r10, [r11] \n" /* ACK FIQ */ "stmfd sp!, {r0-r3,lr} \n" - "ldreq r0, =pcm_play_dma_stopped_callback \n" "ldrne r0, =dma_callback \n" "mov lr, pc \n" "bx r0 \n" @@ -225,13 +224,6 @@ void pcm_play_dma_start(const void *addr_in, size_t size) #endif /* S3: DMA channel 0 on */ - if (!size) - { - register pcm_more_callback_type get_more = pcm_callback_for_more; - if (get_more) get_more(&addr, &size); - else return; /* Nothing to play!? */ - } - if (!size) return; /* Nothing to play!? */ clean_dcache(); if (size >= 4096) { @@ -367,12 +359,6 @@ void pcm_rec_unlock(void) { } -void pcm_rec_dma_record_more(void *start, size_t size) -{ - (void)start; - (void)size; -} - void pcm_rec_dma_stop(void) { } diff --git a/firmware/target/arm/tms320dm320/mrobe-500/pcm-mr500.c b/firmware/target/arm/tms320dm320/mrobe-500/pcm-mr500.c index ab3ceba0f3..d7d8f92a0c 100644 --- a/firmware/target/arm/tms320dm320/mrobe-500/pcm-mr500.c +++ b/firmware/target/arm/tms320dm320/mrobe-500/pcm-mr500.c @@ -132,8 +132,6 @@ char buffer[80]; void DSPHINT(void) __attribute__ ((section(".icode"))); void DSPHINT(void) { - register pcm_more_callback_type get_more; /* No stack for this */ - unsigned int i; IO_INTC_FIQ0 = 1 << 11; @@ -152,16 +150,9 @@ void DSPHINT(void) case MSG_REFILL: /* Buffer empty. Try to get more. */ - get_more = pcm_callback_for_more; - size = 0; - - if (get_more == NULL || (get_more(&start, &size), size == 0)) - { - /* Callback missing or no more DMA to do */ - pcm_play_dma_stop(); - pcm_play_dma_stopped_callback(); - } - + pcm_play_get_more_callback(&start, &size); + + if (size != 0) { unsigned long sdem_addr=(unsigned long)start - CONFIG_SDRAM_START; /* Flush any pending cache writes */ -- cgit v1.2.3