summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDana Conrad <dconrad@fastmail.com>2023-03-18 14:09:49 -0500
committerDana Conrad <dconrad@fastmail.com>2023-04-02 11:34:39 -0400
commitb31127db7d169153ac11ab71d8c202e7b95365e4 (patch)
treef6aae23705fc2dc256654288594046534d8b1244
parent287747591e9feafa0d5946e3f7614cec3987e2dc (diff)
downloadrockbox-b31127db7d169153ac11ab71d8c202e7b95365e4.tar.gz
rockbox-b31127db7d169153ac11ab71d8c202e7b95365e4.zip
[bugfix] x1000: Wait for FIFO to be empty rather than flushing
When data is not in packed-16-bit mode, flushing the fifo may result in swapping left and right channels if there happens to be an odd number of entries in the FIFO. This is especially likely when switching sample frequencies for some reason. When stopping PCM DMA, disable DMA and Underrun Interrupts and then wait for FIFO to be empty before stopping AIC's playback. Change-Id: I45b6b022c9e3889627842663cd9b7d2e0affb7c6
-rw-r--r--firmware/target/mips/ingenic_x1000/pcm-x1000.c19
1 files changed, 17 insertions, 2 deletions
diff --git a/firmware/target/mips/ingenic_x1000/pcm-x1000.c b/firmware/target/mips/ingenic_x1000/pcm-x1000.c
index 7d1c83a35a..4b9cb85b57 100644
--- a/firmware/target/mips/ingenic_x1000/pcm-x1000.c
+++ b/firmware/target/mips/ingenic_x1000/pcm-x1000.c
@@ -168,8 +168,23 @@ void pcm_play_dma_start(const void* addr, size_t size)
168 168
169void pcm_play_dma_stop(void) 169void pcm_play_dma_stop(void)
170{ 170{
171 jz_writef(AIC_CCR, TDMS(0), ETUR(0), ERPL(0)); 171 /* disable DMA and underrun interrupts */
172 jz_writef(AIC_CCR, TFLUSH(1)); 172 jz_writef(AIC_CCR, TDMS(0), ETUR(0));
173
174 /*
175 * wait for FIFO to be empty - on targets
176 * with >16bit samples, flushing the fifo
177 * may result in swapping l and r channels!
178 * (ensure bit clock is running first)
179 */
180 if (jz_readf(AIC_I2SCR, STPBK) == 0) {
181 while(jz_readf(AIC_SR, TFL) != 0);
182 } else {
183 panicf("pcm_play_dma_stop: No bit clock running!");
184 }
185
186 /* disable playback */
187 jz_writef(AIC_CCR, ERPL(0));
173 188
174 play_dma_pending_event = DMA_EVENT_NONE; 189 play_dma_pending_event = DMA_EVENT_NONE;
175 aic_state &= ~AIC_STATE_PLAYING; 190 aic_state &= ~AIC_STATE_PLAYING;