mirror of
https://github.com/Rockbox/rockbox.git
synced 2025-12-09 13:15:18 -05:00
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
This commit is contained in:
parent
305d86d045
commit
9f5687c9e6
1 changed files with 14 additions and 22 deletions
|
|
@ -54,10 +54,10 @@ static void play_dma_callback(void)
|
||||||
size_t size;
|
size_t size;
|
||||||
pcm_more_callback_type get_more = pcm_callback_for_more;
|
pcm_more_callback_type get_more = pcm_callback_for_more;
|
||||||
|
|
||||||
if (dma_play_data.locked)
|
if (dma_play_data.locked != 0)
|
||||||
{
|
{
|
||||||
/* Callback is locked out */
|
/* Callback is locked out */
|
||||||
dma_play_data.callback_pending = 1;
|
dma_play_data.callback_pending = dma_play_data.state;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -92,22 +92,16 @@ void pcm_play_unlock(void)
|
||||||
{
|
{
|
||||||
if (--dma_play_data.locked == 0 && dma_play_data.state != 0)
|
if (--dma_play_data.locked == 0 && dma_play_data.state != 0)
|
||||||
{
|
{
|
||||||
bool pending = false;
|
|
||||||
int oldstatus = disable_irq_save();
|
int oldstatus = disable_irq_save();
|
||||||
|
int pending = dma_play_data.callback_pending;
|
||||||
if (dma_play_data.callback_pending)
|
dma_play_data.callback_pending = 0;
|
||||||
{
|
|
||||||
pending = true;
|
|
||||||
dma_play_data.callback_pending = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
SSI_SIER1 |= SSI_SIER_TDMAE;
|
SSI_SIER1 |= SSI_SIER_TDMAE;
|
||||||
restore_irq(oldstatus);
|
restore_irq(oldstatus);
|
||||||
|
|
||||||
/* Should an interrupt be forced instead? The upper pcm layer can
|
/* Should an interrupt be forced instead? The upper pcm layer can
|
||||||
* call producer's callback in thread context so technically this is
|
* call producer's callback in thread context so technically this is
|
||||||
* acceptable. */
|
* acceptable. */
|
||||||
if (pending)
|
if (pending != 0)
|
||||||
play_dma_callback();
|
play_dma_callback();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -258,6 +252,7 @@ static void play_stop_pcm(void)
|
||||||
SSI_STCR1 &= ~SSI_STCR_TFEN0;
|
SSI_STCR1 &= ~SSI_STCR_TFEN0;
|
||||||
SSI_SCR1 &= ~(SSI_SCR_TE | SSI_SCR_SSIEN);
|
SSI_SCR1 &= ~(SSI_SCR_TE | SSI_SCR_SSIEN);
|
||||||
|
|
||||||
|
/* Set state before pending to prevent race with interrupt */
|
||||||
/* Do not enable DMA requests on unlock */
|
/* Do not enable DMA requests on unlock */
|
||||||
dma_play_data.state = 0;
|
dma_play_data.state = 0;
|
||||||
dma_play_data.callback_pending = 0;
|
dma_play_data.callback_pending = 0;
|
||||||
|
|
@ -370,6 +365,7 @@ static struct dma_data dma_rec_data =
|
||||||
{
|
{
|
||||||
/* Initialize to a locked, stopped state */
|
/* Initialize to a locked, stopped state */
|
||||||
.locked = 0,
|
.locked = 0,
|
||||||
|
.callback_pending = 0,
|
||||||
.state = 0
|
.state = 0
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -378,9 +374,9 @@ static void rec_dma_callback(void)
|
||||||
pcm_more_callback_type2 more_ready;
|
pcm_more_callback_type2 more_ready;
|
||||||
int status = 0;
|
int status = 0;
|
||||||
|
|
||||||
if (dma_rec_data.locked)
|
if (dma_rec_data.locked != 0)
|
||||||
{
|
{
|
||||||
dma_rec_data.callback_pending = 1;
|
dma_rec_data.callback_pending = dma_rec_data.state;
|
||||||
return; /* Callback is locked out */
|
return; /* Callback is locked out */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -410,22 +406,16 @@ void pcm_rec_unlock(void)
|
||||||
{
|
{
|
||||||
if (--dma_rec_data.locked == 0 && dma_rec_data.state != 0)
|
if (--dma_rec_data.locked == 0 && dma_rec_data.state != 0)
|
||||||
{
|
{
|
||||||
bool pending = false;
|
|
||||||
int oldstatus = disable_irq_save();
|
int oldstatus = disable_irq_save();
|
||||||
|
int pending = dma_rec_data.callback_pending;
|
||||||
if (dma_rec_data.callback_pending)
|
dma_rec_data.callback_pending = 0;
|
||||||
{
|
|
||||||
pending = true;
|
|
||||||
dma_rec_data.callback_pending = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
SSI_SIER2 |= SSI_SIER_RDMAE;
|
SSI_SIER2 |= SSI_SIER_RDMAE;
|
||||||
restore_irq(oldstatus);
|
restore_irq(oldstatus);
|
||||||
|
|
||||||
/* Should an interrupt be forced instead? The upper pcm layer can
|
/* Should an interrupt be forced instead? The upper pcm layer can
|
||||||
* call consumer's callback in thread context so technically this is
|
* call consumer's callback in thread context so technically this is
|
||||||
* acceptable. */
|
* acceptable. */
|
||||||
if (pending)
|
if (pending != 0)
|
||||||
rec_dma_callback();
|
rec_dma_callback();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -457,6 +447,8 @@ void pcm_rec_dma_stop(void)
|
||||||
SSI_SCR2 &= ~SSI_SCR_RE; /* Disable RX */
|
SSI_SCR2 &= ~SSI_SCR_RE; /* Disable RX */
|
||||||
SSI_SRCR2 &= ~SSI_SRCR_RFEN0; /* Disable RX FIFO */
|
SSI_SRCR2 &= ~SSI_SRCR_RFEN0; /* Disable RX FIFO */
|
||||||
|
|
||||||
|
/* Set state before pending to prevent race with interrupt */
|
||||||
|
/* Do not enable DMA requests on unlock */
|
||||||
dma_rec_data.state = 0;
|
dma_rec_data.state = 0;
|
||||||
dma_rec_data.callback_pending = 0;
|
dma_rec_data.callback_pending = 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue