From ab1861a3c2c06cf3edff7c42348d117f21235e48 Mon Sep 17 00:00:00 2001 From: Michael Sevakis Date: Thu, 23 Nov 2006 19:21:15 +0000 Subject: iRiver/iAudio: Added audio_set_recording gain and sound_default to plugin API. Simplified plugin recording by target/-ing some audio functions. UDA1380 records with WSPLL as a result. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@11577 a1c6a512-1295-4272-9138-f99709370657 --- firmware/target/coldfire/iaudio/x5/audio-x5.c | 126 +++++++++++++++++++++ firmware/target/coldfire/iriver/audio-iriver.c | 148 +++++++++++++++++++++++++ firmware/target/coldfire/pcm-coldfire.c | 110 ++---------------- 3 files changed, 285 insertions(+), 99 deletions(-) create mode 100644 firmware/target/coldfire/iaudio/x5/audio-x5.c create mode 100644 firmware/target/coldfire/iriver/audio-iriver.c (limited to 'firmware/target/coldfire') diff --git a/firmware/target/coldfire/iaudio/x5/audio-x5.c b/firmware/target/coldfire/iaudio/x5/audio-x5.c new file mode 100644 index 0000000000..70ef78ff22 --- /dev/null +++ b/firmware/target/coldfire/iaudio/x5/audio-x5.c @@ -0,0 +1,126 @@ +/*************************************************************************** + * __________ __ ___. + * 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 "system.h" +#include "cpu.h" +#include "audio.h" +#include "tlv320.h" + +/** + * Note that microphone is mono, only left value is used + * See tlv320_set_recvol() for exact ranges. + * + * @param type 0=line-in (radio), 1=mic + * + */ +void audio_set_recording_gain(int left, int right, int type) +{ + //logf("rcmrec: t=%d l=%d r=%d", type, left, right); + tlv320_set_recvol(left, right, type); +} /* audio_set_recording_gain */ + +void audio_set_output_source(int source) +{ + unsigned long txsrc; + + if ((unsigned)source >= AUDIO_NUM_SOURCES) + txsrc = (3 << 8); /* playback, PDOR3 */ + else + txsrc = (4 << 8); /* recording, iis1RcvData */ + + IIS1CONFIG = (IIS1CONFIG & ~(7 << 8)) | txsrc; +} /* audio_set_output_source */ + +void audio_set_source(int source, unsigned flags) +{ + /* Prevent pops from unneeded switching */ + static int last_source = AUDIO_SRC_PLAYBACK; + static bool last_recording = false; + + bool recording = flags & SRCF_RECORDING; + + switch (source) + { + default: /* playback - no recording */ + source = AUDIO_SRC_PLAYBACK; + case AUDIO_SRC_PLAYBACK: + if (source != last_source) + { + tlv320_disable_recording(); + tlv320_set_monitor(false); + /* Reset PDIR2 data flow */ + DATAINCONTROL = (1 << 9); + } + break; + + case AUDIO_SRC_MIC: /* recording only */ + if (source != last_source) + { + tlv320_enable_recording(true); /* source mic */ + /* Int. when 6 samples in FIFO, PDIR2 src = iis1RcvData */ + DATAINCONTROL = (3 << 14) | (4 << 3); + } + break; + + case AUDIO_SRC_LINEIN: /* recording only */ + if (source != last_source) + { + tlv320_enable_recording(false); /* source line */ + /* Int. when 6 samples in FIFO, PDIR2 src = iis1RcvData */ + DATAINCONTROL = (3 << 14) | (4 << 3); + } + break; + + case AUDIO_SRC_FMRADIO: /* recording and playback */ + if (!recording) + tlv320_set_recvol(23, 23, AUDIO_GAIN_LINEIN); + + /* I2S recording and analog playback */ + if (source == last_source && recording == last_recording) + break; + + last_recording = recording; + + if (recording) + { + /* Int. when 6 samples in FIFO, PDIR2 src = iis1RcvData */ + DATAINCONTROL = (3 << 14) | (4 << 3); + tlv320_enable_recording(false); /* source line */ + } + else + { + tlv320_disable_recording(); + tlv320_set_monitor(true); /* analog bypass */ + /* Reset PDIR2 data flow */ + DATAINCONTROL = (1 << 9); + } + break; + } /* end switch */ + + /* set line multiplexer */ + if (source == AUDIO_SRC_FMRADIO) + and_l(~(1 << 29), &GPIO_OUT); /* FM radio */ + else + or_l((1 << 29), &GPIO_OUT); /* Line In */ + + or_l((1 << 29), &GPIO_ENABLE); + or_l((1 << 29), &GPIO_FUNCTION); + + last_source = source; +} /* audio_set_source */ + diff --git a/firmware/target/coldfire/iriver/audio-iriver.c b/firmware/target/coldfire/iriver/audio-iriver.c new file mode 100644 index 0000000000..7a52ce1ff0 --- /dev/null +++ b/firmware/target/coldfire/iriver/audio-iriver.c @@ -0,0 +1,148 @@ +/*************************************************************************** + * __________ __ ___. + * 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 "system.h" +#include "cpu.h" +#include "audio.h" +#include "uda1380.h" + +/** + * Note that microphone is mono, only left value is used + * See uda1380_set_recvol() for exact ranges. + * + * @param type AUDIO_GAIN_MIC, AUDIO_GAIN_LINEIN + * + */ +void audio_set_recording_gain(int left, int right, int type) +{ + //logf("rcmrec: t=%d l=%d r=%d", type, left, right); + uda1380_set_recvol(left, right, type); +} /* audio_set_recording_gain */ + +void audio_set_output_source(int source) +{ + static const unsigned char txsrc_select[AUDIO_NUM_SOURCES+1] = + { + [AUDIO_SRC_PLAYBACK+1] = 3, /* PDOR3 */ + [AUDIO_SRC_MIC+1] = 4, /* IIS1 RcvData */ + [AUDIO_SRC_LINEIN+1] = 4, /* IIS1 RcvData */ + [AUDIO_SRC_FMRADIO+1] = 4, /* IIS1 RcvData */ + #ifdef HAVE_SPDIF_IN + [AUDIO_SRC_SPDIF+1] = 7, /* EBU1 RcvData */ + #endif + }; + + if ((unsigned)source >= AUDIO_NUM_SOURCES) + source = AUDIO_SRC_PLAYBACK; + + IIS2CONFIG = (IIS2CONFIG & ~(7 << 8)) | (txsrc_select[source+1] << 8); +} /* audio_set_output_source */ + +void audio_set_source(int source, unsigned flags) +{ + /* Prevent pops from unneeded switching */ + static int last_source = AUDIO_SRC_PLAYBACK; + bool recording = flags & SRCF_RECORDING; + + switch (source) + { + default: /* playback - no recording */ + source = AUDIO_SRC_PLAYBACK; + case AUDIO_SRC_PLAYBACK: + if (source != last_source) + { + uda1380_disable_recording(); + uda1380_set_monitor(false); + /* Reset PDIR2 data flow */ + DATAINCONTROL = (1 << 9); + } + break; + + case AUDIO_SRC_MIC: /* recording only */ + if (source != last_source) + { + uda1380_enable_recording(true); /* source mic */ + uda1380_set_monitor(true); + /* Int. when 6 samples in FIFO, PDIR2 src = iis1RcvData */ + DATAINCONTROL = (3 << 14) | (4 << 3); + } + break; + + case AUDIO_SRC_LINEIN: /* recording only */ + if (source != last_source) + { + uda1380_enable_recording(false); /* source line */ + uda1380_set_monitor(true); + /* Int. when 6 samples in FIFO, PDIR2 src = iis1RcvData */ + DATAINCONTROL = (3 << 14) | (4 << 3); + } + break; + +#ifdef HAVE_SPDIF_IN + case AUDIO_SRC_SPDIF: /* recording only */ + if (source != last_source) + { + uda1380_disable_recording(); + uda1380_set_monitor(false); + /* Int. when 6 samples in FIFO, PDIR2 src = ebu1RcvData */ + DATAINCONTROL = (3 << 14) | (7 << 3); + } + break; +#endif /* HAVE_SPDIF_IN */ + + case AUDIO_SRC_FMRADIO: /* recording and playback */ + if (recording) + { + /* Int. when 6 samples in FIFO, PDIR2 src = iis1RcvData */ + DATAINCONTROL = (3 << 14) | (4 << 3); + } + else + { + uda1380_set_recvol(0, 0, AUDIO_GAIN_LINEIN); + /* Reset PDIR2 data flow */ + DATAINCONTROL = (1 << 9); + } + + if (source != last_source) + { + /* I2S recording and playback */ + uda1380_enable_recording(false); /* source line */ + uda1380_set_monitor(true); + } + break; + } /* end switch */ + + /* set line multiplexer */ +#if defined(IRIVER_H100_SERIES) + #define MUX_BIT (1 << 23) +#elif defined(IRIVER_H300_SERIES) + #define MUX_BIT (1 << 30) +#endif + + if (source == AUDIO_SRC_FMRADIO) + or_l(MUX_BIT, &GPIO_OUT); /* FM radio */ + else + and_l(~MUX_BIT, &GPIO_OUT); /* Line In */ + + or_l(MUX_BIT, &GPIO_ENABLE); + or_l(MUX_BIT, &GPIO_FUNCTION); + + last_source = source; +} /* audio_set_source */ + + diff --git a/firmware/target/coldfire/pcm-coldfire.c b/firmware/target/coldfire/pcm-coldfire.c index a0d3b67f58..2936cf5621 100644 --- a/firmware/target/coldfire/pcm-coldfire.c +++ b/firmware/target/coldfire/pcm-coldfire.c @@ -57,9 +57,9 @@ static int play_peak_left, play_peak_right; static unsigned long *rec_peak_addr; static int rec_peak_left, rec_peak_right; -#define IIS_DEFPARM ( (freq_ent[FPARM_CLOCKSEL] << 12) | \ - (pcm_txsrc_select[pcm_monitor+1] << 8) | \ - (4 << 2) ) /* 64 bit clocks / word clock */ +#define IIS_DEFPARM(output) ( (freq_ent[FPARM_CLOCKSEL] << 12) | \ + (output) | \ + (4 << 2) ) /* 64 bit clocks / word clock */ #define IIS_RESET 0x800 #ifdef IAUDIO_X5 @@ -128,80 +128,22 @@ void pcm_set_frequency(unsigned int frequency) pcm_freq = hw_freq_sampr[index]; } /* pcm_set_frequency */ -/** monitoring/source selection **/ -static int pcm_monitor = AUDIO_SRC_PLAYBACK; - -static const unsigned char pcm_txsrc_select[AUDIO_NUM_SOURCES+1] = -{ - [AUDIO_SRC_PLAYBACK+1] = 3, /* PDOR3 */ - [AUDIO_SRC_MIC+1] = 4, /* IIS1 RcvData */ - [AUDIO_SRC_LINEIN+1] = 4, /* IIS1 RcvData */ -#ifdef HAVE_FMRADIO_IN - [AUDIO_SRC_FMRADIO+1] = 4, /* IIS1 RcvData */ -#endif -#ifdef HAVE_SPDIF_IN - [AUDIO_SRC_SPDIF+1] = 7, /* EBU1 RcvData */ -#endif -}; - -static const unsigned short pcm_dataincontrol[AUDIO_NUM_SOURCES+1] = -{ - [AUDIO_SRC_PLAYBACK+1] = 0x0200, /* Reset PDIR2 data flow */ - [AUDIO_SRC_MIC+1] = 0xc020, /* Int. when 6 samples in FIFO, - PDIR2 src = ebu1RcvData */ - [AUDIO_SRC_LINEIN+1] = 0xc020, /* Int. when 6 samples in FIFO, - PDIR2 src = ebu1RcvData */ -#ifdef HAVE_FMRADIO_IN - [AUDIO_SRC_FMRADIO+1] = 0xc020, /* Int. when 6 samples in FIFO, - PDIR2 src = ebu1RcvData */ -#endif -#ifdef HAVE_SPDIF_IN - [AUDIO_SRC_SPDIF+1] = 0xc038, /* Int. when 6 samples in FIFO, - PDIR2 src = ebu1RcvData */ -#endif -}; - -static int pcm_rec_src = AUDIO_SRC_PLAYBACK; - -void pcm_set_monitor(int monitor) -{ - if ((unsigned)monitor >= AUDIO_NUM_SOURCES) - monitor = AUDIO_SRC_PLAYBACK; - pcm_monitor = monitor; -} /* pcm_set_monitor */ - -void pcm_set_rec_source(int source) -{ - if ((unsigned)source >= AUDIO_NUM_SOURCES) - source = AUDIO_SRC_PLAYBACK; - pcm_rec_src = source; -} /* pcm_set_rec_source */ - /* apply audio settings */ void pcm_apply_settings(bool reset) { - static int last_pcm_freq = HW_SAMPR_DEFAULT; -#if 0 - static int last_pcm_monitor = AUDIO_SRC_PLAYBACK; -#endif - static int last_pcm_rec_src = AUDIO_SRC_PLAYBACK; + static int last_pcm_freq = HW_SAMPR_DEFAULT; + unsigned long output = IIS_CONFIG & (7 << 8); - /* Playback must prevent pops and record monitoring won't work at all + /* Playback must prevent pops and record monitoring won't work at all if adding IIS_RESET when setting IIS_CONFIG. Use a different method for each. */ - if (reset && (pcm_monitor != AUDIO_SRC_PLAYBACK)) + if (reset && output != (3 << 8)) { /* Not playback - reset first */ SET_IIS_CONFIG(IIS_RESET); reset = false; } - if (pcm_rec_src != last_pcm_rec_src) - { - last_pcm_rec_src = pcm_rec_src; - DATAINCONTROL = pcm_dataincontrol[pcm_rec_src+1]; - } - if (pcm_freq != last_pcm_freq) { last_pcm_freq = pcm_freq; @@ -209,7 +151,7 @@ void pcm_apply_settings(bool reset) coldfire_set_pllcr_audio_bits(PLLCR_SET_AUDIO_BITS_DEFPARM); } - SET_IIS_CONFIG(IIS_DEFPARM | (reset ? IIS_RESET : 0)); + SET_IIS_CONFIG(IIS_DEFPARM(output) | (reset ? IIS_RESET : 0)); } /* pcm_apply_settings */ /** DMA **/ @@ -270,11 +212,10 @@ void pcm_init(void) /* Reset the audio FIFO */ SET_IIS_CONFIG(IIS_RESET); - pcm_set_frequency(-1); - pcm_set_monitor(-1); + pcm_set_frequency(HW_FREQ_DEFAULT); /* Prevent pops (resets DAC to zero point) */ - SET_IIS_CONFIG(IIS_DEFPARM | IIS_RESET); + SET_IIS_CONFIG(IIS_DEFPARM(3 << 8) | IIS_RESET); #if defined(HAVE_SPDIF_IN) || defined(HAVE_SPDIF_OUT) spdif_init(); @@ -443,7 +384,7 @@ void DMA1(void) logf("DMA1 err: 0x%x", res); } #ifdef HAVE_SPDIF_IN - else if (pcm_rec_src == AUDIO_SRC_SPDIF && + else if (DATAINCONTROL == 0xc038 && (INTERRUPTSTAT & 0x01c00000)) /* valnogood, symbolerr, parityerr */ { INTERRUPTCLEAR = 0x03c00000; @@ -685,32 +626,3 @@ peak_done: if (right) *right = rec_peak_right; } /* pcm_calculate_rec_peaks */ - -/** - * Select VINL & VINR source: 0=Line-in, 1=FM Radio - */ -/* All use GPIO */ -#if defined(IAUDIO_X5) - #define REC_MUX_BIT (1 << 29) - #define REC_MUX_SET_LINE() or_l(REC_MUX_BIT, &GPIO_OUT) - #define REC_MUX_SET_FM() and_l(~REC_MUX_BIT, &GPIO_OUT) -#else -#if defined(IRIVER_H100_SERIES) - #define REC_MUX_BIT (1 << 23) -#elif defined(IRIVER_H300_SERIES) - #define REC_MUX_BIT (1 << 30) -#endif - #define REC_MUX_SET_LINE() and_l(~REC_MUX_BIT, &GPIO_OUT) - #define REC_MUX_SET_FM() or_l(REC_MUX_BIT, &GPIO_OUT) -#endif - -void pcm_rec_mux(int source) -{ - if (source == 0) - REC_MUX_SET_LINE(); /* Line In */ - else - REC_MUX_SET_FM(); /* FM radio */ - - or_l(REC_MUX_BIT, &GPIO_ENABLE); - or_l(REC_MUX_BIT, &GPIO_FUNCTION); -} /* pcm_rec_mux */ -- cgit v1.2.3