summaryrefslogtreecommitdiff
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
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
-rw-r--r--apps/debug_menu.c15
-rw-r--r--apps/recorder/recording.c38
-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
10 files changed, 183 insertions, 113 deletions
diff --git a/apps/debug_menu.c b/apps/debug_menu.c
index 4620adaaec..e1bb5ccb9f 100644
--- a/apps/debug_menu.c
+++ b/apps/debug_menu.c
@@ -74,6 +74,9 @@
74#if CONFIG_CODEC == SWCODEC 74#if CONFIG_CODEC == SWCODEC
75#include "pcmbuf.h" 75#include "pcmbuf.h"
76#include "pcm_playback.h" 76#include "pcm_playback.h"
77#if defined(HAVE_SPDIF_OUT) || defined(HAVE_SPDIF_IN)
78#include "spdif.h"
79#endif
77#endif 80#endif
78 81
79#ifdef IAUDIO_X5 82#ifdef IAUDIO_X5
@@ -774,14 +777,17 @@ bool dbg_spdif(void)
774 unsigned int interruptstat; 777 unsigned int interruptstat;
775 bool valnogood, symbolerr, parityerr; 778 bool valnogood, symbolerr, parityerr;
776 bool done = false; 779 bool done = false;
780 bool spdif_src_on;
781 int spdif_source = spdif_get_output_source(&spdif_src_on);
782 spdif_set_output_source(AUDIO_SRC_SPDIF, true);
777 783
778 lcd_setmargins(0, 0); 784 lcd_setmargins(0, 0);
779 lcd_clear_display(); 785 lcd_clear_display();
780 lcd_setfont(FONT_SYSFIXED); 786 lcd_setfont(FONT_SYSFIXED);
787
781#ifdef HAVE_SPDIF_POWER 788#ifdef HAVE_SPDIF_POWER
782 spdif_power_enable(true); /* We need SPDIF power for both sending & receiving */ 789 spdif_power_enable(true); /* We need SPDIF power for both sending & receiving */
783#endif 790#endif
784 PHASECONFIG = 0x34; /* Gain = 3*2^13, source = EBUIN */
785 791
786 while (!done) 792 while (!done)
787 { 793 {
@@ -914,15 +920,18 @@ bool dbg_spdif(void)
914 920
915#ifndef SIMULATOR 921#ifndef SIMULATOR
916 snprintf(buf, sizeof(buf), "Measured freq: %ldHz", 922 snprintf(buf, sizeof(buf), "Measured freq: %ldHz",
917 (long)((long long)FREQMEAS*CPU_FREQ/((1 << 15)*3*(1 << 13))/128)); 923 spdif_measure_frequency());
918 lcd_puts(0, line++, buf); 924 lcd_puts(0, line++, buf);
919#endif 925#endif
920 926
921 lcd_update(); 927 lcd_update();
922 928
923 if (action_userabort(HZ/10)) 929 if (action_userabort(HZ/10))
924 return false; 930 break;
925 } 931 }
932
933 spdif_set_output_source(spdif_source, spdif_src_on);
934
926#ifdef HAVE_SPDIF_POWER 935#ifdef HAVE_SPDIF_POWER
927 spdif_power_enable(global_settings.spdif_enable); 936 spdif_power_enable(global_settings.spdif_enable);
928#endif 937#endif
diff --git a/apps/recorder/recording.c b/apps/recorder/recording.c
index d38856db23..4c2b00c33c 100644
--- a/apps/recorder/recording.c
+++ b/apps/recorder/recording.c
@@ -34,7 +34,10 @@
34#include "pcm_playback.h" 34#include "pcm_playback.h"
35#include "playback.h" 35#include "playback.h"
36#include "enc_config.h" 36#include "enc_config.h"
37#if defined(HAVE_SPDIF_IN) || defined(HAVE_SPDIF_OUT)
38#include "spdif.h"
37#endif 39#endif
40#endif /* CONFIG_CODEC == SWCODEC */
38#ifdef HAVE_UDA1380 41#ifdef HAVE_UDA1380
39#include "uda1380.h" 42#include "uda1380.h"
40#endif 43#endif
@@ -587,12 +590,6 @@ static void rec_boost(bool state)
587#define ac_set_monitor tlv320_set_monitor 590#define ac_set_monitor tlv320_set_monitor
588#endif 591#endif
589 592
590#ifdef HAVE_SPDIF_IN
591#define rec_spdif_set_monitor(m) audio_spdif_set_monitor(m)
592#else
593#define rec_spdif_set_monitor(m)
594#endif
595
596void rec_set_source(int source, unsigned flags) 593void rec_set_source(int source, unsigned flags)
597{ 594{
598 /* Prevent pops from unneeded switching */ 595 /* Prevent pops from unneeded switching */
@@ -613,15 +610,23 @@ void rec_set_source(int source, unsigned flags)
613 /* Always boost for SPDIF */ 610 /* Always boost for SPDIF */
614 if ((source == AUDIO_SRC_SPDIF) != (source == last_source)) 611 if ((source == AUDIO_SRC_SPDIF) != (source == last_source))
615 rec_boost(source == AUDIO_SRC_SPDIF); 612 rec_boost(source == AUDIO_SRC_SPDIF);
613#endif /* HAVE_SPDIF_IN */
616 614
617#ifdef HAVE_SPDIF_POWER 615#ifdef HAVE_SPDIF_POWER
618 /* Check if S/PDIF output power should be switched off or on. NOTE: assumes 616 /* Check if S/PDIF output power should be switched off or on. NOTE: assumes
619 both optical in and out is controlled by the same power source, which is 617 both optical in and out is controlled by the same power source, which is
620 the case on H1x0. */ 618 the case on H1x0. */
621 spdif_power_enable((source == AUDIO_SRC_SPDIF) || 619 spdif_power_enable((source == AUDIO_SRC_SPDIF) ||
622 audio_get_spdif_power_setting()); 620 global_settings.spdif_enable);
621 /* Set the appropriate feed for spdif output */
622#ifdef HAVE_SPDIF_OUT
623 spdif_set_output_source(source, global_settings.spdif_enable);
623#endif 624#endif
625#else /* !HAVE_SPDIF_POWER */
626#ifdef HAVE_SPDIF_OUT
627 spdif_set_output_source(source, true);
624#endif 628#endif
629#endif /* !HAVE_SPDIF_POWER */
625 630
626 /** Tuner **/ 631 /** Tuner **/
627#ifdef CONFIG_TUNER 632#ifdef CONFIG_TUNER
@@ -645,7 +650,6 @@ void rec_set_source(int source, unsigned flags)
645 ac_disable_recording(); 650 ac_disable_recording();
646 ac_set_monitor(false); 651 ac_set_monitor(false);
647 pcm_rec_mux(0); /* line in */ 652 pcm_rec_mux(0); /* line in */
648 rec_spdif_set_monitor(-1); /* silence it */
649 break; 653 break;
650 654
651 case AUDIO_SRC_MIC: /* recording only */ 655 case AUDIO_SRC_MIC: /* recording only */
@@ -653,7 +657,6 @@ void rec_set_source(int source, unsigned flags)
653 break; 657 break;
654 ac_enable_recording(true); /* source mic */ 658 ac_enable_recording(true); /* source mic */
655 pcm_rec_mux(0); /* line in */ 659 pcm_rec_mux(0); /* line in */
656 rec_spdif_set_monitor(0);
657 break; 660 break;
658 661
659 case AUDIO_SRC_LINEIN: /* recording only */ 662 case AUDIO_SRC_LINEIN: /* recording only */
@@ -661,7 +664,6 @@ void rec_set_source(int source, unsigned flags)
661 break; 664 break;
662 pcm_rec_mux(0); /* line in */ 665 pcm_rec_mux(0); /* line in */
663 ac_enable_recording(false); /* source line */ 666 ac_enable_recording(false); /* source line */
664 rec_spdif_set_monitor(0);
665 break; 667 break;
666 668
667#ifdef HAVE_SPDIF_IN 669#ifdef HAVE_SPDIF_IN
@@ -669,7 +671,6 @@ void rec_set_source(int source, unsigned flags)
669 if (source == last_source) 671 if (source == last_source)
670 break; 672 break;
671 ac_disable_recording(); 673 ac_disable_recording();
672 audio_spdif_set_monitor(1);
673 break; 674 break;
674#endif /* HAVE_SPDIF_IN */ 675#endif /* HAVE_SPDIF_IN */
675 676
@@ -690,7 +691,6 @@ void rec_set_source(int source, unsigned flags)
690 break; 691 break;
691 /* I2S recording and playback */ 692 /* I2S recording and playback */
692 uda1380_enable_recording(false); /* source line */ 693 uda1380_enable_recording(false); /* source line */
693 uda1380_set_monitor(true);
694#endif 694#endif
695#ifdef HAVE_TLV320 695#ifdef HAVE_TLV320
696 /* I2S recording and analog playback */ 696 /* I2S recording and analog playback */
@@ -707,8 +707,6 @@ void rec_set_source(int source, unsigned flags)
707 tlv320_set_monitor(true); /* analog bypass */ 707 tlv320_set_monitor(true); /* analog bypass */
708 } 708 }
709#endif 709#endif
710
711 rec_spdif_set_monitor(0);
712 break; 710 break;
713/* #elif defined(CONFIG_TUNER) */ 711/* #elif defined(CONFIG_TUNER) */
714/* Have radio but cannot record it */ 712/* Have radio but cannot record it */
@@ -745,18 +743,10 @@ void rec_set_recording_options(struct audio_recording_options *options)
745#if CONFIG_CODEC != SWCODEC 743#if CONFIG_CODEC != SWCODEC
746 if (global_settings.rec_prerecord_time) 744 if (global_settings.rec_prerecord_time)
747 talk_buffer_steal(); /* will use the mp3 buffer */ 745 talk_buffer_steal(); /* will use the mp3 buffer */
748#endif 746#else /* == SWOCODEC */
749
750#ifdef HAVE_SPDIF_IN
751#ifdef HAVE_SPDIF_POWER
752 audio_set_spdif_power_setting(global_settings.spdif_enable);
753#endif
754#endif
755
756#if CONFIG_CODEC == SWCODEC
757 rec_set_source(options->rec_source, 747 rec_set_source(options->rec_source,
758 options->rec_source_flags | SRCF_RECORDING); 748 options->rec_source_flags | SRCF_RECORDING);
759#endif 749#endif /* CONFIG_CODEC != SWCODEC */
760 750
761 audio_set_recording_options(options); 751 audio_set_recording_options(options);
762} 752}
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
366target/coldfire/iriver/h100/button-h100.c 366target/coldfire/iriver/h100/button-h100.c
367target/coldfire/iriver/h100/lcd-as-h100.S 367target/coldfire/iriver/h100/lcd-as-h100.S
368target/coldfire/iriver/h100/lcd-h100.c 368target/coldfire/iriver/h100/lcd-h100.c
369#ifndef BOOTLOADER
370target/coldfire/iriver/h100/spdif-h100.c
371#endif
369target/coldfire/iriver/h100/usb-h100.c 372target/coldfire/iriver/h100/usb-h100.c
370#endif /* SIMULATOR */ 373#endif /* SIMULATOR */
371#endif /* IRIVER_H100_SERIES */ 374#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);
185#endif /* HAVE_RECORDING */ 185#endif /* HAVE_RECORDING */
186 186
187#ifdef HAVE_SPDIF_IN 187#ifdef HAVE_SPDIF_IN
188#ifdef HAVE_SPDIF_POWER
189void audio_set_spdif_power_setting(bool on);
190bool audio_get_spdif_power_setting(void);
191#endif
192/* returns index into rec_master_sampr_list */ 188/* returns index into rec_master_sampr_list */
193int audio_get_spdif_sample_rate(void); 189int audio_get_spdif_sample_rate(void);
194/* > 0: monitor EBUin, 0: Monitor IISrecv, <0: reset only */ 190/* > 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);
44 44
45#ifdef HAVE_SPDIF_POWER 45#ifdef HAVE_SPDIF_POWER
46void spdif_power_enable(bool on); 46void spdif_power_enable(bool on);
47bool spdif_powered(void);
47#endif 48#endif
48 49
49#ifdef CONFIG_TUNER 50#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 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2006 by Michal Sevakis
11 * Based on the work of Thom Johansen
12 *
13 * All files in this archive are subject to the GNU General Public License.
14 * See the file COPYING in the source tree root for full license agreement.
15 *
16 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
17 * KIND, either express or implied.
18 *
19 ****************************************************************************/
20#ifndef SPDIF_H
21#define SPDIF_H
22
23/* Initialize the S/PDIF driver */
24void spdif_init(void);
25/* Return the S/PDIF frequency in herz - unrounded */
26unsigned long spdif_measure_frequency(void);
27#ifdef HAVE_SPDIF_OUT
28/* Set the S/PDIF audio feed - Use AUDIO_SRC_* values -
29 will be off if not powered or !on */
30void spdif_set_output_source(int source, bool on);
31/* Return the last set S/PDIF audio source - literally the last value passed
32 to spdif_set_monitor regardless of power state */
33int spdif_get_output_source(bool *src_on);
34#endif /* HAVE_SPDIF_OUT */
35
36#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 @@
34#include "audio.h" 34#include "audio.h"
35#include "sound.h" 35#include "sound.h"
36#include "id3.h" 36#include "id3.h"
37#ifdef HAVE_SPDIF_IN
38#include "spdif.h"
39#endif
37 40
38/***************************************************************************/ 41/***************************************************************************/
39 42
@@ -349,18 +352,6 @@ unsigned long audio_num_recorded_bytes(void)
349} /* audio_num_recorded_bytes */ 352} /* audio_num_recorded_bytes */
350 353
351#ifdef HAVE_SPDIF_IN 354#ifdef HAVE_SPDIF_IN
352/* Return current SPDIF sample rate */
353static unsigned long measure_spdif_sample_rate(void)
354{
355 /* The following formula is specified in MCF5249 user's manual section
356 * 17.6.1. The 128 divide is because of the fact that the SPDIF clock is
357 * the sample rate times 128. Keep "3*(1 << 13)" part in sync with
358 * PHASECONFIG setup in pcm_init_recording in pcm-coldfire.c.
359 */
360 return (unsigned long)((unsigned long long)FREQMEAS*CPU_FREQ /
361 ((1 << 15)*3*(1 << 13))/128);
362} /* measure_spdif_sample_rate */
363
364/** 355/**
365 * Return SPDIF sample rate index in audio_master_sampr_list. Since we base 356 * Return SPDIF sample rate index in audio_master_sampr_list. Since we base
366 * our reading on the actual SPDIF sample rate (which might be a bit 357 * 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)
369 */ 360 */
370int audio_get_spdif_sample_rate(void) 361int audio_get_spdif_sample_rate(void)
371{ 362{
372 unsigned long measured_rate = measure_spdif_sample_rate(); 363 unsigned long measured_rate = spdif_measure_frequency();
373 /* Find which SPDIF sample rate we're closest to. */ 364 /* Find which SPDIF sample rate we're closest to. */
374 return round_value_to_list32(measured_rate, audio_master_sampr_list, 365 return round_value_to_list32(measured_rate, audio_master_sampr_list,
375 SAMPR_NUM_FREQ, false); 366 SAMPR_NUM_FREQ, false);
376} /* audio_get_spdif_sample_rate */ 367} /* audio_get_spdif_sample_rate */
377
378#ifdef HAVE_SPDIF_POWER
379static bool spdif_power_setting;
380
381void audio_set_spdif_power_setting(bool on)
382{
383 spdif_power_setting = on;
384} /* audio_set_spdif_power_setting */
385
386bool audio_get_spdif_power_setting(void)
387{
388 return spdif_power_setting;
389} /* audio_get_spdif_power_setting */
390#endif
391
392void audio_spdif_set_monitor(int monitor_spdif)
393{
394 EBU1CONFIG = 0x800; /* Reset before reprogram */
395
396 if (monitor_spdif > 0)
397 {
398#ifdef HAVE_SPDIF_POWER
399 EBU1CONFIG = spdif_power_setting ? (1 << 2) : 0;
400 /* Input source is EBUin1, Feed-through monitoring if desired */
401#else
402 EBU1CONFIG = (1 << 2);
403 /* Input source is EBUin1, Feed-through monitoring */
404#endif
405 }
406 else if (monitor_spdif == 0)
407 {
408 /* SCLK2, TXSRC = IIS1recv, validity, normal operation */
409 EBU1CONFIG = (7 << 12) | (4 << 8) | (1 << 5) | (5 << 2);
410 }
411} /* audio_spdif_set_monitor */
412
413#endif /* HAVE_SPDIF_IN */ 368#endif /* HAVE_SPDIF_IN */
414 369
415/** 370/**
@@ -434,7 +389,7 @@ void audio_set_recording_options(struct audio_recording_options *options)
434 if (rec_source == AUDIO_SRC_SPDIF) 389 if (rec_source == AUDIO_SRC_SPDIF)
435 { 390 {
436 /* must measure SPDIF sample rate before configuring codecs */ 391 /* must measure SPDIF sample rate before configuring codecs */
437 unsigned long sr = measure_spdif_sample_rate(); 392 unsigned long sr = spdif_measure_frequency();
438 /* round to master list for SPDIF rate */ 393 /* round to master list for SPDIF rate */
439 int index = round_value_to_list32(sr, audio_master_sampr_list, 394 int index = round_value_to_list32(sr, audio_master_sampr_list,
440 SAMPR_NUM_FREQ, false); 395 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 @@
22#include "kernel.h" 22#include "kernel.h"
23#include "system.h" 23#include "system.h"
24#include "power.h" 24#include "power.h"
25#include "spdif.h"
25 26
26 27
27#ifdef CONFIG_TUNER 28#ifdef CONFIG_TUNER
@@ -85,8 +86,23 @@ void spdif_power_enable(bool on)
85 and_l(~0x01000000, &GPIO1_OUT); 86 and_l(~0x01000000, &GPIO1_OUT);
86 else 87 else
87 or_l(0x01000000, &GPIO1_OUT); 88 or_l(0x01000000, &GPIO1_OUT);
88} 89
90#ifndef BOOTLOADER
91 /* Make sure the feed is reset */
92 spdif_set_output_source(spdif_get_output_source(NULL), true);
89#endif 93#endif
94}
95
96bool spdif_powered(void)
97{
98 bool state = (GPIO1_READ & 0x01000000)?false:true;
99#ifdef SPDIF_POWER_INVERTED
100 return !state;
101#else
102 return state;
103#endif /* SPDIF_POWER_INVERTED */
104}
105#endif /* HAVE_SPDIF_POWER */
90 106
91void ide_power_enable(bool on) 107void ide_power_enable(bool on)
92{ 108{
@@ -96,13 +112,11 @@ void ide_power_enable(bool on)
96 or_l(0x80000000, &GPIO_OUT); 112 or_l(0x80000000, &GPIO_OUT);
97} 113}
98 114
99
100bool ide_powered(void) 115bool ide_powered(void)
101{ 116{
102 return (GPIO_OUT & 0x80000000)?false:true; 117 return (GPIO_OUT & 0x80000000)?false:true;
103} 118}
104 119
105
106void power_off(void) 120void power_off(void)
107{ 121{
108 set_irq_level(HIGHEST_IRQ_LEVEL); 122 set_irq_level(HIGHEST_IRQ_LEVEL);
@@ -138,6 +152,11 @@ void spdif_power_enable(bool on)
138{ 152{
139 (void)on; 153 (void)on;
140} 154}
155
156bool spdif_powered(void)
157{
158 return false;
159}
141#endif 160#endif
142 161
143#endif /* SIMULATOR */ 162#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 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2006 by Michal Sevakis
11 * Based on the work of Thom Johansen
12 *
13 * All files in this archive are subject to the GNU General Public License.
14 * See the file COPYING in the source tree root for full license agreement.
15 *
16 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
17 * KIND, either express or implied.
18 *
19 ****************************************************************************/
20#include <stdbool.h>
21#include "config.h"
22#include "cpu.h"
23#include "power.h"
24#include "system.h"
25#include "audio.h"
26#include "spdif.h"
27
28static int spdif_source = AUDIO_SRC_PLAYBACK;
29static int spdif_on = false;
30
31/* Initialize the S/PDIF driver */
32void spdif_init(void)
33{
34 /* PHASECONFIG setup: gain = 3*2^13, source = EBUIN */
35 PHASECONFIG = (6 << 3) | (4 << 0);
36 spdif_set_output_source(AUDIO_SRC_PLAYBACK, true);
37}
38
39/* Return the S/PDIF frequency in herz - unrounded */
40unsigned long spdif_measure_frequency(void)
41{
42 /* The following formula is specified in MCF5249 user's manual section
43 * 17.6.1. The 128 divide is because of the fact that the SPDIF clock is
44 * the sample rate times 128.
45 */
46 return (unsigned long)((unsigned long long)FREQMEAS*CPU_FREQ /
47 ((1 << 15)*3*(1 << 13))/128);
48} /* spdif_measure_frequency */
49
50/* Set the S/PDIF audio feed */
51void spdif_set_output_source(int source, bool src_on)
52{
53 static const unsigned short ebu1_config[] =
54 {
55 /* SCLK2, TXSRC = PDOR3, validity, normal operation */
56 [AUDIO_SRC_PLAYBACK+1] = (7 << 12) | (3 << 8) | (1 << 5) | (5 << 2),
57 /* Input source is EBUin1, Feed-through monitoring */
58 [AUDIO_SRC_SPDIF+1] = (1 << 2),
59 /* SCLK2, TXSRC = IIS1recv, validity, normal operation */
60 [AUDIO_SRC_MIC+1] = (7 << 12) | (4 << 8) | (1 << 5) | (5 << 2),
61 [AUDIO_SRC_LINEIN+1] = (7 << 12) | (4 << 8) | (1 << 5) | (5 << 2),
62 [AUDIO_SRC_FMRADIO+1] = (7 << 12) | (4 << 8) | (1 << 5) | (5 << 2),
63 };
64
65 if ((unsigned)source >= ARRAYLEN(ebu1_config))
66 source = AUDIO_SRC_PLAYBACK;
67
68 EBU1CONFIG = 0x800; /* Reset before reprogram */
69
70 spdif_source = source;
71 spdif_on = spdif_powered() && src_on;
72
73 /* Tranceiver must be powered or else monitoring will be disabled */
74 EBU1CONFIG = spdif_on ? ebu1_config[source + 1] : 0;
75} /* spdif_set_output_source */
76
77/* Return the last set S/PDIF audio source */
78int spdif_get_output_source(bool *src_on)
79{
80 if (src_on != NULL)
81 *src_on = spdif_on;
82 return spdif_source;
83} /* 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 @@
26#elif defined(HAVE_TLV320) 26#elif defined(HAVE_TLV320)
27#include "tlv320.h" 27#include "tlv320.h"
28#endif 28#endif
29#if defined(HAVE_SPDIF_IN) || defined(HAVE_SPDIF_OUT)
30#include "spdif.h"
31#endif
29 32
30/* Avoid further #ifdef's for some codec functions */ 33/* Avoid further #ifdef's for some codec functions */
31#if defined(HAVE_UDA1380) 34#if defined(HAVE_UDA1380)
@@ -69,10 +72,6 @@ static int rec_peak_left, rec_peak_right;
69#define IIS_CONFIG IIS2CONFIG 72#define IIS_CONFIG IIS2CONFIG
70#define PLLCR_SET_AUDIO_BITS_DEFPARM \ 73#define PLLCR_SET_AUDIO_BITS_DEFPARM \
71 ((freq_ent[FPARM_CLSEL] << 28) | (3 << 22)) 74 ((freq_ent[FPARM_CLSEL] << 28) | (3 << 22))
72
73#ifdef HAVE_SPDIF_OUT
74#define EBU_DEFPARM ((7 << 12) | (3 << 8) | (1 << 5) | (5 << 2))
75#endif
76#endif 75#endif
77 76
78/** Sample rates **/ 77/** Sample rates **/
@@ -229,11 +228,6 @@ void pcm_play_dma_start(const void *addr, size_t size)
229 228
230 pcm_playing = true; 229 pcm_playing = true;
231 230
232 /* Reset the audio FIFO */
233#ifdef HAVE_SPDIF_OUT
234 EBU1CONFIG = IIS_RESET | EBU_DEFPARM;
235#endif
236
237 /* Set up DMA transfer */ 231 /* Set up DMA transfer */
238 SAR0 = (unsigned long)addr; /* Source address */ 232 SAR0 = (unsigned long)addr; /* Source address */
239 DAR0 = (unsigned long)&PDOR3; /* Destination address */ 233 DAR0 = (unsigned long)&PDOR3; /* Destination address */
@@ -242,11 +236,6 @@ void pcm_play_dma_start(const void *addr, size_t size)
242 /* Enable the FIFO and force one write to it */ 236 /* Enable the FIFO and force one write to it */
243 pcm_apply_settings(false); 237 pcm_apply_settings(false);
244 238
245 /* Also send the audio to S/PDIF */
246#ifdef HAVE_SPDIF_OUT
247 EBU1CONFIG = EBU_DEFPARM;
248#endif
249
250 DCR0 = DMA_INT | DMA_EEXT | DMA_CS | DMA_AA | 239 DCR0 = DMA_INT | DMA_EEXT | DMA_CS | DMA_AA |
251 DMA_SINC | DMA_SSIZE(3) | DMA_START; 240 DMA_SINC | DMA_SSIZE(3) | DMA_START;
252} /* pcm_play_dma_start */ 241} /* pcm_play_dma_start */
@@ -263,10 +252,6 @@ void pcm_play_dma_stop(void)
263 252
264 /* Reset the FIFO */ 253 /* Reset the FIFO */
265 pcm_apply_settings(false); 254 pcm_apply_settings(false);
266
267#ifdef HAVE_SPDIF_OUT
268 EBU1CONFIG = IIS_RESET | EBU_DEFPARM;
269#endif
270} /* pcm_play_dma_stop */ 255} /* pcm_play_dma_stop */
271 256
272void pcm_init(void) 257void pcm_init(void)
@@ -291,6 +276,10 @@ void pcm_init(void)
291 /* Prevent pops (resets DAC to zero point) */ 276 /* Prevent pops (resets DAC to zero point) */
292 SET_IIS_CONFIG(IIS_DEFPARM | IIS_RESET); 277 SET_IIS_CONFIG(IIS_DEFPARM | IIS_RESET);
293 278
279#if defined(HAVE_SPDIF_IN) || defined(HAVE_SPDIF_OUT)
280 spdif_init();
281#endif
282
294 /* Initialize default register values. */ 283 /* Initialize default register values. */
295 ac_init(); 284 ac_init();
296 285
@@ -417,11 +406,6 @@ void pcm_init_recording(void)
417 DMACONFIG = 1; /* DMA0Req = PDOR3, DMA1Req = PDIR2 */ 406 DMACONFIG = 1; /* DMA0Req = PDOR3, DMA1Req = PDIR2 */
418 DMAROUTE = (DMAROUTE & 0xffff00ff) | DMA1_REQ_AUDIO_2; 407 DMAROUTE = (DMAROUTE & 0xffff00ff) | DMA1_REQ_AUDIO_2;
419 408
420#ifdef HAVE_SPDIF_IN
421 /* PHASECONFIG setup: gain = 3*2^13, source = EBUIN */
422 PHASECONFIG = (6 << 3) | (4 << 0);
423#endif
424
425 pcm_rec_dma_stop(); 409 pcm_rec_dma_stop();
426 410
427 ICR7 = (7 << 2); /* Enable interrupt at level 7, priority 0 */ 411 ICR7 = (7 << 2); /* Enable interrupt at level 7, priority 0 */
@@ -506,18 +490,12 @@ void pcm_play_pause_pause(void)
506 /* Disable DMA peripheral request. */ 490 /* Disable DMA peripheral request. */
507 DCR0 &= ~DMA_EEXT; 491 DCR0 &= ~DMA_EEXT;
508 pcm_apply_settings(true); 492 pcm_apply_settings(true);
509#ifdef HAVE_SPDIF_OUT
510 EBU1CONFIG = EBU_DEFPARM;
511#endif
512} /* pcm_play_pause_pause */ 493} /* pcm_play_pause_pause */
513 494
514void pcm_play_pause_unpause(void) 495void pcm_play_pause_unpause(void)
515{ 496{
516 /* Enable the FIFO and force one write to it */ 497 /* Enable the FIFO and force one write to it */
517 pcm_apply_settings(false); 498 pcm_apply_settings(false);
518#ifdef HAVE_SPDIF_OUT
519 EBU1CONFIG = EBU_DEFPARM;
520#endif
521 DCR0 |= DMA_EEXT | DMA_START; 499 DCR0 |= DMA_EEXT | DMA_START;
522} /* pcm_play_pause_unpause */ 500} /* pcm_play_pause_unpause */
523 501