diff options
Diffstat (limited to 'firmware')
-rw-r--r-- | firmware/export/pcm_playback.h | 2 | ||||
-rw-r--r-- | firmware/pcm_record.c | 6 | ||||
-rw-r--r-- | firmware/target/arm/gigabeat/meg-fx/pcm-meg-fx.c | 3 | ||||
-rw-r--r-- | firmware/target/coldfire/iaudio/m5/audio-m5.c | 7 | ||||
-rw-r--r-- | firmware/target/coldfire/iaudio/x5/audio-x5.c | 12 | ||||
-rw-r--r-- | firmware/target/coldfire/iriver/audio-iriver.c | 22 | ||||
-rw-r--r-- | firmware/target/coldfire/pcm-coldfire.c | 162 | ||||
-rw-r--r-- | firmware/target/coldfire/system-coldfire.c | 5 | ||||
-rw-r--r-- | firmware/target/coldfire/system-target.h | 3 |
9 files changed, 122 insertions, 100 deletions
diff --git a/firmware/export/pcm_playback.h b/firmware/export/pcm_playback.h index 80a1f557fe..28409c01d9 100644 --- a/firmware/export/pcm_playback.h +++ b/firmware/export/pcm_playback.h | |||
@@ -33,7 +33,7 @@ void pcm_init(void); | |||
33 | */ | 33 | */ |
34 | void pcm_set_frequency(unsigned int frequency); | 34 | void pcm_set_frequency(unsigned int frequency); |
35 | /* apply settings to hardware immediately */ | 35 | /* apply settings to hardware immediately */ |
36 | void pcm_apply_settings(bool reset); | 36 | void pcm_apply_settings(void); |
37 | 37 | ||
38 | /* This is for playing "raw" PCM data */ | 38 | /* This is for playing "raw" PCM data */ |
39 | void pcm_play_data(pcm_more_callback_type get_more, | 39 | void pcm_play_data(pcm_more_callback_type get_more, |
diff --git a/firmware/pcm_record.c b/firmware/pcm_record.c index 3f4abc7be3..f467b734c8 100644 --- a/firmware/pcm_record.c +++ b/firmware/pcm_record.c | |||
@@ -329,7 +329,7 @@ static void reset_hardware(void) | |||
329 | /* reset pcm to defaults (playback only) */ | 329 | /* reset pcm to defaults (playback only) */ |
330 | pcm_set_frequency(HW_SAMPR_DEFAULT); | 330 | pcm_set_frequency(HW_SAMPR_DEFAULT); |
331 | audio_set_output_source(AUDIO_SRC_PLAYBACK); | 331 | audio_set_output_source(AUDIO_SRC_PLAYBACK); |
332 | pcm_apply_settings(true); | 332 | pcm_apply_settings(); |
333 | } | 333 | } |
334 | 334 | ||
335 | /** pcm_rec_* group **/ | 335 | /** pcm_rec_* group **/ |
@@ -1326,8 +1326,8 @@ static void pcmrec_set_recording_options( | |||
1326 | /* set monitoring */ | 1326 | /* set monitoring */ |
1327 | audio_set_output_source(rec_source); | 1327 | audio_set_output_source(rec_source); |
1328 | 1328 | ||
1329 | /* apply pcm settings to hardware */ | 1329 | /* apply hardware setting to start monitoring now */ |
1330 | pcm_apply_settings(true); | 1330 | pcm_apply_settings(); |
1331 | 1331 | ||
1332 | queue_reply(&pcmrec_queue, 0); /* Release sender */ | 1332 | queue_reply(&pcmrec_queue, 0); /* Release sender */ |
1333 | 1333 | ||
diff --git a/firmware/target/arm/gigabeat/meg-fx/pcm-meg-fx.c b/firmware/target/arm/gigabeat/meg-fx/pcm-meg-fx.c index fcfe813ab7..7e1cebc555 100644 --- a/firmware/target/arm/gigabeat/meg-fx/pcm-meg-fx.c +++ b/firmware/target/arm/gigabeat/meg-fx/pcm-meg-fx.c | |||
@@ -282,9 +282,8 @@ size_t pcm_get_bytes_waiting(void) | |||
282 | 282 | ||
283 | 283 | ||
284 | /* dummy functions for those not actually supporting all this yet */ | 284 | /* dummy functions for those not actually supporting all this yet */ |
285 | void pcm_apply_settings(bool reset) | 285 | void pcm_apply_settings(void) |
286 | { | 286 | { |
287 | (void)reset; | ||
288 | } | 287 | } |
289 | 288 | ||
290 | void pcm_set_monitor(int monitor) | 289 | void pcm_set_monitor(int monitor) |
diff --git a/firmware/target/coldfire/iaudio/m5/audio-m5.c b/firmware/target/coldfire/iaudio/m5/audio-m5.c index fcedbcad78..9531f932ad 100644 --- a/firmware/target/coldfire/iaudio/m5/audio-m5.c +++ b/firmware/target/coldfire/iaudio/m5/audio-m5.c | |||
@@ -49,8 +49,7 @@ void audio_set_source(int source, unsigned flags) | |||
49 | { | 49 | { |
50 | audiohw_disable_recording(); | 50 | audiohw_disable_recording(); |
51 | audiohw_set_monitor(false); | 51 | audiohw_set_monitor(false); |
52 | /* Reset PDIR2 data flow */ | 52 | coldfire_set_dataincontrol(0); |
53 | DATAINCONTROL = (1 << 9); | ||
54 | } | 53 | } |
55 | break; | 54 | break; |
56 | 55 | ||
@@ -59,7 +58,7 @@ void audio_set_source(int source, unsigned flags) | |||
59 | { | 58 | { |
60 | audiohw_enable_recording(true); /* source mic */ | 59 | audiohw_enable_recording(true); /* source mic */ |
61 | /* Int. when 6 samples in FIFO, PDIR2 src = iis1RcvData */ | 60 | /* Int. when 6 samples in FIFO, PDIR2 src = iis1RcvData */ |
62 | DATAINCONTROL = (3 << 14) | (4 << 3); | 61 | coldfire_set_dataincontrol((3 << 14) | (4 << 3)); |
63 | } | 62 | } |
64 | break; | 63 | break; |
65 | 64 | ||
@@ -68,7 +67,7 @@ void audio_set_source(int source, unsigned flags) | |||
68 | { | 67 | { |
69 | audiohw_enable_recording(false); /* source line */ | 68 | audiohw_enable_recording(false); /* source line */ |
70 | /* Int. when 6 samples in FIFO, PDIR2 src = iis1RcvData */ | 69 | /* Int. when 6 samples in FIFO, PDIR2 src = iis1RcvData */ |
71 | DATAINCONTROL = (3 << 14) | (4 << 3); | 70 | coldfire_set_dataincontrol((3 << 14) | (4 << 3)); |
72 | } | 71 | } |
73 | break; | 72 | break; |
74 | } /* end switch */ | 73 | } /* end switch */ |
diff --git a/firmware/target/coldfire/iaudio/x5/audio-x5.c b/firmware/target/coldfire/iaudio/x5/audio-x5.c index 23aaa42cd6..e673d4ad47 100644 --- a/firmware/target/coldfire/iaudio/x5/audio-x5.c +++ b/firmware/target/coldfire/iaudio/x5/audio-x5.c | |||
@@ -50,8 +50,7 @@ void audio_set_source(int source, unsigned flags) | |||
50 | { | 50 | { |
51 | audiohw_disable_recording(); | 51 | audiohw_disable_recording(); |
52 | audiohw_set_monitor(false); | 52 | audiohw_set_monitor(false); |
53 | /* Reset PDIR2 data flow */ | 53 | coldfire_set_dataincontrol(0); |
54 | DATAINCONTROL = (1 << 9); | ||
55 | } | 54 | } |
56 | break; | 55 | break; |
57 | 56 | ||
@@ -60,7 +59,7 @@ void audio_set_source(int source, unsigned flags) | |||
60 | { | 59 | { |
61 | audiohw_enable_recording(true); /* source mic */ | 60 | audiohw_enable_recording(true); /* source mic */ |
62 | /* Int. when 6 samples in FIFO, PDIR2 src = iis1RcvData */ | 61 | /* Int. when 6 samples in FIFO, PDIR2 src = iis1RcvData */ |
63 | DATAINCONTROL = (3 << 14) | (4 << 3); | 62 | coldfire_set_dataincontrol((3 << 14) | (4 << 3)); |
64 | } | 63 | } |
65 | break; | 64 | break; |
66 | 65 | ||
@@ -69,7 +68,7 @@ void audio_set_source(int source, unsigned flags) | |||
69 | { | 68 | { |
70 | audiohw_enable_recording(false); /* source line */ | 69 | audiohw_enable_recording(false); /* source line */ |
71 | /* Int. when 6 samples in FIFO, PDIR2 src = iis1RcvData */ | 70 | /* Int. when 6 samples in FIFO, PDIR2 src = iis1RcvData */ |
72 | DATAINCONTROL = (3 << 14) | (4 << 3); | 71 | coldfire_set_dataincontrol((3 << 14) | (4 << 3)); |
73 | } | 72 | } |
74 | break; | 73 | break; |
75 | 74 | ||
@@ -86,15 +85,14 @@ void audio_set_source(int source, unsigned flags) | |||
86 | if (recording) | 85 | if (recording) |
87 | { | 86 | { |
88 | /* Int. when 6 samples in FIFO, PDIR2 src = iis1RcvData */ | 87 | /* Int. when 6 samples in FIFO, PDIR2 src = iis1RcvData */ |
89 | DATAINCONTROL = (3 << 14) | (4 << 3); | 88 | coldfire_set_dataincontrol((3 << 14) | (4 << 3)); |
90 | audiohw_enable_recording(false); /* source line */ | 89 | audiohw_enable_recording(false); /* source line */ |
91 | } | 90 | } |
92 | else | 91 | else |
93 | { | 92 | { |
94 | audiohw_disable_recording(); | 93 | audiohw_disable_recording(); |
95 | audiohw_set_monitor(true); /* analog bypass */ | 94 | audiohw_set_monitor(true); /* analog bypass */ |
96 | /* Reset PDIR2 data flow */ | 95 | coldfire_set_dataincontrol(0); |
97 | DATAINCONTROL = (1 << 9); | ||
98 | } | 96 | } |
99 | break; | 97 | break; |
100 | } /* end switch */ | 98 | } /* end switch */ |
diff --git a/firmware/target/coldfire/iriver/audio-iriver.c b/firmware/target/coldfire/iriver/audio-iriver.c index 751025d08a..2df7a216a9 100644 --- a/firmware/target/coldfire/iriver/audio-iriver.c +++ b/firmware/target/coldfire/iriver/audio-iriver.c | |||
@@ -56,8 +56,7 @@ void audio_set_source(int source, unsigned flags) | |||
56 | { | 56 | { |
57 | audiohw_disable_recording(); | 57 | audiohw_disable_recording(); |
58 | audiohw_set_monitor(false); | 58 | audiohw_set_monitor(false); |
59 | /* Reset PDIR2 data flow */ | 59 | coldfire_set_dataincontrol(0); |
60 | DATAINCONTROL = (1 << 9); | ||
61 | } | 60 | } |
62 | break; | 61 | break; |
63 | 62 | ||
@@ -67,7 +66,7 @@ void audio_set_source(int source, unsigned flags) | |||
67 | audiohw_enable_recording(true); /* source mic */ | 66 | audiohw_enable_recording(true); /* source mic */ |
68 | audiohw_set_monitor(false); | 67 | audiohw_set_monitor(false); |
69 | /* Int. when 6 samples in FIFO, PDIR2 src = iis1RcvData */ | 68 | /* Int. when 6 samples in FIFO, PDIR2 src = iis1RcvData */ |
70 | DATAINCONTROL = (3 << 14) | (4 << 3); | 69 | coldfire_set_dataincontrol((3 << 14) | (4 << 3)); |
71 | } | 70 | } |
72 | break; | 71 | break; |
73 | 72 | ||
@@ -77,7 +76,7 @@ void audio_set_source(int source, unsigned flags) | |||
77 | audiohw_enable_recording(false); /* source line */ | 76 | audiohw_enable_recording(false); /* source line */ |
78 | audiohw_set_monitor(false); | 77 | audiohw_set_monitor(false); |
79 | /* Int. when 6 samples in FIFO, PDIR2 src = iis1RcvData */ | 78 | /* Int. when 6 samples in FIFO, PDIR2 src = iis1RcvData */ |
80 | DATAINCONTROL = (3 << 14) | (4 << 3); | 79 | coldfire_set_dataincontrol((3 << 14) | (4 << 3)); |
81 | } | 80 | } |
82 | break; | 81 | break; |
83 | 82 | ||
@@ -88,7 +87,7 @@ void audio_set_source(int source, unsigned flags) | |||
88 | audiohw_disable_recording(); | 87 | audiohw_disable_recording(); |
89 | audiohw_set_monitor(false); | 88 | audiohw_set_monitor(false); |
90 | /* Int. when 6 samples in FIFO, PDIR2 src = ebu1RcvData */ | 89 | /* Int. when 6 samples in FIFO, PDIR2 src = ebu1RcvData */ |
91 | DATAINCONTROL = (3 << 14) | (7 << 3); | 90 | coldfire_set_dataincontrol((3 << 14) | (7 << 3)); |
92 | } | 91 | } |
93 | break; | 92 | break; |
94 | #endif /* HAVE_SPDIF_IN */ | 93 | #endif /* HAVE_SPDIF_IN */ |
@@ -102,16 +101,9 @@ void audio_set_source(int source, unsigned flags) | |||
102 | 101 | ||
103 | last_recording = recording; | 102 | last_recording = recording; |
104 | 103 | ||
105 | if (recording) | 104 | /* Int. when 6 samples in FIFO, PDIR2 src = iis1RcvData */ |
106 | { | 105 | coldfire_set_dataincontrol(recording ? |
107 | /* Int. when 6 samples in FIFO, PDIR2 src = iis1RcvData */ | 106 | ((3 << 14) | (4 << 3)) : 0); |
108 | DATAINCONTROL = (3 << 14) | (4 << 3); | ||
109 | } | ||
110 | else | ||
111 | { | ||
112 | /* Reset PDIR2 data flow */ | ||
113 | DATAINCONTROL = (1 << 9); | ||
114 | } | ||
115 | 107 | ||
116 | /* I2S recording and playback */ | 108 | /* I2S recording and playback */ |
117 | audiohw_enable_recording(false); /* source line */ | 109 | audiohw_enable_recording(false); /* source line */ |
diff --git a/firmware/target/coldfire/pcm-coldfire.c b/firmware/target/coldfire/pcm-coldfire.c index 8738316aa9..2addcb9da8 100644 --- a/firmware/target/coldfire/pcm-coldfire.c +++ b/firmware/target/coldfire/pcm-coldfire.c | |||
@@ -41,23 +41,23 @@ enum | |||
41 | }; | 41 | }; |
42 | static int peaks[4]; /* p-l, p-r, r-l, r-r */ | 42 | static int peaks[4]; /* p-l, p-r, r-l, r-r */ |
43 | 43 | ||
44 | #define IIS_DEFPARM(output) ( (freq_ent[FPARM_CLOCKSEL] << 12) | \ | 44 | #define IIS_PLAY_DEFPARM ( (freq_ent[FPARM_CLOCKSEL] << 12) | \ |
45 | (output) | \ | 45 | (IIS_PLAY & (7 << 8)) | \ |
46 | (4 << 2) ) /* 64 bit clocks / word clock */ | 46 | (4 << 2) ) /* 64 bit clocks / word clock */ |
47 | #define IIS_RESET 0x800 | 47 | #define IIS_FIFO_RESET (1 << 11) |
48 | #define PDIR2_FIFO_RESET (1 << 9) | ||
48 | 49 | ||
49 | #if defined(IAUDIO_X5) || defined(IAUDIO_M5) | 50 | #if defined(IAUDIO_X5) || defined(IAUDIO_M5) |
50 | #define SET_IIS_CONFIG(x) IIS1CONFIG = (x); | 51 | #define SET_IIS_PLAY(x) IIS1CONFIG = (x) |
51 | #define IIS_CONFIG IIS1CONFIG | 52 | #define IIS_PLAY IIS1CONFIG |
52 | #define PLLCR_SET_AUDIO_BITS_DEFPARM \ | ||
53 | ((freq_ent[FPARM_CLSEL] << 28) | (1 << 22)) | ||
54 | #else | 53 | #else |
55 | #define SET_IIS_CONFIG(x) IIS2CONFIG = (x); | 54 | #define SET_IIS_PLAY(x) IIS2CONFIG = (x) |
56 | #define IIS_CONFIG IIS2CONFIG | 55 | #define IIS_PLAY IIS2CONFIG |
57 | #define PLLCR_SET_AUDIO_BITS_DEFPARM \ | ||
58 | ((freq_ent[FPARM_CLSEL] << 28) | (3 << 22)) | ||
59 | #endif | 56 | #endif |
60 | 57 | ||
58 | #define PLLCR_SET_AUDIO_BITS_DEFPARM \ | ||
59 | ((freq_ent[FPARM_CLSEL] << 28) | (1 << 22)) | ||
60 | |||
61 | /** Sample rates **/ | 61 | /** Sample rates **/ |
62 | #define FPARM_CLOCKSEL 0 | 62 | #define FPARM_CLOCKSEL 0 |
63 | #define FPARM_CLSEL 1 | 63 | #define FPARM_CLSEL 1 |
@@ -113,29 +113,31 @@ void pcm_set_frequency(unsigned int frequency) | |||
113 | } /* pcm_set_frequency */ | 113 | } /* pcm_set_frequency */ |
114 | 114 | ||
115 | /* apply audio settings */ | 115 | /* apply audio settings */ |
116 | void pcm_apply_settings(bool reset) | 116 | void _pcm_apply_settings(bool clear_reset) |
117 | { | 117 | { |
118 | static int last_pcm_freq = HW_SAMPR_DEFAULT; | 118 | static int last_pcm_freq = 0; |
119 | unsigned long output = IIS_CONFIG & (7 << 8); | 119 | |
120 | |||
121 | /* Playback must prevent pops and record monitoring won't work at all if | ||
122 | adding IIS_RESET when setting IIS_CONFIG. Use a different method for | ||
123 | each. */ | ||
124 | if (reset && output != (3 << 8)) | ||
125 | { | ||
126 | /* Not playback - reset first */ | ||
127 | SET_IIS_CONFIG(IIS_RESET); | ||
128 | reset = false; | ||
129 | } | ||
130 | |||
131 | if (pcm_freq != last_pcm_freq) | 120 | if (pcm_freq != last_pcm_freq) |
132 | { | 121 | { |
133 | last_pcm_freq = pcm_freq; | 122 | last_pcm_freq = pcm_freq; |
123 | /* Reprogramming bits 15-12 requires FIFO to be in a reset | ||
124 | condition - Users Manual 17-8, Note 11 */ | ||
125 | or_l(IIS_FIFO_RESET, &IIS_PLAY); | ||
134 | audiohw_set_frequency(freq_ent[FPARM_FSEL]); | 126 | audiohw_set_frequency(freq_ent[FPARM_FSEL]); |
135 | coldfire_set_pllcr_audio_bits(PLLCR_SET_AUDIO_BITS_DEFPARM); | 127 | coldfire_set_pllcr_audio_bits(PLLCR_SET_AUDIO_BITS_DEFPARM); |
136 | } | 128 | } |
137 | 129 | ||
138 | SET_IIS_CONFIG(IIS_DEFPARM(output) | (reset ? IIS_RESET : 0)); | 130 | SET_IIS_PLAY(IIS_PLAY_DEFPARM | |
131 | (clear_reset ? 0 : (IIS_PLAY & IIS_FIFO_RESET))); | ||
132 | #if 0 | ||
133 | logf("IISPLAY: %08X", IIS_PLAY); | ||
134 | #endif | ||
135 | } /* _pcm_apply_settings */ | ||
136 | |||
137 | /* This clears the reset bit to enable monitoring immediately */ | ||
138 | void pcm_apply_settings(void) | ||
139 | { | ||
140 | _pcm_apply_settings(true); | ||
139 | } /* pcm_apply_settings */ | 141 | } /* pcm_apply_settings */ |
140 | 142 | ||
141 | /** DMA **/ | 143 | /** DMA **/ |
@@ -157,27 +159,31 @@ void pcm_play_dma_start(const void *addr, size_t size) | |||
157 | /* Set up DMA transfer */ | 159 | /* Set up DMA transfer */ |
158 | SAR0 = (unsigned long)addr; /* Source address */ | 160 | SAR0 = (unsigned long)addr; /* Source address */ |
159 | DAR0 = (unsigned long)&PDOR3; /* Destination address */ | 161 | DAR0 = (unsigned long)&PDOR3; /* Destination address */ |
160 | BCR0 = size; /* Bytes to transfer */ | 162 | BCR0 = (unsigned long)size; /* Bytes to transfer */ |
161 | 163 | ||
162 | /* Enable the FIFO and force one write to it */ | 164 | /* Enable the FIFO and force one write to it */ |
163 | pcm_apply_settings(false); | 165 | pcm_apply_settings(); |
164 | 166 | ||
165 | DCR0 = DMA_INT | DMA_EEXT | DMA_CS | DMA_AA | | 167 | DCR0 = DMA_INT | DMA_EEXT | DMA_CS | DMA_AA | |
166 | DMA_SINC | DMA_SSIZE(3) | DMA_START; | 168 | DMA_SINC | DMA_SSIZE(DMA_SIZE_LINE) | DMA_START; |
167 | } /* pcm_play_dma_start */ | 169 | } /* pcm_play_dma_start */ |
168 | 170 | ||
169 | /* Stops the DMA transfer and interrupt */ | 171 | /* Stops the DMA transfer and interrupt */ |
170 | void pcm_play_dma_stop(void) | 172 | void pcm_play_dma_stop(void) |
171 | { | 173 | { |
174 | #if 0 | ||
172 | logf("pcm_play_dma_stop"); | 175 | logf("pcm_play_dma_stop"); |
176 | #endif | ||
173 | 177 | ||
174 | pcm_playing = false; | 178 | pcm_playing = false; |
175 | 179 | ||
176 | DCR0 = 0; | ||
177 | DSR0 = 1; | 180 | DSR0 = 1; |
181 | DCR0 = 0; | ||
178 | 182 | ||
179 | /* Reset the FIFO */ | 183 | /* Place FIFO in reset condition */ |
180 | pcm_apply_settings(false); | 184 | or_l(IIS_FIFO_RESET, &IIS_PLAY); |
185 | |||
186 | pcm_playing = false; | ||
181 | } /* pcm_play_dma_stop */ | 187 | } /* pcm_play_dma_stop */ |
182 | 188 | ||
183 | void pcm_init(void) | 189 | void pcm_init(void) |
@@ -188,17 +194,26 @@ void pcm_init(void) | |||
188 | pcm_paused = false; | 194 | pcm_paused = false; |
189 | pcm_callback_for_more = NULL; | 195 | pcm_callback_for_more = NULL; |
190 | 196 | ||
197 | AUDIOGLOB = (1 << 8) /* IIS1 fifo auto sync */ | ||
198 | | (1 << 7) /* PDIR2 fifo auto sync */ | ||
199 | #ifdef HAVE_SPDIF_OUT | ||
200 | | (1 << 10) /* EBU TX auto sync */ | ||
201 | #endif | ||
202 | ; | ||
191 | DIVR0 = 54; /* DMA0 is mapped into vector 54 in system.c */ | 203 | DIVR0 = 54; /* DMA0 is mapped into vector 54 in system.c */ |
192 | DMAROUTE = (DMAROUTE & 0xffffff00) | DMA0_REQ_AUDIO_1; | 204 | and_l(0xffffff00, &DMAROUTE); |
205 | or_l(DMA0_REQ_AUDIO_1, &DMAROUTE); | ||
193 | DMACONFIG = 1; /* DMA0Req = PDOR3, DMA1Req = PDIR2 */ | 206 | DMACONFIG = 1; /* DMA0Req = PDOR3, DMA1Req = PDIR2 */ |
194 | 207 | ||
195 | /* Reset the audio FIFO */ | 208 | /* Call pcm_play_dma_stop to initialize everything. */ |
196 | SET_IIS_CONFIG(IIS_RESET); | 209 | pcm_play_dma_stop(); |
197 | 210 | /* Call pcm_close_recording to put in closed state */ | |
211 | pcm_close_recording(); | ||
212 | audio_set_output_source(AUDIO_SRC_PLAYBACK); | ||
213 | audio_set_source(AUDIO_SRC_PLAYBACK, SRCF_PLAYBACK); | ||
198 | pcm_set_frequency(HW_FREQ_DEFAULT); | 214 | pcm_set_frequency(HW_FREQ_DEFAULT); |
199 | 215 | ||
200 | /* Prevent pops (resets DAC to zero point) */ | 216 | _pcm_apply_settings(false); |
201 | SET_IIS_CONFIG(IIS_DEFPARM(3 << 8) | IIS_RESET); | ||
202 | 217 | ||
203 | #if defined(HAVE_SPDIF_IN) || defined(HAVE_SPDIF_OUT) | 218 | #if defined(HAVE_SPDIF_IN) || defined(HAVE_SPDIF_OUT) |
204 | spdif_init(); | 219 | spdif_init(); |
@@ -221,12 +236,9 @@ void pcm_init(void) | |||
221 | (DAC should be at zero point now). */ | 236 | (DAC should be at zero point now). */ |
222 | audiohw_mute(false); | 237 | audiohw_mute(false); |
223 | 238 | ||
224 | /* Call pcm_play_dma_stop to initialize everything. */ | ||
225 | pcm_play_dma_stop(); | ||
226 | |||
227 | /* Enable interrupt at level 7, priority 0 */ | 239 | /* Enable interrupt at level 7, priority 0 */ |
228 | ICR6 = (7 << 2); | 240 | ICR6 = (7 << 2); |
229 | IMR &= ~(1 << 14); /* bit 14 is DMA0 */ | 241 | and_l(~(1 << 14), &IMR); /* bit 14 is DMA0 */ |
230 | } /* pcm_init */ | 242 | } /* pcm_init */ |
231 | 243 | ||
232 | size_t pcm_get_bytes_waiting(void) | 244 | size_t pcm_get_bytes_waiting(void) |
@@ -241,9 +253,8 @@ void DMA0(void) | |||
241 | { | 253 | { |
242 | int res = DSR0; | 254 | int res = DSR0; |
243 | 255 | ||
244 | DSR0 = 1; /* Clear interrupt */ | 256 | DSR0 = 1; /* Clear interrupt */ |
245 | DCR0 &= ~DMA_EEXT; | 257 | and_l(~DMA_EEXT, &DCR0); /* Disable peripheral request */ |
246 | |||
247 | /* Stop on error */ | 258 | /* Stop on error */ |
248 | if ((res & 0x70) == 0) | 259 | if ((res & 0x70) == 0) |
249 | { | 260 | { |
@@ -258,7 +269,7 @@ void DMA0(void) | |||
258 | { | 269 | { |
259 | SAR0 = (unsigned long)next_start; /* Source address */ | 270 | SAR0 = (unsigned long)next_start; /* Source address */ |
260 | BCR0 = next_size; /* Bytes to transfer */ | 271 | BCR0 = next_size; /* Bytes to transfer */ |
261 | DCR0 |= DMA_EEXT; | 272 | or_l(DMA_EEXT, &DCR0); /* Enable peripheral request */ |
262 | return; | 273 | return; |
263 | } | 274 | } |
264 | else | 275 | else |
@@ -272,7 +283,13 @@ void DMA0(void) | |||
272 | } | 283 | } |
273 | else | 284 | else |
274 | { | 285 | { |
275 | logf("DMA Error:0x%04x", res); | 286 | logf("DMA0 err: %02x", res); |
287 | #if 0 | ||
288 | logf(" SAR0: %08x", SAR0); | ||
289 | logf(" DAR0: %08x", DAR0); | ||
290 | logf(" BCR0: %08x", BCR0); | ||
291 | logf(" DCR0: %08x", DCR0); | ||
292 | #endif | ||
276 | } | 293 | } |
277 | 294 | ||
278 | pcm_play_dma_stop(); | 295 | pcm_play_dma_stop(); |
@@ -290,7 +307,10 @@ void pcm_rec_dma_start(void *addr, size_t size) | |||
290 | 307 | ||
291 | pcm_recording = true; | 308 | pcm_recording = true; |
292 | 309 | ||
293 | pcm_apply_settings(false); | 310 | and_l(~PDIR2_FIFO_RESET, &DATAINCONTROL); |
311 | /* Clear reset bit if the source is not set to monitor playback | ||
312 | otherwise maintain independence between playback and recording. */ | ||
313 | _pcm_apply_settings((IIS_PLAY & (7 << 8)) != (3 << 8)); | ||
294 | 314 | ||
295 | /* Start the DMA transfer.. */ | 315 | /* Start the DMA transfer.. */ |
296 | #ifdef HAVE_SPDIF_IN | 316 | #ifdef HAVE_SPDIF_IN |
@@ -303,7 +323,7 @@ void pcm_rec_dma_start(void *addr, size_t size) | |||
303 | BCR1 = (unsigned long)size; /* Bytes to transfer */ | 323 | BCR1 = (unsigned long)size; /* Bytes to transfer */ |
304 | 324 | ||
305 | DCR1 = DMA_INT | DMA_EEXT | DMA_CS | DMA_AA | DMA_DINC | | 325 | DCR1 = DMA_INT | DMA_EEXT | DMA_CS | DMA_AA | DMA_DINC | |
306 | DMA_DSIZE(3) | DMA_START; | 326 | DMA_DSIZE(DMA_SIZE_LINE) /* | DMA_START */; |
307 | } /* pcm_dma_start */ | 327 | } /* pcm_dma_start */ |
308 | 328 | ||
309 | void pcm_rec_dma_stop(void) | 329 | void pcm_rec_dma_stop(void) |
@@ -314,6 +334,7 @@ void pcm_rec_dma_stop(void) | |||
314 | DCR1 = 0; | 334 | DCR1 = 0; |
315 | 335 | ||
316 | pcm_recording = false; | 336 | pcm_recording = false; |
337 | or_l(PDIR2_FIFO_RESET, &DATAINCONTROL); | ||
317 | } /* pcm_dma_stop */ | 338 | } /* pcm_dma_stop */ |
318 | 339 | ||
319 | void pcm_init_recording(void) | 340 | void pcm_init_recording(void) |
@@ -323,16 +344,15 @@ void pcm_init_recording(void) | |||
323 | pcm_recording = false; | 344 | pcm_recording = false; |
324 | pcm_callback_more_ready = NULL; | 345 | pcm_callback_more_ready = NULL; |
325 | 346 | ||
326 | AUDIOGLOB |= 0x180; /* IIS1 fifo auto sync = on, PDIR2 auto sync = on */ | 347 | DIVR1 = 55; /* DMA1 is mapped into vector 55 in system.c */ |
327 | 348 | DMACONFIG = 1; /* DMA0Req = PDOR3, DMA1Req = PDIR2 */ | |
328 | DIVR1 = 55; /* DMA1 is mapped into vector 55 in system.c */ | 349 | and_l(0xffff00ff, &DMAROUTE); |
329 | DMACONFIG = 1; /* DMA0Req = PDOR3, DMA1Req = PDIR2 */ | 350 | or_l(DMA1_REQ_AUDIO_2, &DMAROUTE); |
330 | DMAROUTE = (DMAROUTE & 0xffff00ff) | DMA1_REQ_AUDIO_2; | ||
331 | 351 | ||
332 | pcm_rec_dma_stop(); | 352 | pcm_rec_dma_stop(); |
333 | 353 | ||
334 | ICR7 = (7 << 2); /* Enable interrupt at level 7, priority 0 */ | 354 | ICR7 = (7 << 2); /* Enable interrupt at level 7, priority 0 */ |
335 | IMR &= ~(1 << 15); /* bit 15 is DMA1 */ | 355 | and_l(~(1 << 15), &IMR); /* bit 15 is DMA1 */ |
336 | } /* pcm_init_recording */ | 356 | } /* pcm_init_recording */ |
337 | 357 | ||
338 | void pcm_close_recording(void) | 358 | void pcm_close_recording(void) |
@@ -341,9 +361,9 @@ void pcm_close_recording(void) | |||
341 | 361 | ||
342 | pcm_rec_dma_stop(); | 362 | pcm_rec_dma_stop(); |
343 | 363 | ||
344 | DMAROUTE &= 0xffff00ff; | 364 | and_l(0xffff00ff, &DMAROUTE); |
345 | ICR7 = 0x00; /* Disable interrupt */ | 365 | ICR7 = 0x00; /* Disable interrupt */ |
346 | IMR |= (1 << 15); /* bit 15 is DMA1 */ | 366 | or_l((1 << 15), &IMR); /* bit 15 is DMA1 */ |
347 | } /* pcm_close_recording */ | 367 | } /* pcm_close_recording */ |
348 | 368 | ||
349 | /* DMA1 Interrupt is called when the DMA has finished transfering a chunk | 369 | /* DMA1 Interrupt is called when the DMA has finished transfering a chunk |
@@ -355,13 +375,19 @@ void DMA1(void) | |||
355 | int status = 0; | 375 | int status = 0; |
356 | pcm_more_callback_type2 more_ready; | 376 | pcm_more_callback_type2 more_ready; |
357 | 377 | ||
358 | DSR1 = 1; /* Clear interrupt */ | 378 | DSR1 = 1; /* Clear interrupt */ |
359 | DCR1 &= ~DMA_EEXT; /* Disable peripheral request */ | 379 | and_l(~DMA_EEXT, &DCR1); /* Disable peripheral request */ |
360 | 380 | ||
361 | if (res & 0x70) | 381 | if (res & 0x70) |
362 | { | 382 | { |
363 | status = DMA_REC_ERROR_DMA; | 383 | status = DMA_REC_ERROR_DMA; |
364 | logf("DMA1 err: 0x%x", res); | 384 | logf("DMA1 err: %02x", res); |
385 | #if 0 | ||
386 | logf(" SAR1: %08x", SAR1); | ||
387 | logf(" DAR1: %08x", DAR1); | ||
388 | logf(" BCR1: %08x", BCR1); | ||
389 | logf(" DCR1: %08x", DCR1); | ||
390 | #endif | ||
365 | } | 391 | } |
366 | #ifdef HAVE_SPDIF_IN | 392 | #ifdef HAVE_SPDIF_IN |
367 | else if (DATAINCONTROL == 0xc038 && | 393 | else if (DATAINCONTROL == 0xc038 && |
@@ -392,7 +418,7 @@ void pcm_record_more(void *start, size_t size) | |||
392 | rec_peak_addr = (unsigned long *)start; /* Start peaking at dest */ | 418 | rec_peak_addr = (unsigned long *)start; /* Start peaking at dest */ |
393 | DAR1 = (unsigned long)start; /* Destination address */ | 419 | DAR1 = (unsigned long)start; /* Destination address */ |
394 | BCR1 = (unsigned long)size; /* Bytes to transfer */ | 420 | BCR1 = (unsigned long)size; /* Bytes to transfer */ |
395 | DCR1 |= DMA_EEXT; | 421 | or_l(DMA_EEXT, &DCR1); /* Enable peripheral request */ |
396 | } | 422 | } |
397 | 423 | ||
398 | void pcm_mute(bool mute) | 424 | void pcm_mute(bool mute) |
@@ -405,15 +431,15 @@ void pcm_mute(bool mute) | |||
405 | void pcm_play_pause_pause(void) | 431 | void pcm_play_pause_pause(void) |
406 | { | 432 | { |
407 | /* Disable DMA peripheral request. */ | 433 | /* Disable DMA peripheral request. */ |
408 | DCR0 &= ~DMA_EEXT; | 434 | and_l(~DMA_EEXT, &DCR0); |
409 | pcm_apply_settings(true); | 435 | or_l(IIS_FIFO_RESET, &IIS_PLAY); |
410 | } /* pcm_play_pause_pause */ | 436 | } /* pcm_play_pause_pause */ |
411 | 437 | ||
412 | void pcm_play_pause_unpause(void) | 438 | void pcm_play_pause_unpause(void) |
413 | { | 439 | { |
414 | /* Enable the FIFO and force one write to it */ | 440 | /* Enable the FIFO and force one write to it */ |
415 | pcm_apply_settings(false); | 441 | pcm_apply_settings(); |
416 | DCR0 |= DMA_EEXT | DMA_START; | 442 | or_l(DMA_EEXT | DMA_START, &DCR0); |
417 | } /* pcm_play_pause_unpause */ | 443 | } /* pcm_play_pause_unpause */ |
418 | 444 | ||
419 | /** | 445 | /** |
diff --git a/firmware/target/coldfire/system-coldfire.c b/firmware/target/coldfire/system-coldfire.c index bc769877ba..251c97fb73 100644 --- a/firmware/target/coldfire/system-coldfire.c +++ b/firmware/target/coldfire/system-coldfire.c | |||
@@ -321,3 +321,8 @@ void coldfire_set_pllcr_audio_bits(long bits) | |||
321 | PLLCR = (PLLCR & ~0x70400000) | (bits & 0x70400000); | 321 | PLLCR = (PLLCR & ~0x70400000) | (bits & 0x70400000); |
322 | } | 322 | } |
323 | 323 | ||
324 | /* Set DATAINCONTROL without disturbing FIFO reset state */ | ||
325 | void coldfire_set_dataincontrol(unsigned long value) | ||
326 | { | ||
327 | DATAINCONTROL = (DATAINCONTROL & (1 << 9)) | value; | ||
328 | } | ||
diff --git a/firmware/target/coldfire/system-target.h b/firmware/target/coldfire/system-target.h index d02f835540..31947a2883 100644 --- a/firmware/target/coldfire/system-target.h +++ b/firmware/target/coldfire/system-target.h | |||
@@ -143,6 +143,9 @@ static inline void invalidate_icache(void) | |||
143 | #define DEFAULT_PLLCR_AUDIO_BITS 0x10400000 | 143 | #define DEFAULT_PLLCR_AUDIO_BITS 0x10400000 |
144 | void coldfire_set_pllcr_audio_bits(long bits); | 144 | void coldfire_set_pllcr_audio_bits(long bits); |
145 | 145 | ||
146 | /* Set DATAINCONTROL without disturbing FIFO reset state */ | ||
147 | void coldfire_set_dataincontrol(unsigned long value); | ||
148 | |||
146 | /* 11.2896 MHz */ | 149 | /* 11.2896 MHz */ |
147 | #define CPUFREQ_DEFAULT_MULT 1 | 150 | #define CPUFREQ_DEFAULT_MULT 1 |
148 | #define CPUFREQ_DEFAULT (CPUFREQ_DEFAULT_MULT * CPU_FREQ) | 151 | #define CPUFREQ_DEFAULT (CPUFREQ_DEFAULT_MULT * CPU_FREQ) |