summaryrefslogtreecommitdiff
path: root/firmware/target/coldfire
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/coldfire')
-rw-r--r--firmware/target/coldfire/pcm-coldfire.c101
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)
74static const unsigned char pcm_freq_parms[HW_NUM_FREQ][3] = 73static 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)
84static const unsigned char pcm_freq_parms[HW_NUM_FREQ][3] = 83static 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
93static unsigned long pcm_freq = 0; /* 44.1 is default */ 92static const unsigned char *freq_ent;
94static const unsigned char *freq_ent = pcm_freq_parms[HW_FREQ_DEFAULT];
95
96/* set frequency used by the audio hardware */
97void 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 */
124static bool _pcm_apply_settings(bool clear_reset) 95static 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 */
159static 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 */
169void pcm_apply_settings(void) 141void 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
183void pcm_play_dma_init(void) 155void 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