summaryrefslogtreecommitdiff
path: root/firmware
diff options
context:
space:
mode:
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
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