summaryrefslogtreecommitdiffstats
path: root/firmware
diff options
context:
space:
mode:
authorMichael Sevakis <jethead71@rockbox.org>2006-11-13 23:21:54 +0000
committerMichael Sevakis <jethead71@rockbox.org>2006-11-13 23:21:54 +0000
commitcc50c149e9452e7c8ea199fd72f7458ead96bad7 (patch)
tree78efc4e2c391f0cfcab8fe76777dab63070e64d9 /firmware
parentda55588fc7e0134decd4ba8cc573f507302a5664 (diff)
downloadrockbox-cc50c149e9452e7c8ea199fd72f7458ead96bad7.tar.gz
rockbox-cc50c149e9452e7c8ea199fd72f7458ead96bad7.zip
H100/General: HAL for S/PDIF and refinement/bufixes in optical output powering/source selection.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@11523 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware')
-rw-r--r--firmware/SOURCES3
-rw-r--r--firmware/export/audio.h4
-rw-r--r--firmware/export/power.h1
-rw-r--r--firmware/export/spdif.h36
-rw-r--r--firmware/pcm_record.c55
-rw-r--r--firmware/target/coldfire/iriver/h100/power-h100.c25
-rw-r--r--firmware/target/coldfire/iriver/h100/spdif-h100.c83
-rw-r--r--firmware/target/coldfire/pcm-coldfire.c36
8 files changed, 157 insertions, 86 deletions
diff --git a/firmware/SOURCES b/firmware/SOURCES
index 369b260c8e..73d68fee91 100644
--- a/firmware/SOURCES
+++ b/firmware/SOURCES
@@ -366,6 +366,9 @@ target/coldfire/iriver/h100/backlight-h100.c
target/coldfire/iriver/h100/button-h100.c
target/coldfire/iriver/h100/lcd-as-h100.S
target/coldfire/iriver/h100/lcd-h100.c
+#ifndef BOOTLOADER
+target/coldfire/iriver/h100/spdif-h100.c
+#endif
target/coldfire/iriver/h100/usb-h100.c
#endif /* SIMULATOR */
#endif /* IRIVER_H100_SERIES */
diff --git a/firmware/export/audio.h b/firmware/export/audio.h
index d3f544de94..42d94a9158 100644
--- a/firmware/export/audio.h
+++ b/firmware/export/audio.h
@@ -185,10 +185,6 @@ unsigned char *audio_get_recording_buffer(size_t *buffer_size);
#endif /* HAVE_RECORDING */
#ifdef HAVE_SPDIF_IN
-#ifdef HAVE_SPDIF_POWER
-void audio_set_spdif_power_setting(bool on);
-bool audio_get_spdif_power_setting(void);
-#endif
/* returns index into rec_master_sampr_list */
int audio_get_spdif_sample_rate(void);
/* > 0: monitor EBUin, 0: Monitor IISrecv, <0: reset only */
diff --git a/firmware/export/power.h b/firmware/export/power.h
index dc6c09d9f9..911ae1dd29 100644
--- a/firmware/export/power.h
+++ b/firmware/export/power.h
@@ -44,6 +44,7 @@ bool ide_powered(void);
#ifdef HAVE_SPDIF_POWER
void spdif_power_enable(bool on);
+bool spdif_powered(void);
#endif
#ifdef CONFIG_TUNER
diff --git a/firmware/export/spdif.h b/firmware/export/spdif.h
new file mode 100644
index 0000000000..f4712fb88f
--- /dev/null
+++ b/firmware/export/spdif.h
@@ -0,0 +1,36 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2006 by Michal Sevakis
+ * Based on the work of Thom Johansen
+ *
+ * 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.
+ *
+ ****************************************************************************/
+#ifndef SPDIF_H
+#define SPDIF_H
+
+/* Initialize the S/PDIF driver */
+void spdif_init(void);
+/* Return the S/PDIF frequency in herz - unrounded */
+unsigned long spdif_measure_frequency(void);
+#ifdef HAVE_SPDIF_OUT
+/* Set the S/PDIF audio feed - Use AUDIO_SRC_* values -
+ will be off if not powered or !on */
+void spdif_set_output_source(int source, bool on);
+/* Return the last set S/PDIF audio source - literally the last value passed
+ to spdif_set_monitor regardless of power state */
+int spdif_get_output_source(bool *src_on);
+#endif /* HAVE_SPDIF_OUT */
+
+#endif /* SPDIF_H */
diff --git a/firmware/pcm_record.c b/firmware/pcm_record.c
index 25f1f1ef64..04289f36ec 100644
--- a/firmware/pcm_record.c
+++ b/firmware/pcm_record.c
@@ -34,6 +34,9 @@
#include "audio.h"
#include "sound.h"
#include "id3.h"
+#ifdef HAVE_SPDIF_IN
+#include "spdif.h"
+#endif
/***************************************************************************/
@@ -349,18 +352,6 @@ unsigned long audio_num_recorded_bytes(void)
} /* audio_num_recorded_bytes */
#ifdef HAVE_SPDIF_IN
-/* Return current SPDIF sample rate */
-static unsigned long measure_spdif_sample_rate(void)
-{
- /* The following formula is specified in MCF5249 user's manual section
- * 17.6.1. The 128 divide is because of the fact that the SPDIF clock is
- * the sample rate times 128. Keep "3*(1 << 13)" part in sync with
- * PHASECONFIG setup in pcm_init_recording in pcm-coldfire.c.
- */
- return (unsigned long)((unsigned long long)FREQMEAS*CPU_FREQ /
- ((1 << 15)*3*(1 << 13))/128);
-} /* measure_spdif_sample_rate */
-
/**
* Return SPDIF sample rate index in audio_master_sampr_list. Since we base
* our reading on the actual SPDIF sample rate (which might be a bit
@@ -369,47 +360,11 @@ static unsigned long measure_spdif_sample_rate(void)
*/
int audio_get_spdif_sample_rate(void)
{
- unsigned long measured_rate = measure_spdif_sample_rate();
+ unsigned long measured_rate = spdif_measure_frequency();
/* Find which SPDIF sample rate we're closest to. */
return round_value_to_list32(measured_rate, audio_master_sampr_list,
SAMPR_NUM_FREQ, false);
} /* audio_get_spdif_sample_rate */
-
-#ifdef HAVE_SPDIF_POWER
-static bool spdif_power_setting;
-
-void audio_set_spdif_power_setting(bool on)
-{
- spdif_power_setting = on;
-} /* audio_set_spdif_power_setting */
-
-bool audio_get_spdif_power_setting(void)
-{
- return spdif_power_setting;
-} /* audio_get_spdif_power_setting */
-#endif
-
-void audio_spdif_set_monitor(int monitor_spdif)
-{
- EBU1CONFIG = 0x800; /* Reset before reprogram */
-
- if (monitor_spdif > 0)
- {
-#ifdef HAVE_SPDIF_POWER
- EBU1CONFIG = spdif_power_setting ? (1 << 2) : 0;
- /* Input source is EBUin1, Feed-through monitoring if desired */
-#else
- EBU1CONFIG = (1 << 2);
- /* Input source is EBUin1, Feed-through monitoring */
-#endif
- }
- else if (monitor_spdif == 0)
- {
- /* SCLK2, TXSRC = IIS1recv, validity, normal operation */
- EBU1CONFIG = (7 << 12) | (4 << 8) | (1 << 5) | (5 << 2);
- }
-} /* audio_spdif_set_monitor */
-
#endif /* HAVE_SPDIF_IN */
/**
@@ -434,7 +389,7 @@ void audio_set_recording_options(struct audio_recording_options *options)
if (rec_source == AUDIO_SRC_SPDIF)
{
/* must measure SPDIF sample rate before configuring codecs */
- unsigned long sr = measure_spdif_sample_rate();
+ unsigned long sr = spdif_measure_frequency();
/* round to master list for SPDIF rate */
int index = round_value_to_list32(sr, audio_master_sampr_list,
SAMPR_NUM_FREQ, false);
diff --git a/firmware/target/coldfire/iriver/h100/power-h100.c b/firmware/target/coldfire/iriver/h100/power-h100.c
index 0714ab2d3f..9effeef7c8 100644
--- a/firmware/target/coldfire/iriver/h100/power-h100.c
+++ b/firmware/target/coldfire/iriver/h100/power-h100.c
@@ -22,6 +22,7 @@
#include "kernel.h"
#include "system.h"
#include "power.h"
+#include "spdif.h"
#ifdef CONFIG_TUNER
@@ -85,8 +86,23 @@ void spdif_power_enable(bool on)
and_l(~0x01000000, &GPIO1_OUT);
else
or_l(0x01000000, &GPIO1_OUT);
-}
+
+#ifndef BOOTLOADER
+ /* Make sure the feed is reset */
+ spdif_set_output_source(spdif_get_output_source(NULL), true);
#endif
+}
+
+bool spdif_powered(void)
+{
+ bool state = (GPIO1_READ & 0x01000000)?false:true;
+#ifdef SPDIF_POWER_INVERTED
+ return !state;
+#else
+ return state;
+#endif /* SPDIF_POWER_INVERTED */
+}
+#endif /* HAVE_SPDIF_POWER */
void ide_power_enable(bool on)
{
@@ -96,13 +112,11 @@ void ide_power_enable(bool on)
or_l(0x80000000, &GPIO_OUT);
}
-
bool ide_powered(void)
{
return (GPIO_OUT & 0x80000000)?false:true;
}
-
void power_off(void)
{
set_irq_level(HIGHEST_IRQ_LEVEL);
@@ -138,6 +152,11 @@ void spdif_power_enable(bool on)
{
(void)on;
}
+
+bool spdif_powered(void)
+{
+ return false;
+}
#endif
#endif /* SIMULATOR */
diff --git a/firmware/target/coldfire/iriver/h100/spdif-h100.c b/firmware/target/coldfire/iriver/h100/spdif-h100.c
new file mode 100644
index 0000000000..20e5bc3c45
--- /dev/null
+++ b/firmware/target/coldfire/iriver/h100/spdif-h100.c
@@ -0,0 +1,83 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2006 by Michal Sevakis
+ * Based on the work of Thom Johansen
+ *
+ * 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 <stdbool.h>
+#include "config.h"
+#include "cpu.h"
+#include "power.h"
+#include "system.h"
+#include "audio.h"
+#include "spdif.h"
+
+static int spdif_source = AUDIO_SRC_PLAYBACK;
+static int spdif_on = false;
+
+/* Initialize the S/PDIF driver */
+void spdif_init(void)
+{
+ /* PHASECONFIG setup: gain = 3*2^13, source = EBUIN */
+ PHASECONFIG = (6 << 3) | (4 << 0);
+ spdif_set_output_source(AUDIO_SRC_PLAYBACK, true);
+}
+
+/* Return the S/PDIF frequency in herz - unrounded */
+unsigned long spdif_measure_frequency(void)
+{
+ /* The following formula is specified in MCF5249 user's manual section
+ * 17.6.1. The 128 divide is because of the fact that the SPDIF clock is
+ * the sample rate times 128.
+ */
+ return (unsigned long)((unsigned long long)FREQMEAS*CPU_FREQ /
+ ((1 << 15)*3*(1 << 13))/128);
+} /* spdif_measure_frequency */
+
+/* Set the S/PDIF audio feed */
+void spdif_set_output_source(int source, bool src_on)
+{
+ static const unsigned short ebu1_config[] =
+ {
+ /* SCLK2, TXSRC = PDOR3, validity, normal operation */
+ [AUDIO_SRC_PLAYBACK+1] = (7 << 12) | (3 << 8) | (1 << 5) | (5 << 2),
+ /* Input source is EBUin1, Feed-through monitoring */
+ [AUDIO_SRC_SPDIF+1] = (1 << 2),
+ /* SCLK2, TXSRC = IIS1recv, validity, normal operation */
+ [AUDIO_SRC_MIC+1] = (7 << 12) | (4 << 8) | (1 << 5) | (5 << 2),
+ [AUDIO_SRC_LINEIN+1] = (7 << 12) | (4 << 8) | (1 << 5) | (5 << 2),
+ [AUDIO_SRC_FMRADIO+1] = (7 << 12) | (4 << 8) | (1 << 5) | (5 << 2),
+ };
+
+ if ((unsigned)source >= ARRAYLEN(ebu1_config))
+ source = AUDIO_SRC_PLAYBACK;
+
+ EBU1CONFIG = 0x800; /* Reset before reprogram */
+
+ spdif_source = source;
+ spdif_on = spdif_powered() && src_on;
+
+ /* Tranceiver must be powered or else monitoring will be disabled */
+ EBU1CONFIG = spdif_on ? ebu1_config[source + 1] : 0;
+} /* spdif_set_output_source */
+
+/* Return the last set S/PDIF audio source */
+int spdif_get_output_source(bool *src_on)
+{
+ if (src_on != NULL)
+ *src_on = spdif_on;
+ return spdif_source;
+} /* spdif_get_output_source */
diff --git a/firmware/target/coldfire/pcm-coldfire.c b/firmware/target/coldfire/pcm-coldfire.c
index 6b92f9cc14..0048c9990c 100644
--- a/firmware/target/coldfire/pcm-coldfire.c
+++ b/firmware/target/coldfire/pcm-coldfire.c
@@ -26,6 +26,9 @@
#elif defined(HAVE_TLV320)
#include "tlv320.h"
#endif
+#if defined(HAVE_SPDIF_IN) || defined(HAVE_SPDIF_OUT)
+#include "spdif.h"
+#endif
/* Avoid further #ifdef's for some codec functions */
#if defined(HAVE_UDA1380)
@@ -69,10 +72,6 @@ static int rec_peak_left, rec_peak_right;
#define IIS_CONFIG IIS2CONFIG
#define PLLCR_SET_AUDIO_BITS_DEFPARM \
((freq_ent[FPARM_CLSEL] << 28) | (3 << 22))
-
-#ifdef HAVE_SPDIF_OUT
-#define EBU_DEFPARM ((7 << 12) | (3 << 8) | (1 << 5) | (5 << 2))
-#endif
#endif
/** Sample rates **/
@@ -229,11 +228,6 @@ void pcm_play_dma_start(const void *addr, size_t size)
pcm_playing = true;
- /* Reset the audio FIFO */
-#ifdef HAVE_SPDIF_OUT
- EBU1CONFIG = IIS_RESET | EBU_DEFPARM;
-#endif
-
/* Set up DMA transfer */
SAR0 = (unsigned long)addr; /* Source address */
DAR0 = (unsigned long)&PDOR3; /* Destination address */
@@ -242,11 +236,6 @@ void pcm_play_dma_start(const void *addr, size_t size)
/* Enable the FIFO and force one write to it */
pcm_apply_settings(false);
- /* Also send the audio to S/PDIF */
-#ifdef HAVE_SPDIF_OUT
- EBU1CONFIG = EBU_DEFPARM;
-#endif
-
DCR0 = DMA_INT | DMA_EEXT | DMA_CS | DMA_AA |
DMA_SINC | DMA_SSIZE(3) | DMA_START;
} /* pcm_play_dma_start */
@@ -263,10 +252,6 @@ void pcm_play_dma_stop(void)
/* Reset the FIFO */
pcm_apply_settings(false);
-
-#ifdef HAVE_SPDIF_OUT
- EBU1CONFIG = IIS_RESET | EBU_DEFPARM;
-#endif
} /* pcm_play_dma_stop */
void pcm_init(void)
@@ -291,6 +276,10 @@ void pcm_init(void)
/* Prevent pops (resets DAC to zero point) */
SET_IIS_CONFIG(IIS_DEFPARM | IIS_RESET);
+#if defined(HAVE_SPDIF_IN) || defined(HAVE_SPDIF_OUT)
+ spdif_init();
+#endif
+
/* Initialize default register values. */
ac_init();
@@ -417,11 +406,6 @@ void pcm_init_recording(void)
DMACONFIG = 1; /* DMA0Req = PDOR3, DMA1Req = PDIR2 */
DMAROUTE = (DMAROUTE & 0xffff00ff) | DMA1_REQ_AUDIO_2;
-#ifdef HAVE_SPDIF_IN
- /* PHASECONFIG setup: gain = 3*2^13, source = EBUIN */
- PHASECONFIG = (6 << 3) | (4 << 0);
-#endif
-
pcm_rec_dma_stop();
ICR7 = (7 << 2); /* Enable interrupt at level 7, priority 0 */
@@ -506,18 +490,12 @@ void pcm_play_pause_pause(void)
/* Disable DMA peripheral request. */
DCR0 &= ~DMA_EEXT;
pcm_apply_settings(true);
-#ifdef HAVE_SPDIF_OUT
- EBU1CONFIG = EBU_DEFPARM;
-#endif
} /* pcm_play_pause_pause */
void pcm_play_pause_unpause(void)
{
/* Enable the FIFO and force one write to it */
pcm_apply_settings(false);
-#ifdef HAVE_SPDIF_OUT
- EBU1CONFIG = EBU_DEFPARM;
-#endif
DCR0 |= DMA_EEXT | DMA_START;
} /* pcm_play_pause_unpause */