summaryrefslogtreecommitdiff
path: root/firmware/target/arm/s3c2440/gigabeat-fx/pcm-meg-fx.c
diff options
context:
space:
mode:
authorMichael Sevakis <jethead71@rockbox.org>2007-06-24 20:41:27 +0000
committerMichael Sevakis <jethead71@rockbox.org>2007-06-24 20:41:27 +0000
commitf783617cbcd407090f55dd71b152366a518d3a3a (patch)
treee3791e8e57450e8ccac0fa6ee4c9ebf887d1723a /firmware/target/arm/s3c2440/gigabeat-fx/pcm-meg-fx.c
parentfc9ed84e02c5655e42abfdcc81280ca914ca9936 (diff)
downloadrockbox-f783617cbcd407090f55dd71b152366a518d3a3a.tar.gz
rockbox-f783617cbcd407090f55dd71b152366a518d3a3a.zip
Gigabeat: Audio tweak mishmash - Make sure zero crossing detection times out so the volume always gets updated. Make sure i2s is off at boot and set to proper mode before audio hardware is initialized. Make pausing pcm instant instead of waiting until the end of the current DMA transfer.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@13706 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/target/arm/s3c2440/gigabeat-fx/pcm-meg-fx.c')
-rw-r--r--firmware/target/arm/s3c2440/gigabeat-fx/pcm-meg-fx.c60
1 files changed, 34 insertions, 26 deletions
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 592842668d..0624aa6f2f 100644
--- a/firmware/target/arm/s3c2440/gigabeat-fx/pcm-meg-fx.c
+++ b/firmware/target/arm/s3c2440/gigabeat-fx/pcm-meg-fx.c
@@ -34,9 +34,6 @@ static int pcm_freq = 0; /* 44.1 is default */
34static int sr_ctrl = 0; 34static int sr_ctrl = 0;
35#define FIFO_COUNT ((IISFCON >> 6) & 0x01F) 35#define FIFO_COUNT ((IISFCON >> 6) & 0x01F)
36 36
37/* number of bytes in FIFO */
38#define IIS_FIFO_SIZE 64
39
40/* Setup for the DMA controller */ 37/* Setup for the DMA controller */
41#define DMA_CONTROL_SETUP ((1<<31) | (1<<29) | (1<<23) | (1<<22) | (1<<20)) 38#define DMA_CONTROL_SETUP ((1<<31) | (1<<29) | (1<<23) | (1<<22) | (1<<20))
42 39
@@ -72,6 +69,9 @@ void pcm_init(void)
72 69
73 pcm_set_frequency(SAMPR_44); 70 pcm_set_frequency(SAMPR_44);
74 71
72 /* slave */
73 IISMOD |= (1<<8);
74
75 audiohw_init(); 75 audiohw_init();
76 76
77 /* init GPIO */ 77 /* init GPIO */
@@ -84,7 +84,6 @@ void pcm_init(void)
84 INTMSK |= (1<<19); /* mask the interrupt */ 84 INTMSK |= (1<<19); /* mask the interrupt */
85 SRCPND = (1<<19); /* clear any pending interrupts */ 85 SRCPND = (1<<19); /* clear any pending interrupts */
86 INTMOD |= (1<<19); /* connect to FIQ */ 86 INTMOD |= (1<<19); /* connect to FIQ */
87
88} 87}
89 88
90void pcm_postinit(void) 89void pcm_postinit(void)
@@ -99,7 +98,7 @@ void pcm_play_dma_start(const void *addr, size_t size)
99 size &= ~3; /* Size must be multiple of 4 */ 98 size &= ~3; /* Size must be multiple of 4 */
100 99
101 /* sanity check: bad pointer or too small file */ 100 /* sanity check: bad pointer or too small file */
102 if (NULL == addr || size <= IIS_FIFO_SIZE) return; 101 if (NULL == addr || size == 0) return;
103 102
104 disable_fiq(); 103 disable_fiq();
105 104
@@ -109,8 +108,9 @@ void pcm_play_dma_start(const void *addr, size_t size)
109 /* IIS interface setup and set to idle */ 108 /* IIS interface setup and set to idle */
110 IISCON = (1<<5) | (1<<3); 109 IISCON = (1<<5) | (1<<3);
111 110
112 /* slave, transmit mode, 16 bit samples - 384fs - use 16.9344Mhz */ 111 /* slave, transmit mode, 16 bit samples - MCLK 384fs - use 16.9344Mhz -
113 IISMOD = (1<<9) | (1<<8) | (2<<6) | (1<<3) | (1<<2); 112 BCLK 32fs */
113 IISMOD = (1<<9) | (1<<8) | (2<<6) | (1<<3) | (1<<2) | (1<<0);
114 114
115 /* connect DMA to the FIFO and enable the FIFO */ 115 /* connect DMA to the FIFO and enable the FIFO */
116 IISFCON = (1<<15) | (1<<13); 116 IISFCON = (1<<15) | (1<<13);
@@ -157,8 +157,9 @@ void pcm_play_dma_start(const void *addr, size_t size)
157 157
158static void pcm_play_dma_stop_fiq(void) 158static void pcm_play_dma_stop_fiq(void)
159{ 159{
160 /* mask the DMA interrupt */ 160 INTMSK |= (1<<19); /* mask the DMA interrupt */
161 INTMSK |= (1<<19); 161 IISCON &= ~(1<<5); /* disable fifo request */
162 DMASKTRIG2 = 0x4; /* De-Activate the DMA channel */
162 163
163 /* are we playing? wait for the chunk to finish */ 164 /* are we playing? wait for the chunk to finish */
164 if (pcm_playing) 165 if (pcm_playing)
@@ -170,9 +171,6 @@ static void pcm_play_dma_stop_fiq(void)
170 pcm_paused = false; 171 pcm_paused = false;
171 } 172 }
172 173
173 /* De-Activate the DMA channel */
174 DMASKTRIG2 = 0x4;
175
176 /* Disconnect the IIS clock */ 174 /* Disconnect the IIS clock */
177 CLKCON &= ~(1<<17); 175 CLKCON &= ~(1<<17);
178} 176}
@@ -232,23 +230,39 @@ void pcm_play_dma_stop(void)
232 pcm_play_dma_stop_fiq(); 230 pcm_play_dma_stop_fiq();
233} 231}
234 232
235
236void pcm_play_pause_pause(void) 233void pcm_play_pause_pause(void)
237{ 234{
238 /* stop servicing refills */ 235 /* stop servicing refills */
239 int oldstatus = set_fiq_status(FIQ_DISABLED); 236 int oldstatus = set_fiq_status(FIQ_DISABLED);
240 INTMSK |= (1<<19); 237 INTMSK |= (1<<19); /* mask interrupt request */
241 set_fiq_status(oldstatus); 238 IISCON &= ~(1<<5); /* turn off FIFO request */
242} 239 DMASKTRIG2 = 0x4; /* stop DMA at end of atomic transfer */
243 240
241 if (pcm_playing)
242 {
243 /* playing - wait for the FIFO to empty */
244 while (IISCON & (1<<7)) ;
245 }
244 246
247 set_fiq_status(oldstatus);
248}
245 249
246void pcm_play_pause_unpause(void) 250void pcm_play_pause_unpause(void)
247{ 251{
248 /* refill buffer and keep going */ 252 /* refill buffer and keep going */
249 int oldstatus = set_fiq_status(FIQ_DISABLED); 253 int oldstatus = set_fiq_status(FIQ_DISABLED);
250 _pcm_apply_settings(); 254 _pcm_apply_settings();
251 INTMSK &= ~(1<<19); 255 if (pcm_playing)
256 {
257 /* make sure we're aligned on left channel - skip any right channel
258 sample left waiting */
259 DISRC2 = (DCSRC2 + 2) & ~0x3;
260 DCON2 = (DSTAT2 & 0xFFFFE);
261
262 SRCPND = (1<<19); /* clear pending DMA interrupt */
263 INTMSK &= ~(1<<19); /* unmask interrupt request */
264 IISCON |= (1<<5); /* enable FIFO request */
265 }
252 set_fiq_status(oldstatus); 266 set_fiq_status(oldstatus);
253} 267}
254 268
@@ -275,19 +289,12 @@ void pcm_set_frequency(unsigned int frequency)
275 pcm_freq = frequency; 289 pcm_freq = frequency;
276} 290}
277 291
278
279
280size_t pcm_get_bytes_waiting(void) 292size_t pcm_get_bytes_waiting(void)
281{ 293{
282 return (DSTAT2 & 0xFFFFF) * 2; 294 /* lie a little and only return full pairs */
295 return (DSTAT2 & 0xFFFFE) * 2;
283} 296}
284 297
285#if 0
286void pcm_set_monitor(int monitor)
287{
288 (void)monitor;
289}
290#endif
291/** **/ 298/** **/
292 299
293void pcm_mute(bool mute) 300void pcm_mute(bool mute)
@@ -327,6 +334,7 @@ void pcm_calculate_peaks(int *left, int *right)
327 long samples = DSTAT2; 334 long samples = DSTAT2;
328 long samp_frames; 335 long samp_frames;
329 336
337 addr = (unsigned long *)((unsigned long)addr & ~3);
330 samples &= 0xFFFFE; 338 samples &= 0xFFFFE;
331 samp_frames = frame_period*pcm_freq/(HZ/2); 339 samp_frames = frame_period*pcm_freq/(HZ/2);
332 samples = MIN(samp_frames, samples) >> 1; 340 samples = MIN(samp_frames, samples) >> 1;