2007-09-21 15:51:53 +00:00
|
|
|
/***************************************************************************
|
|
|
|
* __________ __ ___.
|
|
|
|
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
|
|
|
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
|
|
|
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
|
|
|
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
|
|
|
* \/ \/ \/ \/ \/
|
|
|
|
* $Id$
|
|
|
|
*
|
|
|
|
* Copyright (C) 2006 by Michael Sevakis
|
|
|
|
*
|
|
|
|
* All files in this archive are subject to the GNU General Public License.
|
|
|
|
* See the file COPYING in the source tree root for full license agreement.
|
|
|
|
*
|
|
|
|
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
|
|
|
* KIND, either express or implied.
|
|
|
|
*
|
|
|
|
****************************************************************************/
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include "system.h"
|
|
|
|
#include "kernel.h"
|
|
|
|
#include "logf.h"
|
|
|
|
#include "audio.h"
|
|
|
|
#include "sound.h"
|
|
|
|
#include "file.h"
|
|
|
|
#include "mmu-imx31.h"
|
|
|
|
|
2007-10-06 22:27:27 +00:00
|
|
|
static int pcm_freq = HW_SAMPR_DEFAULT; /* 44.1 is default */
|
|
|
|
|
2007-09-21 15:51:53 +00:00
|
|
|
void fiq_handler(void) __attribute__((naked));
|
|
|
|
|
2007-10-06 22:27:27 +00:00
|
|
|
/* Implement separately on recording and playback - simply disable the
|
|
|
|
specific DMA interrupt. Disable the FIQ itself only temporarily to sync
|
|
|
|
with the DMA interrupt and restore its previous state. The pcm routines
|
|
|
|
will call the lockout first then call into these low-level routines. */
|
|
|
|
struct dma_lock
|
|
|
|
{
|
|
|
|
int locked;
|
|
|
|
unsigned long state;
|
|
|
|
};
|
|
|
|
|
|
|
|
static struct dma_play_lock =
|
|
|
|
{
|
|
|
|
.locked = 0,
|
|
|
|
.state = 0, /* Initialize this as disabled */
|
|
|
|
};
|
|
|
|
|
|
|
|
void pcm_play_lock(void)
|
|
|
|
{
|
|
|
|
int status = set_fiq_status(FIQ_DISABLED);
|
|
|
|
if (++dma_play_lock.locked == 1)
|
|
|
|
; /* Mask the DMA interrupt */
|
|
|
|
set_fiq_status(status);
|
|
|
|
}
|
|
|
|
|
|
|
|
void pcm_play_unlock(void)
|
|
|
|
{
|
|
|
|
int status = set_fiq_status(FIQ_DISABLED);
|
|
|
|
if (--dma_play_lock.locked == 0)
|
|
|
|
; /* Unmask the DMA interrupt if enabled */
|
|
|
|
set_fiq_status(status);
|
|
|
|
}
|
|
|
|
|
2007-09-21 15:51:53 +00:00
|
|
|
static void _pcm_apply_settings(void)
|
|
|
|
{
|
2007-10-06 22:27:27 +00:00
|
|
|
if (pcm_freq != pcm_curr_sampr)
|
|
|
|
{
|
|
|
|
pcm_curr_sampr = pcm_freq;
|
|
|
|
/* Change hardware sample rate */
|
|
|
|
/* */
|
|
|
|
}
|
2007-09-21 15:51:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void pcm_apply_settings(void)
|
|
|
|
{
|
2007-10-06 22:27:27 +00:00
|
|
|
/* Lockout FIQ and sync the hardware to the settings */
|
|
|
|
int oldstatus = set_fiq_status(FIQ_DISABLED);
|
|
|
|
_pcm_apply_settings();
|
|
|
|
set_fiq_status(oldstatus);
|
2007-09-21 15:51:53 +00:00
|
|
|
}
|
|
|
|
|
2007-10-06 22:27:27 +00:00
|
|
|
void pcm_play_dma_init(void)
|
2007-09-21 15:51:53 +00:00
|
|
|
{
|
2007-10-06 22:27:27 +00:00
|
|
|
pcm_set_frequency(SAMPR_44);
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
/* Do basic init enable output in pcm_postinit if popping is a
|
|
|
|
problem at boot to enable a lenghy delay and let the boot
|
|
|
|
process continue */
|
|
|
|
audiohw_init();
|
|
|
|
#endif
|
2007-09-21 15:51:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void pcm_postinit(void)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2007-10-06 22:27:27 +00:00
|
|
|
/* Connect the DMA and start filling the FIFO */
|
|
|
|
static void play_start_pcm(void)
|
2007-09-21 15:51:53 +00:00
|
|
|
{
|
2007-10-06 22:27:27 +00:00
|
|
|
#if 0
|
|
|
|
/* unmask DMA interrupt when unlocking */
|
|
|
|
dma_play_lock.state = 0; /* Set to allow pcm_play_unlock to unmask interrupt */
|
|
|
|
#endif
|
2007-09-21 15:51:53 +00:00
|
|
|
}
|
|
|
|
|
2007-10-06 22:27:27 +00:00
|
|
|
/* Disconnect the DMA and wait for the FIFO to clear */
|
|
|
|
static void play_stop_pcm(void)
|
2007-09-21 15:51:53 +00:00
|
|
|
{
|
2007-10-06 22:27:27 +00:00
|
|
|
#if 0
|
|
|
|
/* Keep interrupt masked when unlocking */
|
|
|
|
dma_play_lock.state = 0; /* Set to keep pcm_play_unlock from unmasking interrupt */
|
|
|
|
#endif
|
2007-09-21 15:51:53 +00:00
|
|
|
}
|
|
|
|
|
2007-10-06 22:27:27 +00:00
|
|
|
void pcm_play_dma_start(const void *addr, size_t size)
|
2007-09-21 15:51:53 +00:00
|
|
|
{
|
2007-10-06 22:27:27 +00:00
|
|
|
(void)addr;
|
|
|
|
(void)size;
|
2007-09-21 15:51:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void pcm_play_dma_stop(void)
|
|
|
|
{
|
2007-10-06 22:27:27 +00:00
|
|
|
play_stop_pcm();
|
2007-09-21 15:51:53 +00:00
|
|
|
}
|
|
|
|
|
2007-10-06 22:27:27 +00:00
|
|
|
void pcm_play_dma_pause(bool pause)
|
2007-09-21 15:51:53 +00:00
|
|
|
{
|
2007-10-06 22:27:27 +00:00
|
|
|
if (pause)
|
|
|
|
{
|
|
|
|
play_stop_pcm();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
play_start_pcm();
|
|
|
|
}
|
2007-09-21 15:51:53 +00:00
|
|
|
}
|
|
|
|
|
2007-10-06 22:27:27 +00:00
|
|
|
/* Get more samples to play out - call pcm_play_dma_stop and
|
|
|
|
pcm_play_dma_stopped_callback if the data runs out */
|
|
|
|
void fiq_handler(void)
|
2007-09-21 15:51:53 +00:00
|
|
|
{
|
2007-10-06 22:27:27 +00:00
|
|
|
#if 0
|
|
|
|
/* Callback missing or no more DMA to do */
|
|
|
|
pcm_play_dma_stop();
|
|
|
|
pcm_play_dma_stopped_callback();
|
|
|
|
#endif
|
2007-09-21 15:51:53 +00:00
|
|
|
}
|
|
|
|
|
2007-10-06 22:27:27 +00:00
|
|
|
/* Set the pcm frequency hardware will use when play is next started or
|
|
|
|
when pcm_apply_settings is called. Do not apply the setting to the
|
|
|
|
hardware here but simply cache it. */
|
2007-09-21 15:51:53 +00:00
|
|
|
void pcm_set_frequency(unsigned int frequency)
|
|
|
|
{
|
2007-10-06 22:27:27 +00:00
|
|
|
pcm_freq = frequency;
|
2007-09-21 15:51:53 +00:00
|
|
|
}
|
|
|
|
|
2007-10-06 22:27:27 +00:00
|
|
|
/* Return the number of bytes waiting - full L-R sample pairs only */
|
2007-09-21 15:51:53 +00:00
|
|
|
size_t pcm_get_bytes_waiting(void)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2007-10-06 22:27:27 +00:00
|
|
|
/* Return a pointer to the samples and the number of them in *count */
|
|
|
|
const void * pcm_play_dma_get_peak_buffer(int *count)
|
2007-09-21 15:51:53 +00:00
|
|
|
{
|
2007-10-06 22:27:27 +00:00
|
|
|
(void)count;
|
2007-09-21 15:51:53 +00:00
|
|
|
}
|
|
|
|
|
2007-10-06 22:27:27 +00:00
|
|
|
/* Any recording functionality should be implemented similarly */
|