1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2006 by Michael Sevakis
11 * Copyright (C) 2005 by Linus Nielsen Feltzing
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License
15 * as published by the Free Software Foundation; either version 2
16 * of the License, or (at your option) any later version.
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
21 ****************************************************************************/
28 #if defined(HAVE_SPDIF_REC) || defined(HAVE_SPDIF_OUT)
32 #define IIS_PLAY_DEFPARM ( (freq_ent[FPARM_CLOCKSEL] << 12) | \
33 (IIS_PLAY & (7 << 8)) | \
34 (4 << 2) ) /* 64 bit clocks / word clock */
35 #define IIS_FIFO_RESET (1 << 11)
36 #define PDIR2_FIFO_RESET (1 << 9)
38 #if defined(IAUDIO_X5) || defined(IAUDIO_M5) || defined(IAUDIO_M3)
39 #define IIS_PLAY IIS1CONFIG
41 #define IIS_PLAY IIS2CONFIG
45 /* EBU TX auto sync, PDIR2 fifo auto sync, IIS1 fifo auto sync */
46 #define AUDIOGLOB_DEFPARM ((1 << 10) | (1 << 8) | (1 << 7))
48 /* PDIR2 fifo auto sync, IIS1 fifo auto sync */
49 #define AUDIOGLOB_DEFPARM ((1 << 8) | (1 << 7))
53 #define PLLCR_SET_AUDIO_BITS_DEFPARM \
54 ((freq_ent[FPARM_CLSEL] << 28) | (1 << 22))
56 #define FPARM_CLOCKSEL 0
59 /* SCLK = Fs * bit clocks per word
60 * so SCLK should be Fs * 64
62 * CLOCKSEL sets SCLK freq based on Audio CLK
63 * 0x0c SCLK = Audio CLK/2 88200 * 64 = 5644800 Hz
64 * 0x06 SCLK = Audio CLK/4 44100 * 64 = 2822400 Hz
65 * 0x04 SCLK = Audio CLK/8 22050 * 64 = 1411200 Hz
66 * 0x02 SCLK = Audio CLK/16 11025 * 64 = 705600 Hz
68 * CLSEL sets MCLK1/2 DAC freq based on XTAL freq
69 * 0x01 MCLK1/2 = XTAL freq
70 * 0x02 MCLK1/2 = XTAL/2 freq
72 * Audio CLK can be XTAL freq or XTAL/2 freq (bit22 in PLLCR)
73 * we always set bit22 so Audio CLK is always XTAL freq
76 #if CONFIG_CPU == MCF5249 && defined(HAVE_UDA1380)
77 static const unsigned char pcm_freq_parms
[HW_NUM_FREQ
][2] =
79 [HW_FREQ_88
] = { 0x0c, 0x01 },
80 [HW_FREQ_44
] = { 0x06, 0x01 },
81 [HW_FREQ_22
] = { 0x04, 0x02 },
82 [HW_FREQ_11
] = { 0x02, 0x02 },
86 #if CONFIG_CPU == MCF5249 && defined(HAVE_WM8750)
87 static const unsigned char pcm_freq_parms
[HW_NUM_FREQ
][2] =
89 [HW_FREQ_88
] = { 0x0c, 0x01 },
90 [HW_FREQ_44
] = { 0x06, 0x01 },
91 [HW_FREQ_22
] = { 0x04, 0x01 },
92 [HW_FREQ_11
] = { 0x02, 0x01 },
96 #if (CONFIG_CPU == MCF5250 || CONFIG_CPU == MCF5249) && defined(HAVE_TLV320)
97 static const unsigned char pcm_freq_parms
[HW_NUM_FREQ
][2] =
99 [HW_FREQ_88
] = { 0x0c, 0x01 },
100 [HW_FREQ_44
] = { 0x06, 0x01 },
101 [HW_FREQ_22
] = { 0x04, 0x01 },
102 [HW_FREQ_11
] = { 0x02, 0x02 },
106 static const unsigned char *freq_ent
;
108 /* Lock status struct for playback and recording */
115 static void iis_play_reset(void)
117 or_l(IIS_FIFO_RESET
, &IIS_PLAY
);
118 and_l(~IIS_FIFO_RESET
, &IIS_PLAY
);
122 static bool is_playback_monitoring(void)
124 return (IIS_PLAY
& (7 << 8)) == (3 << 8);
127 static void iis_play_reset_if_playback(bool if_playback
)
129 int level
= set_irq_level(DMA_IRQ_LEVEL
);
130 if (is_playback_monitoring() == if_playback
)
135 /* apply audio settings */
136 /* This clears the reset bit to enable monitoring immediately if monitoring
137 recording sources or always if playback is in progress - we might be
138 switching samplerates on the fly */
139 void pcm_dma_apply_settings(void)
141 int level
= set_irq_level(DMA_IRQ_LEVEL
);
143 /* remember table entry */
144 freq_ent
= pcm_freq_parms
[pcm_fsel
];
146 /* Reprogramming bits 15-12 requires FIFO to be in a reset
147 condition - Users Manual 17-8, Note 11 */
148 or_l(IIS_FIFO_RESET
, &IIS_PLAY
);
149 /* Important for TLV320 - this must happen in the correct order
150 or starting recording will sound absolutely awful once in
151 awhile - audiohw_set_frequency then coldfire_set_pllcr_audio_bits
153 IIS_PLAY
= IIS_PLAY_DEFPARM
| IIS_FIFO_RESET
;
156 audiohw_set_frequency(pcm_fsel
);
157 coldfire_set_pllcr_audio_bits(PLLCR_SET_AUDIO_BITS_DEFPARM
);
159 level
= set_irq_level(DMA_IRQ_LEVEL
);
161 IIS_PLAY
= IIS_PLAY_DEFPARM
;
163 if ((DCR0
& DMA_EEXT
) != 0 && is_playback_monitoring())
164 PDOR3
= 0; /* Kick FIFO out of reset by writing to it */
167 } /* pcm_dma_apply_settings */
169 void pcm_play_dma_init(void)
171 freq_ent
= pcm_freq_parms
[pcm_fsel
];
173 AUDIOGLOB
= AUDIOGLOB_DEFPARM
;
174 DIVR0
= 54; /* DMA0 is mapped into vector 54 in system.c */
175 and_l(0xffffff00, &DMAROUTE
);
176 or_l(DMA0_REQ_AUDIO_1
, &DMAROUTE
);
177 DMACONFIG
= 1; /* DMA0Req = PDOR3, DMA1Req = PDIR2 */
178 BCR0
= 0; /* No bytes waiting */
179 ICR6
= (6 << 2); /* Enable interrupt at level 6, priority 0 */
181 /* Setup Coldfire I2S before initializing hardware or changing
183 or_l(IIS_FIFO_RESET
, &IIS_PLAY
);
184 IIS_PLAY
= IIS_PLAY_DEFPARM
| IIS_FIFO_RESET
;
185 audio_set_output_source(AUDIO_SRC_PLAYBACK
);
187 /* Initialize default register values. */
190 audio_input_mux(AUDIO_SRC_PLAYBACK
, SRCF_PLAYBACK
);
192 audiohw_set_frequency(pcm_fsel
);
193 coldfire_set_pllcr_audio_bits(PLLCR_SET_AUDIO_BITS_DEFPARM
);
195 #if defined(HAVE_SPDIF_REC) || defined(HAVE_SPDIF_OUT)
198 } /* pcm_play_dma_init */
200 void pcm_postinit(void)
208 /****************************************************************************
209 ** Playback DMA transfer
211 /* For the locks, DMA interrupt must be disabled when manipulating the lock
212 if the handler ever calls these - right now things are arranged so it
214 static struct dma_lock dma_play_lock
=
217 .state
= (0 << 14) /* bit 14 is DMA0 */
220 void pcm_play_lock(void)
222 if (++dma_play_lock
.locked
== 1)
223 or_l((1 << 14), &IMR
);
226 void pcm_play_unlock(void)
228 if (--dma_play_lock
.locked
== 0)
229 and_l(~dma_play_lock
.state
, &IMR
);
232 /* Set up the DMA transfer that kicks in when the audio FIFO gets empty */
233 void pcm_play_dma_start(const void *addr
, size_t size
)
235 /* Stop any DMA in progress */
238 /* Set up DMA transfer */
239 SAR0
= (unsigned long)addr
; /* Source address */
240 DAR0
= (unsigned long)&PDOR3
; /* Destination address */
241 BCR0
= (unsigned long)size
; /* Bytes to transfer */
243 DCR0
= DMA_INT
| DMA_EEXT
| DMA_CS
| DMA_AA
| DMA_SINC
|
244 DMA_SSIZE(DMA_SIZE_LINE
) | DMA_START
;
246 dma_play_lock
.state
= (1 << 14);
247 } /* pcm_play_dma_start */
249 /* Stops the DMA transfer and interrupt */
250 void pcm_play_dma_stop(void)
252 and_l(~(DMA_EEXT
| DMA_INT
), &DCR0
); /* per request and int OFF */
253 BCR0
= 0; /* No bytes remaining */
254 DSR0
= 1; /* Clear interrupt, errors, stop transfer */
256 iis_play_reset_if_playback(true);
258 dma_play_lock
.state
= (0 << 14);
259 } /* pcm_play_dma_stop */
261 void pcm_play_dma_pause(bool pause
)
265 /* pause playback on current buffer */
266 and_l(~(DMA_EEXT
| DMA_INT
), &DCR0
); /* per request and int OFF */
267 DSR0
= 1; /* stop channel */
268 iis_play_reset_if_playback(true);
269 dma_play_lock
.state
= (0 << 14);
273 /* restart playback on current buffer */
274 iis_play_reset_if_playback(true);
275 or_l(DMA_INT
| DMA_EEXT
| DMA_START
, &DCR0
); /* everything ON */
276 dma_play_lock
.state
= (1 << 14);
278 } /* pcm_play_dma_pause */
280 size_t pcm_get_bytes_waiting(void)
282 return BCR0
& 0xffffff;
283 } /* pcm_get_bytes_waiting */
285 /* DMA0 Interrupt is called when the DMA has finished transfering a chunk
286 from the caller's buffer */
287 void DMA0(void) __attribute__ ((interrupt_handler
, section(".icode")));
290 unsigned long res
= DSR0
;
292 and_l(~(DMA_EEXT
| DMA_INT
), &DCR0
); /* per request and int OFF */
293 DSR0
= 1; /* Clear interrupt and errors */
298 logf("DMA0 err: %02x", res
);
300 logf(" SAR0: %08x", SAR0
);
301 logf(" DAR0: %08x", DAR0
);
302 logf(" BCR0: %08x", BCR0
);
303 logf(" DCR0: %08x", DCR0
);
308 pcm_more_callback_type get_more
= pcm_callback_for_more
;
309 unsigned char *start
;
313 get_more(&start
, &size
);
315 start
= (unsigned char *)(((long)start
+ 3) & ~3);
320 SAR0
= (unsigned long)start
; /* Source address */
321 BCR0
= size
; /* Bytes to transfer */
322 or_l(DMA_EEXT
| DMA_INT
, &DCR0
); /* per request and int ON */
325 /* Finished playing */
328 /* Stop interrupt and futher transfers */
330 /* Inform PCM that we're done */
331 pcm_play_dma_stopped_callback();
334 const void * pcm_play_dma_get_peak_buffer(int *count
)
336 unsigned long addr
, cnt
;
338 /* Make sure interrupt doesn't change the second value after we read the
340 int level
= set_irq_level(DMA_IRQ_LEVEL
);
345 *count
= (cnt
& 0xffffff) >> 2;
346 return (void *)((addr
+ 2) & ~3);
347 } /* pcm_play_dma_get_peak_buffer */
349 #ifdef HAVE_RECORDING
350 /****************************************************************************
351 ** Recording DMA transfer
353 static struct dma_lock dma_rec_lock
=
356 .state
= (0 << 15) /* bit 15 is DMA1 */
359 /* For the locks, DMA interrupt must be disabled when manipulating the lock
360 if the handler ever calls these - right now things are arranged so it
362 void pcm_rec_lock(void)
364 if (++dma_rec_lock
.locked
== 1)
365 or_l((1 << 15), &IMR
);
368 void pcm_rec_unlock(void)
370 if (--dma_rec_lock
.locked
== 0)
371 and_l(~dma_rec_lock
.state
, &IMR
);
374 void pcm_rec_dma_start(void *addr
, size_t size
)
376 /* stop any DMA in progress */
379 and_l(~PDIR2_FIFO_RESET
, &DATAINCONTROL
);
381 /* Start the DMA transfer.. */
382 #ifdef HAVE_SPDIF_REC
383 /* clear: ebu1cnew, valnogood, symbolerr, parityerr */
384 INTERRUPTCLEAR
= (1 << 25) | (1 << 24) | (1 << 23) | (1 << 22);
387 SAR1
= (unsigned long)&PDIR2
; /* Source address */
388 DAR1
= (unsigned long)addr
; /* Destination address */
389 BCR1
= (unsigned long)size
; /* Bytes to transfer */
391 DCR1
= DMA_INT
| DMA_EEXT
| DMA_CS
| DMA_AA
| DMA_DINC
|
392 DMA_DSIZE(DMA_SIZE_LINE
) | DMA_START
;
394 dma_rec_lock
.state
= (1 << 15);
395 } /* pcm_rec_dma_start */
397 void pcm_rec_dma_stop(void)
399 and_l(~(DMA_EEXT
| DMA_INT
), &DCR1
); /* per request and int OFF */
400 DSR1
= 1; /* Clear interrupt, errors, stop transfer */
401 BCR1
= 0; /* No bytes received */
403 or_l(PDIR2_FIFO_RESET
, &DATAINCONTROL
);
405 iis_play_reset_if_playback(false);
407 dma_rec_lock
.state
= (0 << 15);
408 } /* pcm_rec_dma_stop */
410 void pcm_rec_dma_init(void)
412 DIVR1
= 55; /* DMA1 is mapped into vector 55 in system.c */
413 DMACONFIG
= 1; /* DMA0Req = PDOR3, DMA1Req = PDIR2 */
414 and_l(0xffff00ff, &DMAROUTE
);
415 or_l(DMA1_REQ_AUDIO_2
, &DMAROUTE
);
419 /* Enable interrupt at level 6, priority 1 */
420 ICR7
= (6 << 2) | (1 << 0);
421 } /* pcm_init_recording */
423 void pcm_rec_dma_close(void)
427 and_l(0xffff00ff, &DMAROUTE
);
428 ICR7
= 0x00; /* Disable interrupt */
429 dma_rec_lock
.state
= (0 << 15);
430 } /* pcm_rec_dma_close */
432 /* DMA1 Interrupt is called when the DMA has finished transfering a chunk
433 into the caller's buffer */
434 void DMA1(void) __attribute__ ((interrupt_handler
, section(".icode")));
437 unsigned long res
= DSR1
;
439 pcm_more_callback_type2 more_ready
;
441 and_l(~(DMA_EEXT
| DMA_INT
), &DCR1
); /* per request and int OFF */
442 DSR1
= 1; /* Clear interrupt and errors */
446 status
= DMA_REC_ERROR_DMA
;
447 logf("DMA1 err: %02x", res
);
449 logf(" SAR1: %08x", SAR1
);
450 logf(" DAR1: %08x", DAR1
);
451 logf(" BCR1: %08x", BCR1
);
452 logf(" DCR1: %08x", DCR1
);
455 #ifdef HAVE_SPDIF_REC
456 else if (DATAINCONTROL
== 0xc038 &&
457 (INTERRUPTSTAT
& ((1 << 23) | (1 << 22))))
459 /* reason: symbolerr, parityerr.
460 * Ignore valnogood since several sources don't set it properly. */
461 /* clear: ebu1cnew, symbolerr, parityerr */
462 INTERRUPTCLEAR
= (1 << 25) | (1 << 23) | (1 << 22);
463 status
= DMA_REC_ERROR_SPDIF
;
468 more_ready
= pcm_callback_more_ready
;
470 if (more_ready
!= NULL
&& more_ready(status
) >= 0)
473 /* Finished recording */
475 /* Inform PCM that we're done */
476 pcm_rec_dma_stopped_callback();
479 /* Continue transferring data in - call from interrupt callback */
480 void pcm_rec_dma_record_more(void *start
, size_t size
)
482 DAR1
= (unsigned long)start
; /* Destination address */
483 BCR1
= (unsigned long)size
; /* Bytes to transfer */
484 or_l(DMA_EEXT
| DMA_INT
, &DCR1
); /* per request and int ON */
485 } /* pcm_record_more */
487 const void * pcm_rec_dma_get_peak_buffer(void)
489 return (void *)(DAR1
& ~3);
490 } /* pcm_rec_dma_get_peak_buffer */