summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--firmware/drivers/audio/wm8751.c3
-rw-r--r--firmware/target/arm/s3c2440/gigabeat-fx/pcm-meg-fx.c60
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 */
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;