diff options
author | Cástor Muñoz <cmvidal@gmail.com> | 2014-11-18 03:08:31 +0100 |
---|---|---|
committer | Cástor Muñoz <cmvidal@gmail.com> | 2014-11-18 06:22:32 +0100 |
commit | 794169a18f644eea32de20b26646381137545e2d (patch) | |
tree | 2fadf3085b8ce698f6cd1c8b80ea181e0e20d314 | |
parent | 61206ce4689458f4031fa27a89f35d52b5554371 (diff) | |
download | rockbox-794169a.tar.gz rockbox-794169a.zip |
iPod Classic: fix HW_FREQ_32
Change-Id: I1e1b4e6ceb92eb793affaefc61ab082d5da735b4
-rw-r--r-- | firmware/target/arm/s5l8702/pcm-s5l8702.c | 33 |
1 files changed, 31 insertions, 2 deletions
diff --git a/firmware/target/arm/s5l8702/pcm-s5l8702.c b/firmware/target/arm/s5l8702/pcm-s5l8702.c index cbfe6ea007..1048354ec5 100644 --- a/firmware/target/arm/s5l8702/pcm-s5l8702.c +++ b/firmware/target/arm/s5l8702/pcm-s5l8702.c @@ -145,10 +145,39 @@ void pcm_play_dma_pause(bool pause) /* set the configured PCM frequency */ void pcm_dma_apply_settings(void) { + static uint16_t last_clkcon3l = 0; + uint16_t clkcon3l; + int fsel; + + /* For unknown reasons, s5l8702 I2S controller does not synchronize + * with CS42L55 at 32000 Hz. To fix it, the CODEC is configured with + * a sample rate of 48000 Hz and MCLK is decreased 1/3 to 8 Mhz, + * obtaining 32 KHz in LRCK controller input and 8 MHz in SCLK input. + * OF uses this trick. + */ + if (pcm_fsel == HW_FREQ_32) { + fsel = HW_FREQ_48; + clkcon3l = 0x3028; /* PLL2 / 3 / 9 -> 8 MHz */ + } + else { + fsel = pcm_fsel; + clkcon3l = 0; /* OSC0 -> 12 MHz */ + } + + /* configure MCLK */ + /* TODO: maybe all CLKCON management should be moved to + cscodec-ipod6g.c and system-s5l8702.c */ + if (last_clkcon3l != clkcon3l) { + CLKCON3 = (CLKCON3 & ~0xffff) | 0x8000 | clkcon3l; + udelay(100); + CLKCON3 &= ~0x8000; /* CLKCON3L on */ + last_clkcon3l = clkcon3l; + } + /* configure I2S clock ratio */ - I2SCLKDIV = MCLK_FREQ / hw_freq_sampr[pcm_fsel]; + I2SCLKDIV = MCLK_FREQ / hw_freq_sampr[fsel]; /* select CS42L55 sample rate */ - audiohw_set_frequency(pcm_fsel); + audiohw_set_frequency(fsel); } void pcm_play_dma_init(void) |