summaryrefslogtreecommitdiff
path: root/firmware/target/arm/as3525/pcm-as3525.c
diff options
context:
space:
mode:
authorMichael Sevakis <jethead71@rockbox.org>2011-01-15 12:13:56 +0000
committerMichael Sevakis <jethead71@rockbox.org>2011-01-15 12:13:56 +0000
commitbb54c8f31556db650f3e89605c699dd41cc2ed52 (patch)
tree32aef72605b0f9fe5cc29d781d8cf234aa61f442 /firmware/target/arm/as3525/pcm-as3525.c
parent27bcc8a8fdbc1ace7a3dda43e8d97ec5ac715578 (diff)
Fix problem with AMS PCM driver that caused mpegplayer lockup. It pre-decremented the size remaining where it is supposed to be post-decremented by the last transfer size in the callback. Pending callbacks also must be cleared when stopping or pausing a channel if they happened before the lock flag was set.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@29059 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/target/arm/as3525/pcm-as3525.c')
-rw-r--r--firmware/target/arm/as3525/pcm-as3525.c20
1 files changed, 16 insertions, 4 deletions
diff --git a/firmware/target/arm/as3525/pcm-as3525.c b/firmware/target/arm/as3525/pcm-as3525.c
index e0cb9aa441..5c53c60fe1 100644
--- a/firmware/target/arm/as3525/pcm-as3525.c
+++ b/firmware/target/arm/as3525/pcm-as3525.c
@@ -37,6 +37,7 @@
static void *dma_start_addr;
static size_t dma_size; /* in 4*32 bits */
+static size_t play_sub_size; /* size of subtransfer */
static void dma_callback(void);
static int locked = 0;
static bool is_playing = false;
@@ -70,8 +71,7 @@ static void play_start_pcm(void)
if(size > MAX_TRANSFER)
size = MAX_TRANSFER;
- dma_size -= size;
- dma_start_addr += size;
+ play_sub_size = size;
clean_dcache_range((void*)addr, size); /* force write back */
dma_enable_channel(1, (void*)addr, (void*)I2SOUT_DATA, DMA_PERI_I2SOUT,
@@ -81,6 +81,10 @@ static void play_start_pcm(void)
static void dma_callback(void)
{
+ dma_size -= play_sub_size;
+ dma_start_addr += play_sub_size;
+ play_sub_size = 0; /* Might get called again if locked */
+
if(locked)
{
play_callback_pending = is_playing;
@@ -123,16 +127,22 @@ void pcm_play_dma_stop(void)
bitclr32(&CGU_PERI, CGU_I2SOUT_APB_CLOCK_ENABLE);
CGU_AUDIO &= ~(1<<11);
+
+ play_callback_pending = false;
}
void pcm_play_dma_pause(bool pause)
{
- is_playing = !pause;
-
if(pause)
+ {
+ is_playing = false;
dma_disable_channel(1);
+ play_callback_pending = false;
+ }
else
+ {
play_start_pcm();
+ }
}
void pcm_play_dma_init(void)
@@ -343,6 +353,8 @@ void pcm_rec_dma_stop(void)
CGU_AUDIO &= ~(1<<11);
bitclr32(&CGU_PERI, CGU_I2SIN_APB_CLOCK_ENABLE |
CGU_I2SOUT_APB_CLOCK_ENABLE);
+
+ rec_callback_pending = false;
}