summaryrefslogtreecommitdiffstats
path: root/firmware
diff options
context:
space:
mode:
authorChristian Gmeiner <christian.gmeiner@gmail.com>2005-08-06 10:12:19 +0000
committerChristian Gmeiner <christian.gmeiner@gmail.com>2005-08-06 10:12:19 +0000
commit14e80671afca494b26354753c8fddc3c3a787d4c (patch)
tree68fa16731953a3bff3fcb531dc0ef61cddad6f89 /firmware
parent095854b98925f5b01643b78f664dc4e6eace72be (diff)
downloadrockbox-14e80671afca494b26354753c8fddc3c3a787d4c.tar.gz
rockbox-14e80671afca494b26354753c8fddc3c3a787d4c.zip
iAudio: First unfinished attempt for tlv320 driver and rockbox integration
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@7286 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware')
-rw-r--r--firmware/SOURCES4
-rw-r--r--firmware/drivers/tlv320.c223
-rw-r--r--firmware/export/tlv320.h19
-rw-r--r--firmware/pcm_playback.c56
-rw-r--r--firmware/pcm_record.c194
-rw-r--r--firmware/powermgmt.c6
-rw-r--r--firmware/sound.c2
7 files changed, 391 insertions, 113 deletions
diff --git a/firmware/SOURCES b/firmware/SOURCES
index 937bb0bfb6..be471fb51b 100644
--- a/firmware/SOURCES
+++ b/firmware/SOURCES
@@ -126,6 +126,8 @@ drivers/lcd-h100-remote.c
#endif
#if defined(HAVE_UDA1380) && !defined(SIMULATOR)
drivers/uda1380.c
+#elif defined(HAVE_TLV320) && !defined(SIMULATOR)
+drivers/tlv320.c
#endif
#if (CONFIG_HWCODEC == MASNONE) && !defined(SIMULATOR)
pcm_playback.c
@@ -133,7 +135,7 @@ pcm_playback.c
#if CONFIG_HWCODEC == MASNONE
replaygain.c
#endif
-#if defined(HAVE_UDA1380) && !defined(SIMULATOR)
+#if defined(CPU_COLDFIRE) && !defined(SIMULATOR)
pcm_record.c
#endif
sound.c
diff --git a/firmware/drivers/tlv320.c b/firmware/drivers/tlv320.c
new file mode 100644
index 0000000000..bafd77cd39
--- /dev/null
+++ b/firmware/drivers/tlv320.c
@@ -0,0 +1,223 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2005 by Christian Gmeiner
+ *
+ * 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 "lcd.h"
+#include "cpu.h"
+#include "kernel.h"
+#include "thread.h"
+#include "power.h"
+#include "debug.h"
+#include "system.h"
+#include "sprintf.h"
+#include "button.h"
+#include "string.h"
+#include "file.h"
+#include "buffer.h"
+
+#include "i2c-coldfire.h"
+#include "tlv320.h"
+
+/* local functions and definations */
+#define TLV320_ADDR 0x34
+
+struct tlv320_info
+{
+ int vol_l;
+ int vol_r;
+} tlv320;
+
+/* Definition of a playback configuration to start with */
+#define NUM_DEFAULT_REGS 10
+unsigned tlv320_defaults[2*NUM_DEFAULT_REGS] =
+{
+ REG_PC, PC_ON | PC_OSC | PC_CLK | PC_DAC | ~PC_OUT, /* do we need to enable osciliator and clock? */
+ REG_LLIV, LLIV_LIM, /* mute adc input */
+ REG_RLIV, RLIV_RIM, /* mute adc input */
+ REG_LHV, LHV_LHV(HEADPHONE_MUTE), /* mute headphone */
+ REG_RHV, RHV_RHV(HEADPHONE_MUTE), /* mute headphone */
+ REG_AAP, AAP_MICM, /* mute microphone */
+ REG_DAP, DAP_DEEMP_DIS, /* de-emphasis control: disabled */
+ REG_DAIF, DAIF_FOR_I2S | DAIF_IWL_24 | ~DAIF_MS, /* i2s with 24 bit data len and slave mode */
+ REG_SRC, 0, /* ToDo */
+ REG_DIA, DIA_ACT, /* activate digital interface */
+};
+unsigned tlv320_regs[0xf];
+
+void tlv320_write_reg(unsigned reg, unsigned value)
+{
+ unsigned data[3];
+
+ data[0] = TLV320_ADDR;
+ data[1] = reg << 1;
+ data[2] = value & 0xff;
+
+ if (i2c_write(1, data, 3) != 3)
+ {
+ DEBUGF("tlv320 error reg=0x%x", reg);
+ return;
+ }
+
+ tlv320_regs[reg] = value;
+}
+
+/* Returns 0 if successful or -1 if some register failed */
+void tlv320_set_regs()
+{
+ int i;
+ memset(tlv320_regs, 0, sizeof(tlv320_regs));
+
+ /* Initialize all registers */
+ for (i=0; i<NUM_DEFAULT_REGS; i++)
+ {
+ unsigned reg = tlv320_defaults[i*2+0];
+ unsigned value = tlv320_defaults[i*2+1];
+
+ tlv320_write_reg(reg, value);
+ }
+}
+
+/* public functions */
+
+/**
+ * Init our tlv with default values
+ */
+void tlv320_init()
+{
+ tlv320_reset();
+ tlv320_set_regs();
+}
+
+/**
+ * Resets tlv320 to default values
+ */
+void tlv320_reset()
+{
+ tlv320_write_reg(REG_RR, RR_RESET):
+}
+
+void tlv320_enable_output(bool enable)
+{
+ unsigned value = tlv320regs[REG_PC];
+
+ if (enable)
+ value |= PC_OUT;
+ else
+ value &= ~PC_OUT;
+
+ tlv320_write_reg(REG_PC, value);
+}
+
+/**
+ * Sets left and right headphone volume (127(max) to 48(muted))
+ */
+void tlv320_set_headphone_vol(int vol_l, int vol_r)
+{
+ unsigned value_l = tlv320_regs[REG_LHV];
+ unsigned value_r = tlv320_regs[REG_RHV];
+
+ /* keep track of current setting */
+ tlv320.vol_l = vol_l;
+ tlv320.vol_r = vol_r;
+
+ /* set new values in local register holders */
+ value_l |= LHV_LHV(vol_l);
+ value_r |= LHV_LHV(vol_r);
+
+ /* update */
+ tlv320_write_reg(REG_LHV, value_l);
+ tlv320_write_reg(REG_RHV, value_r);
+}
+
+/**
+ * Sets left and right linein volume (31(max) to 0(muted))
+ */
+void tlv320_set_linein_vol(int vol_l, int vol_r)
+{
+ unsigned value_l = tlv320regs[REG_LLIV];
+ unsigned value_r = tlv320regs[REG_RLIV];
+
+ value_l |= LLIV_LHV(vol_l);
+ value_r |= RLIV_RHV(vol_r);
+
+ tlv320_write_reg(REG_LLIV, value_l);
+ tlv320_write_reg(REG_RLIV, value_r);
+}
+
+/**
+ * Mute (mute=true) or enable sound (mute=false)
+ *
+ */
+void tlv320_mute(bool mute)
+{
+ unsigned value_l = tlv320regs[REG_LHV];
+ unsigned value_r = tlv320regs[REG_RHV];
+
+ if (mute)
+ {
+ value_l |= LHV_LHV(HEADPHONE_MUTE);
+ value_r |= RHV_RHV(HEADPHONE_MUTE);
+ }
+ else
+ {
+ value_l |= LHV_LHV(tlv320.vol_l);
+ value_r |= RHV_RHV(tlv320.vol_r);
+ }
+
+ tlv320_write_reg(REG_LHV, value_r);
+ tlv320_write_reg(REG_RHV, value_r);
+}
+
+void tlv320_close()
+{
+ /* todo */
+}
+
+void tlv320_enable_recording(bool source_mic)
+{
+ unsigned value_pc = tlv320regs[REG_PC];
+ unsigned value_aap = tlv320regs[REG_AAP];
+
+ /* select source*/
+ if (source_mic)
+ {
+ value_aap &= ~AAP_INSEL;
+ value_pc |= PC_MIC;
+ }
+ else
+ {
+ value_aap |= AAP_INSEL;
+ value_pc |= PC_LINE;
+ }
+
+ /* poweron adc */
+ value_pc |= PC_ADC;
+
+ tlv320_write_reg(REG_AAP, value_aap);
+ tlv320_write_reg(REG_PC, value_pc);
+}
+
+void tlv320_disable_recording()
+{
+ unsigned value = tlv320regs[REG_PC];
+
+ /* powerdown mic, linein and adc */
+ value &= ~(PC_MIC | PC_LINE | PC_ADC);
+
+ /* powerdown mic, linein and adc */
+ tlv320_write_reg(REG_PC, value);
+} \ No newline at end of file
diff --git a/firmware/export/tlv320.h b/firmware/export/tlv320.h
index 0e50e4f6d1..70ba56e3e2 100644
--- a/firmware/export/tlv320.h
+++ b/firmware/export/tlv320.h
@@ -22,10 +22,15 @@
/*** definitions ***/
-extern void tlv320_reset(void);
-extern int tlv320_init(void);
-extern int tlv320_set_headphone_vol(int vol_l, int vol_r);
-extern int tlv320_mute(bool mute);
+extern void tlv320_init();
+extern void tlv320_reset();
+extern void tlv320_enable_output(bool enable);
+extern void tlv320_set_headphone_vol(int vol_l, int vol_r);
+extern void tlv320_set_linein_vol(int vol_l, int vol_r);
+extern void tlv320_mute(bool mute);
+extern void tlv320_close();
+extern void tlv320_enable_recording(bool source_mic);
+extern void tlv320_disable_recording();
#define HEADPHONE_MUTE 0x30 /* 0110000 = -73db */
@@ -35,8 +40,8 @@ extern int tlv320_mute(bool mute);
/* REG_LLIV: Left line input channel volume control */
#define REG_LLIV 0x0
#define LLIV_LRS (0 << 8) /* simultaneous volume/mute update */
-#define LIM (1 << 7) /* Left line input mute */
-#define LIV ((x) & 0x1f)/* Left line input volume control */
+#define LLIV_LIM (1 << 7) /* Left line input mute */
+#define LLIV_LIV ((x) & 0x1f)/* Left line input volume control */
/* REG_RLIV: Right line input channel volume control */
#define REG_RLIV 0x1
@@ -75,7 +80,7 @@ extern int tlv320_mute(bool mute);
/* REG_PC: Power Down Control */
#define REG_PC 0x6
-#define PC_OFF (0 << 7) /* Device power */
+#define PC_ON (0 << 7) /* Device power */
#define PC_CLK (0 << 6) /* Clock */
#define PC_OSC (0 << 5) /* Oscillator */
#define PC_OUT (0 << 4) /* Outputs */
diff --git a/firmware/pcm_playback.c b/firmware/pcm_playback.c
index 17350edfb5..c79902845a 100644
--- a/firmware/pcm_playback.c
+++ b/firmware/pcm_playback.c
@@ -24,7 +24,11 @@
#ifndef SIMULATOR
#include "cpu.h"
#include "i2c.h"
+#if defined(HAVE_UDA1380)
#include "uda1380.h"
+#elif defined(HAVE_TLV320)
+#include "tlv320.h"
+#endif
#include "system.h"
#endif
#include "logf.h"
@@ -181,13 +185,18 @@ void pcm_play_data(void (*get_more)(unsigned char** start, long* size))
{
unsigned char *start;
long size;
-
+
callback_for_more = get_more;
-
+
get_more((unsigned char **)&start, (long *)&size);
get_more(&next_start, &next_size);
dma_start(start, size);
+
+#if defined(HAVE_UDA1380)
uda1380_mute(false);
+#elif defined(HAVE_TLV320)
+ tlv320_mute(false);
+#endif
}
long pcm_get_bytes_waiting(void)
@@ -198,7 +207,12 @@ long pcm_get_bytes_waiting(void)
void pcm_play_stop(void)
{
if (pcm_playing) {
+
+#if defined(HAVE_UDA1380)
uda1380_mute(true);
+#elif defined(HAVE_TLV320)
+ tlv320_mute(true);
+#endif
dma_stop();
}
}
@@ -216,14 +230,23 @@ void pcm_play_pause(bool play)
IIS2CONFIG = (pcm_freq << 12) | 0x300 | 4 << 2;
EBU1CONFIG = (7 << 12) | (3 << 8) | (1 << 5) | (5 << 2);
DCR0 |= DMA_EEXT | DMA_START;
-
+
+#if defined(HAVE_UDA1380)
uda1380_mute(false);
+#elif defined(HAVE_TLV320)
+ tlv320_mute(false);
+#endif
}
else if(!pcm_paused && !play)
{
logf("pause");
+
+#if defined(HAVE_UDA1380)
uda1380_mute(true);
-
+#elif defined(HAVE_TLV320)
+ tlv320_mute(true);
+#endif
+
/* Disable DMA peripheral request. */
DCR0 &= ~DMA_EEXT;
IIS2CONFIG = 0x800;
@@ -250,7 +273,7 @@ void DMA0(void)
DSR0 = 1; /* Clear interrupt */
DCR0 &= ~DMA_EEXT;
-
+
/* Stop on error */
if(res & 0x70)
{
@@ -274,7 +297,7 @@ void DMA0(void)
logf("DMA No Data:0x%04x", res);
}
}
-
+
IPR |= (1<<14); /* Clear pending interrupt request */
}
@@ -282,8 +305,12 @@ void pcm_init(void)
{
pcm_playing = false;
pcm_paused = false;
-
+
+#if defined(HAVE_UDA1380)
uda1380_init();
+#elif defined(HAVE_TLV320)
+ tlv320_init();
+#endif
BUSMASTER_CTRL = 0x81; /* PARK[1,0]=10 + BCR24BIT */
DIVR0 = 54; /* DMA0 is mapped into vector 54 in system.c */
@@ -292,18 +319,25 @@ void pcm_init(void)
/* Reset the audio FIFO */
IIS2CONFIG = 0x800;
-
+
/* Enable interrupt at level 7, priority 0 */
ICR4 = (ICR4 & 0xffff00ff) | 0x00001c00;
IMR &= ~(1<<14); /* bit 14 is DMA0 */
-
+
pcm_set_frequency(44100);
-
+
/* Turn on headphone power with audio output muted. */
+#if defined(HAVE_UDA1380)
uda1380_mute(true);
+#elif defined(HAVE_TLV320)
+ tlv320_mute(true);
+#endif
sleep(HZ/4);
+#if defined(HAVE_UDA1380)
uda1380_enable_output(true);
-
+#elif defined(HAVE_TLV320)
+ tlv320_enable_output(true);
+#endif
/* Call dma_stop to initialize everything. */
dma_stop();
}
diff --git a/firmware/pcm_record.c b/firmware/pcm_record.c
index 7ecd1d1bbb..3101a16e02 100644
--- a/firmware/pcm_record.c
+++ b/firmware/pcm_record.c
@@ -30,7 +30,11 @@
#include "cpu.h"
#include "i2c.h"
+#if defined(HAVE_UDA1380)
#include "uda1380.h"
+#elif defined(HAVE_TLV320)
+#include "tlv320.h"
+#endif
#include "system.h"
#include "usb.h"
@@ -61,7 +65,7 @@ static unsigned long record_start_time; /* Value of current_tick when re
static unsigned long pause_start_time; /* Value of current_tick when pause was started */
static int rec_gain, rec_volume;
-static bool show_waveform;
+static bool show_waveform;
static int init_done = 0;
static int wav_file;
static char recording_filename[MAX_PATH];
@@ -72,12 +76,12 @@ static char recording_filename[MAX_PATH];
Some estimates:
44100 HZ * 4 = 176400 bytes/s
Refresh LCD 10 HZ = 176400 / 10 = 17640 bytes ~=~ 1024*16 bytes
-
+
If NUM_BUFFERS is 80 we can hold ~8 sec of data in memory
ALL_BUFFER_SIZE will be 1024*16 * 80 = 1310720 bytes
*/
-#define NUM_BUFFERS 80
+#define NUM_BUFFERS 80
#define EACH_BUFFER_SIZE (1024*16) /* Multiple of 4. Use small value to get responsive waveform */
#define ALL_BUFFERS_SIZE (NUM_BUFFERS * EACH_BUFFER_SIZE)
@@ -130,7 +134,7 @@ void pcm_init_recording(void)
wav_file = -1;
read_index = 0;
write_index = 0;
-
+
queue_init(&pcmrec_queue);
create_thread(pcmrec_thread, pcmrec_stack, sizeof(pcmrec_stack), pcmrec_thread_name);
}
@@ -138,16 +142,16 @@ void pcm_init_recording(void)
void pcm_open_recording(void)
{
init_done = 0;
-
+
logf("pcm_open_rec");
-
+
queue_post(&pcmrec_queue, PCMREC_OPEN, 0);
-
+
while (init_done)
{
sleep(HZ >> 8);
}
-
+
logf("pcm_open_rec done");
}
@@ -162,10 +166,10 @@ void pcm_close_recording(void)
unsigned long pcm_status(void)
{
unsigned long ret = 0;
-
+
if (is_recording)
ret |= AUDIO_STATUS_RECORD;
-
+
return ret;
}
@@ -193,7 +197,7 @@ unsigned long pcm_recorded_time(void)
unsigned long pcm_num_recorded_bytes(void)
{
-
+
if (is_recording)
{
return num_rec_bytes;
@@ -222,10 +226,12 @@ void pcm_resume_recording(void)
*/
void pcm_set_recording_options(int source, bool enable_waveform)
{
+#if defined(HAVE_UDA1380)
uda1380_enable_recording(source);
-
+#elif defined(HAVE_TLV320)
+ tlv320_enable_recording(source);
+#endif
show_waveform = enable_waveform;
-
}
@@ -238,21 +244,20 @@ void pcm_set_recording_gain(int gain, int volume)
{
rec_gain = gain;
rec_volume = volume;
-
+
queue_post(&pcmrec_queue, PCMREC_SET_GAIN, 0);
-
}
-
+
/**
* Start recording
*
* Use pcm_set_recording_options before calling record
- */
+ */
void pcm_record(const char *filename)
{
strncpy(recording_filename, filename, MAX_PATH - 1);
recording_filename[MAX_PATH - 1] = 0;
-
+
queue_post(&pcmrec_queue, PCMREC_START, 0);
}
@@ -263,19 +268,17 @@ void pcm_stop_recording(void)
{
if (is_recording)
is_stopping = 1;
-
+
queue_post(&pcmrec_queue, PCMREC_STOP, 0);
logf("pcm_stop_recording");
-
+
while (is_stopping)
{
sleep(HZ >> 4);
}
-
+
logf("pcm_stop_recording done");
-
-
}
@@ -303,40 +306,40 @@ void pcmrec_callback(bool flush)
num_ready += NUM_BUFFERS;
/* we can consume up to num_ready buffers */
-
-#ifdef HAVE_REMOTE_LCD
+
+#ifdef HAVE_REMOTE_LCD
/* Draw waveform on remote LCD */
- if (show_waveform && num_ready>0)
+ if (show_waveform && num_ready>0)
{
short *buf;
long x,y,offset;
int show_index;
/* Just display the last buffer (most recent one) */
- show_index = read_index + num_ready - 1;
+ show_index = read_index + num_ready - 1;
buf = (short*)rec_buffers[show_index];
-
+
lcd_remote_clear_display();
-
+
offset = 0;
for (x=0; x<LCD_REMOTE_WIDTH-1; x++)
{
y = buf[offset] * (LCD_REMOTE_HEIGHT / 2) *5; /* The 5 is just 'zooming' */
y = y >> 15; /* Divide with SHRT_MAX */
y += LCD_REMOTE_HEIGHT/2;
-
+
if (y < 2) y=2;
if (y >= LCD_REMOTE_HEIGHT-2) y = LCD_REMOTE_HEIGHT-2;
-
+
lcd_remote_drawpixel(x,y);
-
+
offset += (EACH_BUFFER_SIZE/2) / LCD_REMOTE_WIDTH;
}
-
- lcd_remote_update();
+
+ lcd_remote_update();
}
-
-#endif
+
+#endif
/* Note: This might be a good place to call the 'codec' later */
@@ -348,43 +351,41 @@ void pcmrec_callback(bool flush)
{
unsigned long *ptr = (unsigned long*)rec_buffers[read_index];
int i;
-
+
for (i=0; i<EACH_BUFFER_SIZE * num_ready / 4; i++)
{
*ptr = SWAB32(*ptr);
ptr++;
}
-
+
write(wav_file, rec_buffers[read_index], EACH_BUFFER_SIZE * num_ready);
-
+
read_index+=num_ready;
if (read_index >= NUM_BUFFERS)
read_index -= NUM_BUFFERS;
}
-
+
} else
{
/* In this case we must consume the buffers otherwise we will */
/* get 'dma1 overrun' pretty fast */
-
+
read_index+=num_ready;
if (read_index >= NUM_BUFFERS)
read_index -= NUM_BUFFERS;
}
}
-
-
void pcmrec_dma_start(void)
{
DAR1 = (unsigned long)rec_buffers[write_index++]; /* Destination address */
SAR1 = (unsigned long)&PDIR2; /* Source address */
BCR1 = EACH_BUFFER_SIZE; /* Bytes to transfer */
-
+
/* Start the DMA transfer.. */
- DCR1 = DMA_INT | DMA_EEXT | DMA_CS | DMA_DINC | DMA_START;
-
+ DCR1 = DMA_INT | DMA_EEXT | DMA_CS | DMA_DINC | DMA_START;
+
logf("dma1 started");
}
@@ -396,7 +397,7 @@ void DMA1(void)
int res = DSR1;
DSR1 = 1; /* Clear interrupt */
-
+
int_count++;
if (res & 0x70)
@@ -404,41 +405,41 @@ void DMA1(void)
DCR1 = 0; /* Stop DMA transfer */
error_count++;
is_recording = 0;
-
+
logf("dma1 err 0x%x", res);
-
+
} else
{
num_rec_bytes += EACH_BUFFER_SIZE;
-
+
write_index++;
if (write_index >= NUM_BUFFERS)
write_index = 0;
-
+
if (is_stopping || !is_recording)
{
DCR1 = 0; /* Stop DMA transfer */
is_recording = 0;
-
+
logf("dma1 stopping");
-
+
} else if (write_index == read_index)
{
DCR1 = 0; /* Stop DMA transfer */
is_recording = 0;
-
+
logf("dma1 overrun");
-
+
} else
{
DAR1 = (unsigned long)rec_buffers[write_index]; /* Destination address */
BCR1 = EACH_BUFFER_SIZE;
queue_post(&pcmrec_queue, PCMREC_GOT_DATA, NULL);
-
+
}
}
-
+
IPR |= (1<<15); /* Clear pending interrupt request */
}
@@ -450,7 +451,7 @@ static int start_wave(void)
0x10,0,0,0,1,0,2,0,0x44,0xac,0,0,0x10,0xb1,2,0,
4,0,0x10,0,'d','a','t','a',0,0,0,0
};
-
+
wav_file = open(recording_filename, O_RDWR|O_CREAT|O_TRUNC);
if (wav_file < 0)
{
@@ -458,7 +459,7 @@ static int start_wave(void)
logf("create failed: %d", wav_file);
return -1;
}
-
+
if (sizeof(header) != write(wav_file, header, sizeof(header)))
{
close(wav_file);
@@ -466,7 +467,7 @@ static int start_wave(void)
logf("write failed");
return -2;
}
-
+
return 0;
}
@@ -474,15 +475,15 @@ static int start_wave(void)
static void close_wave(void)
{
long l;
-
+
l = SWAB32(num_rec_bytes + 36);
lseek(wav_file, 4, SEEK_SET);
write(wav_file, &l, 4);
-
+
l = SWAB32(num_rec_bytes);
lseek(wav_file, 40, SEEK_SET);
write(wav_file, &l, 4);
-
+
close(wav_file);
wav_file = -1;
}
@@ -490,19 +491,19 @@ static void close_wave(void)
static void pcmrec_start(void)
{
logf("pcmrec_start");
-
+
if (is_recording)
return;
-
+
if (wav_file != -1)
close(wav_file);
-
+
logf("rec: %s", recording_filename);
-
+
start_wave(); /* todo: send signal to pcm_record if we have failed */
num_rec_bytes = 0;
-
+
/* Store the current time */
record_start_time = current_tick;
@@ -514,29 +515,29 @@ static void pcmrec_start(void)
is_recording = 1;
pcmrec_dma_start();
-
+
}
static void pcmrec_stop(void)
{
/* wait for recording to finish */
-
+
/* todo: Abort current DMA transfer using DCR1.. */
-
+
logf("pcmrec_stop");
-
+
while (is_recording)
{
sleep(HZ >> 4);
}
-
+
logf("pcmrec_stop done");
/* Write unfinished buffers to file */
- pcmrec_callback(true);
+ pcmrec_callback(true);
close_wave();
-
+
is_stopping = 0;
}
@@ -544,7 +545,7 @@ static void pcmrec_open(void)
{
unsigned long buffer_start;
int i;
-
+
show_waveform = 0;
is_recording = 0;
is_stopping = 0;
@@ -555,7 +556,7 @@ static void pcmrec_open(void)
buffer_start = (unsigned long)(&audiobuf[(audiobufend - audiobuf) - (ALL_BUFFERS_SIZE + 16)]);
buffer_start &= ~3;
-
+
for (i=0; i<NUM_BUFFERS; i++)
{
rec_buffers[i] = (unsigned char*)(buffer_start + EACH_BUFFER_SIZE * i);
@@ -572,61 +573,69 @@ static void pcmrec_open(void)
ICR4 = (ICR4 & 0xffffff00) | 0x0000001c; /* Enable interrupt at level 7, priority 0 */
IMR &= ~(1<<15); /* bit 15 is DMA1 */
- init_done = 1;
+ init_done = 1;
}
static void pcmrec_close(void)
{
+#if defined(HAVE_UDA1380)
uda1380_disable_recording();
+#elif defined(HAVE_TLV320)
+ tlv320_disable_recording();
+#endif
DMAROUTE = (DMAROUTE & 0xffff00ff);
ICR4 = (ICR4 & 0xffffff00); /* Disable interrupt */
- IMR |= (1<<15); /* bit 15 is DMA1 */
+ IMR |= (1<<15); /* bit 15 is DMA1 */
}
static void pcmrec_thread(void)
{
struct event ev;
-
+
logf("thread pcmrec start");
-
+
while (1)
{
queue_wait(&pcmrec_queue, &ev);
-
+
switch (ev.id)
{
case PCMREC_OPEN:
pcmrec_open();
break;
-
+
case PCMREC_CLOSE:
pcmrec_close();
- break;
-
+ break;
+
case PCMREC_START:
pcmrec_start();
break;
-
+
case PCMREC_STOP:
pcmrec_stop();
break;
-
+
case PCMREC_PAUSE:
/* todo */
break;
-
+
case PCMREC_RESUME:
/* todo */
break;
-
+
case PCMREC_NEW_FILE:
/* todo */
break;
-
+
case PCMREC_SET_GAIN:
+#if defined(HAVE_UDA1380)
uda1380_set_recvol(rec_gain, rec_gain, rec_volume);
+#elif defined(HAVE_TLV320)
+ /* ToDo */
+#endif
break;
case PCMREC_GOT_DATA:
@@ -637,13 +646,12 @@ static void pcmrec_thread(void)
if (!is_recording && !is_stopping)
{
usb_acknowledge(SYS_USB_CONNECTED_ACK);
- usb_wait_for_disconnect(&pcmrec_queue);
+ usb_wait_for_disconnect(&pcmrec_queue);
}
-
break;
}
}
-
+
logf("thread pcmrec done");
}
diff --git a/firmware/powermgmt.c b/firmware/powermgmt.c
index 40640cd032..6cd2fbdd3b 100644
--- a/firmware/powermgmt.c
+++ b/firmware/powermgmt.c
@@ -43,6 +43,8 @@
#endif
#ifdef HAVE_UDA1380
#include "uda1380.h"
+#eilf HAVE_TLV320
+#include "tlv320.h"
#endif
#include "logf.h"
@@ -377,7 +379,7 @@ static void handle_auto_poweroff(void)
last_event_tick = current_tick;
}
#endif
-
+
if(timeout &&
#ifdef CONFIG_TUNER
(radio_get_status() != FMRADIO_PLAYING) &&
@@ -903,6 +905,8 @@ void shutdown_hw(void)
mp3_shutdown();
#ifdef HAVE_UDA1380
uda1380_close();
+#eilf HAVE_TLV320
+ tlv320_close();
#endif
#if CONFIG_KEYPAD == ONDIO_PAD
backlight_off();
diff --git a/firmware/sound.c b/firmware/sound.c
index 9cac7cbd02..8fb015c27a 100644
--- a/firmware/sound.c
+++ b/firmware/sound.c
@@ -25,6 +25,8 @@
#include "mas.h"
#ifdef HAVE_UDA1380
#include "uda1380.h"
+#elif HAVE_TLV320
+#include "tlv320.h"
#endif
#include "dac.h"
#include "system.h"