diff options
Diffstat (limited to 'firmware/target/coldfire/pcm-coldfire.c')
-rw-r--r-- | firmware/target/coldfire/pcm-coldfire.c | 101 |
1 files changed, 37 insertions, 64 deletions
diff --git a/firmware/target/coldfire/pcm-coldfire.c b/firmware/target/coldfire/pcm-coldfire.c index 35b3ecae9c..914947a98e 100644 --- a/firmware/target/coldfire/pcm-coldfire.c +++ b/firmware/target/coldfire/pcm-coldfire.c | |||
@@ -69,66 +69,43 @@ static void iis_play_reset_if_playback(bool if_playback) | |||
69 | /** Sample rates **/ | 69 | /** Sample rates **/ |
70 | #define FPARM_CLOCKSEL 0 | 70 | #define FPARM_CLOCKSEL 0 |
71 | #define FPARM_CLSEL 1 | 71 | #define FPARM_CLSEL 1 |
72 | #define FPARM_FSEL 2 | ||
73 | #if CONFIG_CPU == MCF5249 && defined(HAVE_UDA1380) | 72 | #if CONFIG_CPU == MCF5249 && defined(HAVE_UDA1380) |
74 | static const unsigned char pcm_freq_parms[HW_NUM_FREQ][3] = | 73 | static const unsigned char pcm_freq_parms[HW_NUM_FREQ][2] = |
75 | { | 74 | { |
76 | [HW_FREQ_88] = { 0x0c, 0x01, 0x03 }, | 75 | [HW_FREQ_88] = { 0x0c, 0x01 }, |
77 | [HW_FREQ_44] = { 0x06, 0x01, 0x02 }, | 76 | [HW_FREQ_44] = { 0x06, 0x01 }, |
78 | [HW_FREQ_22] = { 0x04, 0x02, 0x01 }, | 77 | [HW_FREQ_22] = { 0x04, 0x02 }, |
79 | [HW_FREQ_11] = { 0x02, 0x02, 0x00 }, | 78 | [HW_FREQ_11] = { 0x02, 0x02 }, |
80 | }; | 79 | }; |
81 | #endif | 80 | #endif |
82 | 81 | ||
83 | #if (CONFIG_CPU == MCF5250 || CONFIG_CPU == MCF5249) && defined(HAVE_TLV320) | 82 | #if (CONFIG_CPU == MCF5250 || CONFIG_CPU == MCF5249) && defined(HAVE_TLV320) |
84 | static const unsigned char pcm_freq_parms[HW_NUM_FREQ][3] = | 83 | static const unsigned char pcm_freq_parms[HW_NUM_FREQ][2] = |
85 | { | 84 | { |
86 | [HW_FREQ_88] = { 0x0c, 0x01, 0x02 }, | 85 | [HW_FREQ_88] = { 0x0c, 0x01 }, |
87 | [HW_FREQ_44] = { 0x06, 0x01, 0x01 }, | 86 | [HW_FREQ_44] = { 0x06, 0x01 }, |
88 | [HW_FREQ_22] = { 0x04, 0x01, 0x00 }, | 87 | [HW_FREQ_22] = { 0x04, 0x01 }, |
89 | [HW_FREQ_11] = { 0x02, 0x02, 0x00 }, | 88 | [HW_FREQ_11] = { 0x02, 0x02 }, |
90 | }; | 89 | }; |
91 | #endif | 90 | #endif |
92 | 91 | ||
93 | static unsigned long pcm_freq = 0; /* 44.1 is default */ | 92 | static const unsigned char *freq_ent; |
94 | static const unsigned char *freq_ent = pcm_freq_parms[HW_FREQ_DEFAULT]; | ||
95 | |||
96 | /* set frequency used by the audio hardware */ | ||
97 | void pcm_set_frequency(unsigned int frequency) | ||
98 | { | ||
99 | int index; | ||
100 | |||
101 | switch(frequency) | ||
102 | { | ||
103 | case SAMPR_11: | ||
104 | index = HW_FREQ_11; | ||
105 | break; | ||
106 | case SAMPR_22: | ||
107 | index = HW_FREQ_22; | ||
108 | break; | ||
109 | default: | ||
110 | case SAMPR_44: | ||
111 | index = HW_FREQ_44; | ||
112 | break; | ||
113 | case SAMPR_88: | ||
114 | index = HW_FREQ_88; | ||
115 | break; | ||
116 | } | ||
117 | |||
118 | /* remember table entry and rate */ | ||
119 | freq_ent = pcm_freq_parms[index]; | ||
120 | pcm_freq = hw_freq_sampr[index]; | ||
121 | } /* pcm_set_frequency */ | ||
122 | 93 | ||
123 | /* apply audio settings */ | 94 | /* apply audio settings */ |
124 | static bool _pcm_apply_settings(bool clear_reset) | 95 | static bool _pcm_dma_apply_settings(bool clear_reset) |
125 | { | 96 | { |
126 | bool did_reset = false; | 97 | bool did_reset = false; |
127 | unsigned long iis_play_defparm = IIS_PLAY_DEFPARM; | 98 | unsigned long iis_play_defparm; |
99 | |||
100 | int level = set_irq_level(DMA_IRQ_LEVEL); | ||
101 | |||
102 | /* remember table entry */ | ||
103 | freq_ent = pcm_freq_parms[pcm_fsel]; | ||
128 | 104 | ||
129 | if (pcm_freq != pcm_curr_sampr) | 105 | iis_play_defparm = IIS_PLAY_DEFPARM; |
106 | |||
107 | if (pcm_sampr != pcm_curr_sampr) | ||
130 | { | 108 | { |
131 | pcm_curr_sampr = pcm_freq; | ||
132 | /* Reprogramming bits 15-12 requires FIFO to be in a reset | 109 | /* Reprogramming bits 15-12 requires FIFO to be in a reset |
133 | condition - Users Manual 17-8, Note 11 */ | 110 | condition - Users Manual 17-8, Note 11 */ |
134 | or_l(IIS_FIFO_RESET, &IIS_PLAY); | 111 | or_l(IIS_FIFO_RESET, &IIS_PLAY); |
@@ -136,8 +113,8 @@ static bool _pcm_apply_settings(bool clear_reset) | |||
136 | or starting recording will sound absolutely awful once in | 113 | or starting recording will sound absolutely awful once in |
137 | awhile - audiohw_set_frequency then coldfire_set_pllcr_audio_bits | 114 | awhile - audiohw_set_frequency then coldfire_set_pllcr_audio_bits |
138 | */ | 115 | */ |
139 | SET_IIS_PLAY(iis_play_defparm | IIS_FIFO_RESET); | 116 | SET_IIS_PLAY(IIS_PLAY_DEFPARM | IIS_FIFO_RESET); |
140 | audiohw_set_frequency(freq_ent[FPARM_FSEL]); | 117 | audiohw_set_frequency(pcm_fsel); |
141 | coldfire_set_pllcr_audio_bits(PLLCR_SET_AUDIO_BITS_DEFPARM); | 118 | coldfire_set_pllcr_audio_bits(PLLCR_SET_AUDIO_BITS_DEFPARM); |
142 | did_reset = true; | 119 | did_reset = true; |
143 | } | 120 | } |
@@ -147,26 +124,21 @@ static bool _pcm_apply_settings(bool clear_reset) | |||
147 | be cleared. If the frequency didn't change, it was never altered and | 124 | be cleared. If the frequency didn't change, it was never altered and |
148 | the reset flag can just be removed or no action taken. */ | 125 | the reset flag can just be removed or no action taken. */ |
149 | if (clear_reset) | 126 | if (clear_reset) |
150 | SET_IIS_PLAY(iis_play_defparm & ~IIS_FIFO_RESET); | 127 | SET_IIS_PLAY(IIS_PLAY_DEFPARM & ~IIS_FIFO_RESET); |
128 | |||
129 | restore_irq(level); | ||
130 | |||
151 | #if 0 | 131 | #if 0 |
152 | logf("IISPLAY: %08X", IIS_PLAY); | 132 | logf("IISPLAY: %08X", IIS_PLAY); |
153 | #endif | 133 | #endif |
154 | 134 | ||
155 | return did_reset; | 135 | return did_reset; |
156 | } /* _pcm_apply_settings */ | 136 | } /* _pcm_dma_apply_settings */ |
157 | |||
158 | /* apply audio setting with all DMA interrupts disabled */ | ||
159 | static void _pcm_apply_settings_irq_lock(bool clear_reset) | ||
160 | { | ||
161 | int level = set_irq_level(DMA_IRQ_LEVEL); | ||
162 | _pcm_apply_settings(clear_reset); | ||
163 | restore_irq(level); | ||
164 | } | ||
165 | 137 | ||
166 | /* This clears the reset bit to enable monitoring immediately if monitoring | 138 | /* This clears the reset bit to enable monitoring immediately if monitoring |
167 | recording sources or always if playback is in progress - we might be | 139 | recording sources or always if playback is in progress - we might be |
168 | switching samplerates on the fly */ | 140 | switching samplerates on the fly */ |
169 | void pcm_apply_settings(void) | 141 | void pcm_dma_apply_settings(void) |
170 | { | 142 | { |
171 | int level = set_irq_level(DMA_IRQ_LEVEL); | 143 | int level = set_irq_level(DMA_IRQ_LEVEL); |
172 | bool pbm = is_playback_monitoring(); | 144 | bool pbm = is_playback_monitoring(); |
@@ -174,14 +146,16 @@ void pcm_apply_settings(void) | |||
174 | 146 | ||
175 | /* Clear reset if not playback monitoring or peripheral request is | 147 | /* Clear reset if not playback monitoring or peripheral request is |
176 | active and playback monitoring */ | 148 | active and playback monitoring */ |
177 | if (_pcm_apply_settings(!pbm || kick) && kick) | 149 | if (_pcm_dma_apply_settings(!pbm || kick) && kick) |
178 | PDOR3 = 0; /* Kick FIFO out of reset by writing to it */ | 150 | PDOR3 = 0; /* Kick FIFO out of reset by writing to it */ |
179 | 151 | ||
180 | restore_irq(level); | 152 | restore_irq(level); |
181 | } /* pcm_apply_settings */ | 153 | } /* pcm_dma_apply_settings */ |
182 | 154 | ||
183 | void pcm_play_dma_init(void) | 155 | void pcm_play_dma_init(void) |
184 | { | 156 | { |
157 | freq_ent = pcm_freq_parms[pcm_fsel]; | ||
158 | |||
185 | AUDIOGLOB = (1 << 8) /* IIS1 fifo auto sync */ | 159 | AUDIOGLOB = (1 << 8) /* IIS1 fifo auto sync */ |
186 | | (1 << 7) /* PDIR2 fifo auto sync */ | 160 | | (1 << 7) /* PDIR2 fifo auto sync */ |
187 | #ifdef HAVE_SPDIF_OUT | 161 | #ifdef HAVE_SPDIF_OUT |
@@ -200,7 +174,6 @@ void pcm_play_dma_init(void) | |||
200 | other settings. */ | 174 | other settings. */ |
201 | or_l(IIS_FIFO_RESET, &IIS_PLAY); | 175 | or_l(IIS_FIFO_RESET, &IIS_PLAY); |
202 | SET_IIS_PLAY(IIS_PLAY_DEFPARM | IIS_FIFO_RESET); | 176 | SET_IIS_PLAY(IIS_PLAY_DEFPARM | IIS_FIFO_RESET); |
203 | pcm_set_frequency(HW_FREQ_DEFAULT); | ||
204 | audio_set_output_source(AUDIO_SRC_PLAYBACK); | 177 | audio_set_output_source(AUDIO_SRC_PLAYBACK); |
205 | 178 | ||
206 | /* Initialize default register values. */ | 179 | /* Initialize default register values. */ |
@@ -208,7 +181,7 @@ void pcm_play_dma_init(void) | |||
208 | 181 | ||
209 | audio_input_mux(AUDIO_SRC_PLAYBACK, SRCF_PLAYBACK); | 182 | audio_input_mux(AUDIO_SRC_PLAYBACK, SRCF_PLAYBACK); |
210 | 183 | ||
211 | audiohw_set_frequency(freq_ent[FPARM_FSEL]); | 184 | audiohw_set_frequency(pcm_fsel); |
212 | coldfire_set_pllcr_audio_bits(PLLCR_SET_AUDIO_BITS_DEFPARM); | 185 | coldfire_set_pllcr_audio_bits(PLLCR_SET_AUDIO_BITS_DEFPARM); |
213 | 186 | ||
214 | #if defined(HAVE_SPDIF_REC) || defined(HAVE_SPDIF_OUT) | 187 | #if defined(HAVE_SPDIF_REC) || defined(HAVE_SPDIF_OUT) |
@@ -264,7 +237,7 @@ void pcm_play_dma_start(const void *addr, size_t size) | |||
264 | BCR0 = (unsigned long)size; /* Bytes to transfer */ | 237 | BCR0 = (unsigned long)size; /* Bytes to transfer */ |
265 | 238 | ||
266 | /* Enable the FIFO and force one write to it */ | 239 | /* Enable the FIFO and force one write to it */ |
267 | _pcm_apply_settings_irq_lock(is_playback_monitoring()); | 240 | _pcm_dma_apply_settings(is_playback_monitoring()); |
268 | 241 | ||
269 | DCR0 = DMA_INT | DMA_EEXT | DMA_CS | DMA_AA | | 242 | DCR0 = DMA_INT | DMA_EEXT | DMA_CS | DMA_AA | |
270 | DMA_SINC | DMA_SSIZE(DMA_SIZE_LINE) | DMA_START; | 243 | DMA_SINC | DMA_SSIZE(DMA_SIZE_LINE) | DMA_START; |
@@ -299,7 +272,7 @@ void pcm_play_dma_pause(bool pause) | |||
299 | { | 272 | { |
300 | /* restart playback on current buffer */ | 273 | /* restart playback on current buffer */ |
301 | /* Enable the FIFO and force one write to it */ | 274 | /* Enable the FIFO and force one write to it */ |
302 | _pcm_apply_settings_irq_lock(is_playback_monitoring()); | 275 | _pcm_dma_apply_settings(is_playback_monitoring()); |
303 | or_l(DMA_EEXT | DMA_START, &DCR0); | 276 | or_l(DMA_EEXT | DMA_START, &DCR0); |
304 | dma_play_lock.state = (1 << 14); | 277 | dma_play_lock.state = (1 << 14); |
305 | } | 278 | } |
@@ -403,7 +376,7 @@ void pcm_rec_dma_start(void *addr, size_t size) | |||
403 | and_l(~PDIR2_FIFO_RESET, &DATAINCONTROL); | 376 | and_l(~PDIR2_FIFO_RESET, &DATAINCONTROL); |
404 | /* Clear TX FIFO reset bit if the source is not set to monitor playback | 377 | /* Clear TX FIFO reset bit if the source is not set to monitor playback |
405 | otherwise maintain independence between playback and recording. */ | 378 | otherwise maintain independence between playback and recording. */ |
406 | _pcm_apply_settings_irq_lock(!is_playback_monitoring()); | 379 | _pcm_dma_apply_settings(!is_playback_monitoring()); |
407 | 380 | ||
408 | /* Start the DMA transfer.. */ | 381 | /* Start the DMA transfer.. */ |
409 | #ifdef HAVE_SPDIF_REC | 382 | #ifdef HAVE_SPDIF_REC |