summaryrefslogtreecommitdiff
path: root/firmware/target/arm/imx31/gigabeat-s/pcm-imx31.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/arm/imx31/gigabeat-s/pcm-imx31.c')
-rw-r--r--firmware/target/arm/imx31/gigabeat-s/pcm-imx31.c74
1 files changed, 66 insertions, 8 deletions
diff --git a/firmware/target/arm/imx31/gigabeat-s/pcm-imx31.c b/firmware/target/arm/imx31/gigabeat-s/pcm-imx31.c
index ed3650cd60..99aa66a781 100644
--- a/firmware/target/arm/imx31/gigabeat-s/pcm-imx31.c
+++ b/firmware/target/arm/imx31/gigabeat-s/pcm-imx31.c
@@ -37,7 +37,8 @@ struct dma_data
37 int state; 37 int state;
38}; 38};
39 39
40static unsigned long pcm_freq = HW_SAMPR_DEFAULT; /* 44.1 is default */ 40static unsigned long pcm_freq; /* 44.1 is default */
41static int sr_ctrl;
41 42
42static struct dma_data dma_play_data = 43static struct dma_data dma_play_data =
43{ 44{
@@ -71,7 +72,7 @@ static void _pcm_apply_settings(void)
71 if (pcm_freq != pcm_curr_sampr) 72 if (pcm_freq != pcm_curr_sampr)
72 { 73 {
73 pcm_curr_sampr = pcm_freq; 74 pcm_curr_sampr = pcm_freq;
74 // TODO: audiohw_set_frequency(sr_ctrl); 75 audiohw_set_frequency(sr_ctrl);
75 } 76 }
76} 77}
77 78
@@ -110,11 +111,17 @@ static void __attribute__((interrupt("IRQ"))) SSI1_HANDLER(void)
110 111
111void pcm_apply_settings(void) 112void pcm_apply_settings(void)
112{ 113{
113 int oldstatus = disable_fiq_save(); 114 pcm_play_lock();
115#ifdef HAVE_RECORDING
116 pcm_rec_lock();
117#endif
114 118
115 _pcm_apply_settings(); 119 _pcm_apply_settings();
116 120
117 restore_fiq(oldstatus); 121#ifdef HAVE_RECORDING
122 pcm_rec_unlock();
123#endif
124 pcm_play_unlock();
118} 125}
119 126
120void pcm_play_dma_init(void) 127void pcm_play_dma_init(void)
@@ -189,11 +196,25 @@ void pcm_play_dma_init(void)
189 SSI_SCR2 = 0; 196 SSI_SCR2 = 0;
190 SSI_SRCR2 = 0; 197 SSI_SRCR2 = 0;
191 SSI_STCR2 = SSI_STCR_TXDIR; 198 SSI_STCR2 = SSI_STCR_TXDIR;
192 SSI_STCCR2 = SSI_STRCCR_PMw(0);
193 199
194 /* Enable SSIs */ 200 /* f(INT_BIT_CLK) =
201 * f(SYS_CLK) / [(DIV2 + 1)*(7*PSR + 1)*(PM + 1)*2] =
202 * 677737600 / [(1 + 1)*(7*0 + 1)*(0 + 1)*2] =
203 * 677737600 / 4 = 169344000 Hz
204 *
205 * 45.4.2.2 DIV2, PSR, and PM Bit Description states:
206 * Bits DIV2, PSR, and PM should not be all set to zero at the same
207 * time.
208 *
209 * The hardware seems to force a divide by 4 even if all bits are
210 * zero but comply by setting DIV2 and the others to zero.
211 */
212 SSI_STCCR2 = SSI_STRCCR_DIV2 | SSI_STRCCR_PMw(1-1);
213
214 /* Enable SSI2 (codec clock) */
195 SSI_SCR2 |= SSI_SCR_SSIEN; 215 SSI_SCR2 |= SSI_SCR_SSIEN;
196 216
217 pcm_set_frequency(HW_SAMPR_DEFAULT);
197 audiohw_init(); 218 audiohw_init();
198} 219}
199 220
@@ -280,8 +301,45 @@ void pcm_play_dma_pause(bool pause)
280 hardware here but simply cache it. */ 301 hardware here but simply cache it. */
281void pcm_set_frequency(unsigned int frequency) 302void pcm_set_frequency(unsigned int frequency)
282{ 303{
283 /* TODO */ 304 int index;
284 (void)frequency; 305
306 switch (frequency)
307 {
308 case SAMPR_48:
309 index = HW_FREQ_48;
310 break;
311 case SAMPR_44:
312 index = HW_FREQ_44;
313 break;
314 case SAMPR_32:
315 index = HW_FREQ_32;
316 break;
317 case SAMPR_24:
318 index = HW_FREQ_24;
319 break;
320 case SAMPR_22:
321 index = HW_FREQ_22;
322 break;
323 case SAMPR_16:
324 index = HW_FREQ_16;
325 break;
326 case SAMPR_12:
327 index = HW_FREQ_12;
328 break;
329 case SAMPR_11:
330 index = HW_FREQ_11;
331 break;
332 case SAMPR_8:
333 index = HW_FREQ_8;
334 break;
335 default:
336 /* Invalid = default */
337 frequency = HW_SAMPR_DEFAULT;
338 index = HW_FREQ_DEFAULT;
339 }
340
341 pcm_freq = frequency;
342 sr_ctrl = index;
285} 343}
286 344
287/* Return the number of bytes waiting - full L-R sample pairs only */ 345/* Return the number of bytes waiting - full L-R sample pairs only */