summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Sevakis <jethead71@rockbox.org>2009-02-09 03:13:04 +0000
committerMichael Sevakis <jethead71@rockbox.org>2009-02-09 03:13:04 +0000
commit9f5687c9e633dcc2caef7351747af9ee86689590 (patch)
tree9cd9d98cc02d54ed60e803cea0a8d89b8933d060
parent305d86d045a6336de893003fb5cffe940fd76eab (diff)
downloadrockbox-9f5687c9e633dcc2caef7351747af9ee86689590.tar.gz
rockbox-9f5687c9e633dcc2caef7351747af9ee86689590.zip
Gigabeat S: The PCM lockout routines needed a bit of polishing.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@19952 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--firmware/target/arm/imx31/gigabeat-s/pcm-imx31.c36
1 files changed, 14 insertions, 22 deletions
diff --git a/firmware/target/arm/imx31/gigabeat-s/pcm-imx31.c b/firmware/target/arm/imx31/gigabeat-s/pcm-imx31.c
index 60801262b4..c5ba27ace6 100644
--- a/firmware/target/arm/imx31/gigabeat-s/pcm-imx31.c
+++ b/firmware/target/arm/imx31/gigabeat-s/pcm-imx31.c
@@ -54,10 +54,10 @@ static void play_dma_callback(void)
54 size_t size; 54 size_t size;
55 pcm_more_callback_type get_more = pcm_callback_for_more; 55 pcm_more_callback_type get_more = pcm_callback_for_more;
56 56
57 if (dma_play_data.locked) 57 if (dma_play_data.locked != 0)
58 { 58 {
59 /* Callback is locked out */ 59 /* Callback is locked out */
60 dma_play_data.callback_pending = 1; 60 dma_play_data.callback_pending = dma_play_data.state;
61 return; 61 return;
62 } 62 }
63 63
@@ -92,22 +92,16 @@ void pcm_play_unlock(void)
92{ 92{
93 if (--dma_play_data.locked == 0 && dma_play_data.state != 0) 93 if (--dma_play_data.locked == 0 && dma_play_data.state != 0)
94 { 94 {
95 bool pending = false;
96 int oldstatus = disable_irq_save(); 95 int oldstatus = disable_irq_save();
97 96 int pending = dma_play_data.callback_pending;
98 if (dma_play_data.callback_pending) 97 dma_play_data.callback_pending = 0;
99 {
100 pending = true;
101 dma_play_data.callback_pending = 0;
102 }
103
104 SSI_SIER1 |= SSI_SIER_TDMAE; 98 SSI_SIER1 |= SSI_SIER_TDMAE;
105 restore_irq(oldstatus); 99 restore_irq(oldstatus);
106 100
107 /* Should an interrupt be forced instead? The upper pcm layer can 101 /* Should an interrupt be forced instead? The upper pcm layer can
108 * call producer's callback in thread context so technically this is 102 * call producer's callback in thread context so technically this is
109 * acceptable. */ 103 * acceptable. */
110 if (pending) 104 if (pending != 0)
111 play_dma_callback(); 105 play_dma_callback();
112 } 106 }
113} 107}
@@ -258,6 +252,7 @@ static void play_stop_pcm(void)
258 SSI_STCR1 &= ~SSI_STCR_TFEN0; 252 SSI_STCR1 &= ~SSI_STCR_TFEN0;
259 SSI_SCR1 &= ~(SSI_SCR_TE | SSI_SCR_SSIEN); 253 SSI_SCR1 &= ~(SSI_SCR_TE | SSI_SCR_SSIEN);
260 254
255 /* Set state before pending to prevent race with interrupt */
261 /* Do not enable DMA requests on unlock */ 256 /* Do not enable DMA requests on unlock */
262 dma_play_data.state = 0; 257 dma_play_data.state = 0;
263 dma_play_data.callback_pending = 0; 258 dma_play_data.callback_pending = 0;
@@ -370,6 +365,7 @@ static struct dma_data dma_rec_data =
370{ 365{
371 /* Initialize to a locked, stopped state */ 366 /* Initialize to a locked, stopped state */
372 .locked = 0, 367 .locked = 0,
368 .callback_pending = 0,
373 .state = 0 369 .state = 0
374}; 370};
375 371
@@ -378,9 +374,9 @@ static void rec_dma_callback(void)
378 pcm_more_callback_type2 more_ready; 374 pcm_more_callback_type2 more_ready;
379 int status = 0; 375 int status = 0;
380 376
381 if (dma_rec_data.locked) 377 if (dma_rec_data.locked != 0)
382 { 378 {
383 dma_rec_data.callback_pending = 1; 379 dma_rec_data.callback_pending = dma_rec_data.state;
384 return; /* Callback is locked out */ 380 return; /* Callback is locked out */
385 } 381 }
386 382
@@ -410,22 +406,16 @@ void pcm_rec_unlock(void)
410{ 406{
411 if (--dma_rec_data.locked == 0 && dma_rec_data.state != 0) 407 if (--dma_rec_data.locked == 0 && dma_rec_data.state != 0)
412 { 408 {
413 bool pending = false;
414 int oldstatus = disable_irq_save(); 409 int oldstatus = disable_irq_save();
415 410 int pending = dma_rec_data.callback_pending;
416 if (dma_rec_data.callback_pending) 411 dma_rec_data.callback_pending = 0;
417 {
418 pending = true;
419 dma_rec_data.callback_pending = 0;
420 }
421
422 SSI_SIER2 |= SSI_SIER_RDMAE; 412 SSI_SIER2 |= SSI_SIER_RDMAE;
423 restore_irq(oldstatus); 413 restore_irq(oldstatus);
424 414
425 /* Should an interrupt be forced instead? The upper pcm layer can 415 /* Should an interrupt be forced instead? The upper pcm layer can
426 * call consumer's callback in thread context so technically this is 416 * call consumer's callback in thread context so technically this is
427 * acceptable. */ 417 * acceptable. */
428 if (pending) 418 if (pending != 0)
429 rec_dma_callback(); 419 rec_dma_callback();
430 } 420 }
431} 421}
@@ -457,6 +447,8 @@ void pcm_rec_dma_stop(void)
457 SSI_SCR2 &= ~SSI_SCR_RE; /* Disable RX */ 447 SSI_SCR2 &= ~SSI_SCR_RE; /* Disable RX */
458 SSI_SRCR2 &= ~SSI_SRCR_RFEN0; /* Disable RX FIFO */ 448 SSI_SRCR2 &= ~SSI_SRCR_RFEN0; /* Disable RX FIFO */
459 449
450 /* Set state before pending to prevent race with interrupt */
451 /* Do not enable DMA requests on unlock */
460 dma_rec_data.state = 0; 452 dma_rec_data.state = 0;
461 dma_rec_data.callback_pending = 0; 453 dma_rec_data.callback_pending = 0;
462} 454}