2007-09-20 04:46:41 +00:00
|
|
|
/***************************************************************************
|
|
|
|
* __________ __ ___.
|
|
|
|
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
|
|
|
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
|
|
|
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
|
|
|
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
|
|
|
* \/ \/ \/ \/ \/
|
2007-09-22 15:43:38 +00:00
|
|
|
* $Id$
|
2007-09-20 04:46:41 +00:00
|
|
|
*
|
2009-03-11 01:18:23 +00:00
|
|
|
* Copyright (C) 2007 and 2009 by Karl Kurbjun
|
2007-09-20 04:46:41 +00:00
|
|
|
*
|
2008-06-28 18:10:04 +00:00
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License
|
|
|
|
* as published by the Free Software Foundation; either version 2
|
|
|
|
* of the License, or (at your option) any later version.
|
2007-09-20 04:46:41 +00:00
|
|
|
*
|
|
|
|
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
|
|
|
* KIND, either express or implied.
|
|
|
|
*
|
|
|
|
****************************************************************************/
|
2009-03-11 01:18:23 +00:00
|
|
|
#include <stdlib.h>
|
2007-09-20 04:46:41 +00:00
|
|
|
#include "system.h"
|
|
|
|
#include "kernel.h"
|
2007-09-30 16:29:21 +00:00
|
|
|
#include "logf.h"
|
|
|
|
#include "audio.h"
|
|
|
|
#include "sound.h"
|
|
|
|
#include "file.h"
|
2009-03-11 01:18:23 +00:00
|
|
|
#include "dsp-target.h"
|
|
|
|
#include "dsp/ipc.h"
|
|
|
|
#include "mmu-arm.h"
|
2007-09-20 04:46:41 +00:00
|
|
|
|
2009-03-24 16:40:31 +00:00
|
|
|
/* These are global to save some latency when pcm_play_dma_get_peak_buffer is
|
|
|
|
* called.
|
|
|
|
*/
|
2010-05-24 16:57:48 +00:00
|
|
|
static void *start;
|
|
|
|
static size_t size;
|
2009-03-24 16:40:31 +00:00
|
|
|
|
2007-10-13 14:53:34 +00:00
|
|
|
void pcm_postinit(void)
|
2007-09-30 16:29:21 +00:00
|
|
|
{
|
2010-01-03 10:35:31 +00:00
|
|
|
audiohw_postinit();
|
2007-09-30 16:29:21 +00:00
|
|
|
}
|
2007-09-22 23:17:52 +00:00
|
|
|
|
2009-03-24 16:40:31 +00:00
|
|
|
/* Return the current location in the SDRAM to SARAM transfer along with the
|
|
|
|
* number of bytes read in the current buffer (count). There is latency with
|
|
|
|
* this method equivalent to ~ the size of the SARAM buffer since there is
|
|
|
|
* another buffer between your ears and this calculation, but this works for
|
|
|
|
* key clicks and an approximate peak meter.
|
|
|
|
*/
|
2007-10-13 14:53:34 +00:00
|
|
|
const void * pcm_play_dma_get_peak_buffer(int *count)
|
2007-09-30 16:29:21 +00:00
|
|
|
{
|
2010-01-03 10:35:31 +00:00
|
|
|
int cnt = DSP_(_sdem_level);
|
2009-03-24 16:40:31 +00:00
|
|
|
|
|
|
|
unsigned long addr = (unsigned long) start +cnt;
|
|
|
|
|
|
|
|
*count = (cnt & 0xFFFFF) >> 1;
|
|
|
|
return (void *)((addr + 2) & ~3);
|
2007-09-30 16:29:21 +00:00
|
|
|
}
|
2007-09-23 23:08:39 +00:00
|
|
|
|
2007-10-13 14:53:34 +00:00
|
|
|
void pcm_play_dma_init(void)
|
2007-09-30 16:29:21 +00:00
|
|
|
{
|
2009-03-11 01:18:23 +00:00
|
|
|
IO_INTC_IRQ0 = 1 << 11;
|
|
|
|
IO_INTC_EINT0 |= 1 << 11;
|
|
|
|
|
2009-12-12 18:36:52 +00:00
|
|
|
/* Set this as a FIQ */
|
|
|
|
IO_INTC_FISEL0 |= 1 << 11;
|
|
|
|
|
2009-03-11 01:18:23 +00:00
|
|
|
IO_DSPC_HPIB_CONTROL = 1 << 10 | 1 << 9 | 1 << 8 | 1 << 7 | 1 << 3 | 1 << 0;
|
|
|
|
|
|
|
|
dsp_reset();
|
|
|
|
dsp_load(dsp_image);
|
2009-03-24 16:40:31 +00:00
|
|
|
dsp_wake();
|
2007-09-30 16:29:21 +00:00
|
|
|
}
|
|
|
|
|
2008-12-12 11:01:07 +00:00
|
|
|
void pcm_dma_apply_settings(void)
|
2007-09-30 16:29:21 +00:00
|
|
|
{
|
2010-01-03 10:35:31 +00:00
|
|
|
audiohw_set_frequency(pcm_fsel);
|
2007-10-13 14:53:34 +00:00
|
|
|
}
|
2007-09-20 04:46:41 +00:00
|
|
|
|
2009-03-24 16:40:31 +00:00
|
|
|
/* Note that size is actually limited to the size of a short right now due to
|
|
|
|
* the implementation on the DSP side (and the way that we access it)
|
|
|
|
*/
|
2007-10-13 14:53:34 +00:00
|
|
|
void pcm_play_dma_start(const void *addr, size_t size)
|
|
|
|
{
|
2010-01-03 10:35:31 +00:00
|
|
|
unsigned long sdem_addr=(unsigned long)addr - CONFIG_SDRAM_START;
|
2009-03-11 01:18:23 +00:00
|
|
|
/* Initialize codec. */
|
|
|
|
DSP_(_sdem_addrl) = sdem_addr & 0xffff;
|
|
|
|
DSP_(_sdem_addrh) = sdem_addr >> 16;
|
|
|
|
DSP_(_sdem_dsp_size) = size;
|
2009-03-24 16:40:31 +00:00
|
|
|
DSP_(_dma0_stopped)=0;
|
|
|
|
|
2009-03-11 01:18:23 +00:00
|
|
|
dsp_wake();
|
2007-09-30 16:29:21 +00:00
|
|
|
}
|
2007-09-20 04:46:41 +00:00
|
|
|
|
2007-09-30 16:29:21 +00:00
|
|
|
void pcm_play_dma_stop(void)
|
|
|
|
{
|
2009-03-24 16:40:31 +00:00
|
|
|
DSP_(_dma0_stopped)=1;
|
2009-12-02 04:30:08 +00:00
|
|
|
dsp_wake();
|
2007-09-20 04:46:41 +00:00
|
|
|
}
|
2007-09-30 16:29:21 +00:00
|
|
|
|
2007-10-13 14:53:34 +00:00
|
|
|
void pcm_play_lock(void)
|
2007-09-30 16:29:21 +00:00
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2007-10-13 14:53:34 +00:00
|
|
|
void pcm_play_unlock(void)
|
2007-09-30 16:29:21 +00:00
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2007-10-13 14:53:34 +00:00
|
|
|
void pcm_play_dma_pause(bool pause)
|
2007-09-30 16:29:21 +00:00
|
|
|
{
|
2009-03-24 16:40:31 +00:00
|
|
|
if (pause)
|
|
|
|
{
|
|
|
|
DSP_(_dma0_stopped)=2;
|
2009-12-02 04:30:08 +00:00
|
|
|
dsp_wake();
|
2009-03-24 16:40:31 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2010-01-03 10:35:31 +00:00
|
|
|
DSP_(_dma0_stopped)=0;
|
2009-03-24 16:40:31 +00:00
|
|
|
dsp_wake();
|
|
|
|
}
|
2007-09-30 16:29:21 +00:00
|
|
|
}
|
|
|
|
|
2007-10-13 14:53:34 +00:00
|
|
|
size_t pcm_get_bytes_waiting(void)
|
2007-09-30 16:29:21 +00:00
|
|
|
{
|
2009-03-11 01:18:23 +00:00
|
|
|
return DSP_(_sdem_dsp_size)-DSP_(_sdem_level);
|
|
|
|
}
|
|
|
|
|
2009-08-13 04:20:46 +00:00
|
|
|
/* Only used when debugging */
|
2010-07-31 13:41:06 +00:00
|
|
|
static char buffer[80];
|
2009-08-13 04:20:46 +00:00
|
|
|
|
|
|
|
void DSPHINT(void) __attribute__ ((section(".icode")));
|
2009-03-11 01:18:23 +00:00
|
|
|
void DSPHINT(void)
|
|
|
|
{
|
|
|
|
unsigned int i;
|
|
|
|
|
2009-12-12 18:36:52 +00:00
|
|
|
IO_INTC_FIQ0 = 1 << 11;
|
2009-03-11 01:18:23 +00:00
|
|
|
|
|
|
|
switch (dsp_message.msg)
|
|
|
|
{
|
|
|
|
case MSG_DEBUGF:
|
|
|
|
/* DSP stores one character per word. */
|
|
|
|
for (i = 0; i < sizeof(buffer); i++)
|
|
|
|
{
|
|
|
|
buffer[i] = dsp_message.payload.debugf.buffer[i];
|
|
|
|
}
|
|
|
|
|
|
|
|
DEBUGF("DSP: %s", buffer);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case MSG_REFILL:
|
2010-01-03 10:35:31 +00:00
|
|
|
/* Buffer empty. Try to get more. */
|
2010-05-24 16:42:32 +00:00
|
|
|
pcm_play_get_more_callback(&start, &size);
|
|
|
|
|
|
|
|
if (size != 0)
|
2010-01-03 10:35:31 +00:00
|
|
|
{
|
|
|
|
unsigned long sdem_addr=(unsigned long)start - CONFIG_SDRAM_START;
|
|
|
|
/* Flush any pending cache writes */
|
|
|
|
clean_dcache_range(start, size);
|
|
|
|
|
|
|
|
/* set the new DMA values */
|
|
|
|
DSP_(_sdem_addrl) = sdem_addr & 0xffff;
|
|
|
|
DSP_(_sdem_addrh) = sdem_addr >> 16;
|
|
|
|
DSP_(_sdem_dsp_size) = size;
|
|
|
|
|
|
|
|
DEBUGF("pcm_sdram at 0x%08lx, sdem_addr 0x%08lx",
|
|
|
|
(unsigned long)start, (unsigned long)sdem_addr);
|
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
2009-03-11 01:18:23 +00:00
|
|
|
default:
|
2010-01-03 10:35:31 +00:00
|
|
|
DEBUGF("DSP: unknown msg 0x%04x", dsp_message.msg);
|
|
|
|
break;
|
2009-03-11 01:18:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Re-Activate the channel */
|
|
|
|
dsp_wake();
|
|
|
|
|
|
|
|
DEBUGF("DSP: %s", buffer);
|
2007-10-13 14:53:34 +00:00
|
|
|
}
|
2009-03-11 01:18:23 +00:00
|
|
|
|