bool pcm_rec_dma_complete_callback(enum pcm_dma_status status, void **addr, size_t *size) { /* Check status callback first if error */ if (status < PCM_DMAST_OK) status = pcm_rec_dma_status_callback(status); pcm_rec_callback_type have_more = pcm_callback_more_ready; if (have_more && status >= PCM_DMAST_OK) { /* Call registered callback to obtain next buffer */ have_more(addr, size); ALIGN_AUDIOBUF(*addr, *size); if (*addr && *size) { /* Need a physical DMA address translation, if not already * physical. */ pcm_rec_peak_addr = pcm_rec_dma_addr(*addr); return true; } } /* Error, callback missing or no more DMA to do */ pcm_rec_dma_stop(); pcm_recording_stopped(); return false; }
void pcm_rec_dma_close(void) { pcm_rec_dma_stop(); and_l(0xffff00ff, &DMAROUTE); ICR7 = 0x00; /* Disable interrupt */ dma_rec_lock.state = (0 << 15); } /* pcm_rec_dma_close */
void pcm_rec_dma_init(void) { DIVR1 = 55; /* DMA1 is mapped into vector 55 in system.c */ DMACONFIG = 1; /* DMA0Req = PDOR3, DMA1Req = PDIR2 */ and_l(0xffff00ff, &DMAROUTE); or_l(DMA1_REQ_AUDIO_2, &DMAROUTE); pcm_rec_dma_stop(); /* Enable interrupt at level 6, priority 1 */ ICR7 = (6 << 2) | (1 << 0); } /* pcm_init_recording */
void pcm_stop_recording(void) { logf("pcm_stop_recording"); pcm_rec_lock(); if (pcm_recording) { logf(" pcm_rec_dma_stop"); pcm_rec_dma_stop(); pcm_recording_stopped(); } pcm_rec_unlock(); } /* pcm_stop_recording */
void pcm_close_recording(void) { logf("pcm_close_recording"); pcm_rec_lock(); if (pcm_recording) { logf(" pcm_rec_dma_stop"); pcm_rec_dma_stop(); pcm_recording_stopped(); } logf(" pcm_rec_dma_close"); pcm_rec_dma_close(); pcm_rec_unlock(); }
void pcm_rec_dma_start(void *addr, size_t size) { /* stop any DMA in progress */ pcm_rec_dma_stop(); and_l(~PDIR2_FIFO_RESET, &DATAINCONTROL); /* Start the DMA transfer.. */ #ifdef HAVE_SPDIF_REC /* clear: ebu1cnew, valnogood, symbolerr, parityerr */ INTERRUPTCLEAR = (1 << 25) | (1 << 24) | (1 << 23) | (1 << 22); #endif SAR1 = (unsigned long)&PDIR2; /* Source address */ DAR1 = (unsigned long)addr; /* Destination address */ BCR1 = (unsigned long)size; /* Bytes to transfer */ DCR1 = DMA_INT | DMA_EEXT | DMA_CS | DMA_AA | DMA_DINC | DMA_DSIZE(DMA_SIZE_LINE) | DMA_START; dma_rec_lock.state = (0 << 15); } /* pcm_rec_dma_start */
void pcm_rec_dma_close(void) { bitset32(&CGU_PERI, CGU_I2SIN_APB_CLOCK_ENABLE); pcm_rec_dma_stop(); }