diff options
-rw-r--r-- | firmware/drivers/audio/wm8751.c | 3 | ||||
-rw-r--r-- | firmware/target/arm/s3c2440/gigabeat-fx/pcm-meg-fx.c | 60 |
2 files changed, 37 insertions, 26 deletions
diff --git a/firmware/drivers/audio/wm8751.c b/firmware/drivers/audio/wm8751.c index 056b5d6628..426036aab0 100644 --- a/firmware/drivers/audio/wm8751.c +++ b/firmware/drivers/audio/wm8751.c | |||
@@ -122,6 +122,9 @@ void audiohw_postinit(void) | |||
122 | PWRMGMT2_LOUT1 | PWRMGMT2_ROUT1 | PWRMGMT2_LOUT2 | | 122 | PWRMGMT2_LOUT1 | PWRMGMT2_ROUT1 | PWRMGMT2_LOUT2 | |
123 | PWRMGMT2_ROUT2); | 123 | PWRMGMT2_ROUT2); |
124 | 124 | ||
125 | wmcodec_write(ADDITIONAL1, ADDITIONAL1_TSDEN | ADDITIONAL1_TOEN | | ||
126 | ADDITIONAL1_DMONOMIX_LLRR | ADDITIONAL1_VSEL_DEFAULT); | ||
127 | |||
125 | wmcodec_write(LEFTMIX1, LEFTMIX1_LD2LO | LEFTMIX1_LI2LO_DEFAULT); | 128 | wmcodec_write(LEFTMIX1, LEFTMIX1_LD2LO | LEFTMIX1_LI2LO_DEFAULT); |
126 | wmcodec_write(RIGHTMIX2, RIGHTMIX2_RD2RO | RIGHTMIX2_RI2RO_DEFAULT); | 129 | wmcodec_write(RIGHTMIX2, RIGHTMIX2_RD2RO | RIGHTMIX2_RI2RO_DEFAULT); |
127 | 130 | ||
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 */ | |||
34 | static int sr_ctrl = 0; | 34 | static 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 | ||
90 | void pcm_postinit(void) | 89 | void 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 | ||
158 | static void pcm_play_dma_stop_fiq(void) | 158 | static 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 | |||
236 | void pcm_play_pause_pause(void) | 233 | void 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 | ||
246 | void pcm_play_pause_unpause(void) | 250 | void 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 | |||
280 | size_t pcm_get_bytes_waiting(void) | 292 | size_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 | ||
286 | void pcm_set_monitor(int monitor) | ||
287 | { | ||
288 | (void)monitor; | ||
289 | } | ||
290 | #endif | ||
291 | /** **/ | 298 | /** **/ |
292 | 299 | ||
293 | void pcm_mute(bool mute) | 300 | void 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; |