summaryrefslogtreecommitdiff
path: root/firmware/target/arm/rk27xx/pcm-rk27xx.c
diff options
context:
space:
mode:
authorMarcin Bukat <marcin.bukat@gmail.com>2011-10-17 10:32:19 +0000
committerMarcin Bukat <marcin.bukat@gmail.com>2011-10-17 10:32:19 +0000
commit32f763c39a797221a6e850704feb3743bc104d8c (patch)
treec509c38423f2efb76a13119f92c21e5e82476a42 /firmware/target/arm/rk27xx/pcm-rk27xx.c
parentf0311d3310e84906a6c1afaf941f2f58e2063c30 (diff)
downloadrockbox-32f763c39a797221a6e850704feb3743bc104d8c.tar.gz
rockbox-32f763c39a797221a6e850704feb3743bc104d8c.zip
Add HiFiMAN HM-60x target(s). FS#12319 by Andrew Ryabinin with some (small) modification by me. This also splits rk27xx lcd driver into lcdif-rk27xx and lcd controller specific part. Some modifications to the pcm driver have been made to allow using codecs in slave mode (as TDA1543 used in hifiman is slave only i2s codec).
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@30765 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/target/arm/rk27xx/pcm-rk27xx.c')
-rw-r--r--firmware/target/arm/rk27xx/pcm-rk27xx.c62
1 files changed, 59 insertions, 3 deletions
diff --git a/firmware/target/arm/rk27xx/pcm-rk27xx.c b/firmware/target/arm/rk27xx/pcm-rk27xx.c
index b8ae56adaf..80a8d462ea 100644
--- a/firmware/target/arm/rk27xx/pcm-rk27xx.c
+++ b/firmware/target/arm/rk27xx/pcm-rk27xx.c
@@ -8,6 +8,7 @@
8 * $Id$ 8 * $Id$
9 * 9 *
10 * Copyright (C) 2011 Marcin Bukat 10 * Copyright (C) 2011 Marcin Bukat
11 * Copyright (C) 2011 Andrew Ryabinin
11 * 12 *
12 * This program is free software; you can redistribute it and/or 13 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License 14 * modify it under the terms of the GNU General Public License
@@ -179,13 +180,65 @@ static void i2s_init(void)
179 (0<<2) | /* normal operation */ 180 (0<<2) | /* normal operation */
180#ifdef CODEC_SLAVE 181#ifdef CODEC_SLAVE
181 (1<<1) | /* start Tx (master mode) */ 182 (1<<1) | /* start Tx (master mode) */
182 (1<<0); /* start Rx (master mode) */ 183 (0<<0); /* do not start Rx (master mode) */
184 /* setting Rx bit to 1 result in choppy audio */
183#else 185#else
184 (0<<1) | /* not used in slave mode */ 186 (0<<1) | /* not used in slave mode */
185 (0<<0); /* not used in slave mode */ 187 (0<<0); /* not used in slave mode */
186#endif 188#endif
187} 189}
188 190
191#ifdef CODEC_SLAVE
192/* When codec is slave we need to setup i2s MCLK clock using codec pll.
193 * The MCLK frequency is 256*codec frequency as i2s setup is:
194 * LRCK/SCLK = 64 and MCLK/SCLK = 4 (see i2s_init() for reference)
195 *
196 * PLL output frequency:
197 * Fout = ((Fref / (CLKR+1)) * (CLKF+1)) / (CLKOD+1)
198 * Fref = 24 MHz
199 */
200static void set_codec_freq(unsigned int freq)
201{
202 long timeout;
203
204 /* {CLKR, CLKF, CLKOD, CODECPLL_DIV} */
205 static const unsigned int pcm_freq_params[HW_NUM_FREQ][4] =
206 {
207 [HW_FREQ_96] = {24, 255, 4, 1},
208 [HW_FREQ_48] = {24, 127, 4, 1},
209 [HW_FREQ_44] = {24, 293, 4, 4},
210 [HW_FREQ_32] = {24, 127, 4, 2},
211 [HW_FREQ_24] = {24, 127, 4, 3},
212 [HW_FREQ_22] = {24, 146, 4, 4},
213 [HW_FREQ_16] = {24, 127, 5, 4},
214 [HW_FREQ_12] = {24, 127, 4, 7},
215 [HW_FREQ_11] = {24, 146, 4, 9},
216 [HW_FREQ_8] = {24, 127, 5, 9},
217 };
218 /* select divider output from codec pll */
219 SCU_DIVCON1 &= ~((1<<9) | (0xF<<5));
220 SCU_DIVCON1 |= (pcm_freq_params[freq][3]<<5);
221
222 /* Codec PLL power up */
223 SCU_PLLCON3 &= ~(1<<22);
224
225 SCU_PLLCON3 = (1<<24) | /* Saturation behavior enable */
226 (1<<23) | /* Enable fast locking circuit */
227 (pcm_freq_params[freq][0]<<16) | /* CLKR factor */
228 (pcm_freq_params[freq][1]<<4) | /* CLKF factor */
229 (pcm_freq_params[freq][2]<<1) ; /* CLKOD factor */
230
231/* wait for CODEC PLL lock with 10 ms timeout
232 * datasheet states that pll lock should take approx. 0.3 ms
233 */
234 timeout = current_tick + (HZ/100);
235 while (!(SCU_STATUS & (1<<2)))
236 if (TIME_AFTER(current_tick, timeout))
237 break;
238
239}
240#endif
241
189void pcm_play_dma_init(void) 242void pcm_play_dma_init(void)
190{ 243{
191 /* unmask HDMA interrupt in INTC */ 244 /* unmask HDMA interrupt in INTC */
@@ -204,8 +257,11 @@ void pcm_play_dma_postinit(void)
204 257
205void pcm_dma_apply_settings(void) 258void pcm_dma_apply_settings(void)
206{ 259{
207 /* I2S module runs in slave mode */ 260#ifdef CODEC_SLAVE
208 return; 261 set_codec_freq(pcm_fsel);
262#endif
263
264 audiohw_set_frequency(pcm_fsel);
209} 265}
210 266
211size_t pcm_get_bytes_waiting(void) 267size_t pcm_get_bytes_waiting(void)