From ba9040a82b15c18b242134474a6e1d571ed686a3 Mon Sep 17 00:00:00 2001 From: Bertrik Sikken Date: Sun, 10 Jan 2010 14:24:45 +0000 Subject: Sansa AMS: allow use of PLL B for more accurate audio sample rate (0.04% instead 0.15% error) git-svn-id: svn://svn.rockbox.org/rockbox/trunk@24211 a1c6a512-1295-4272-9138-f99709370657 --- firmware/target/arm/as3525/clock-target.h | 24 +++++++++++++++++++----- firmware/target/arm/as3525/pcm-as3525.c | 14 ++++++++------ firmware/target/arm/as3525/system-as3525.c | 7 +++++++ 3 files changed, 34 insertions(+), 11 deletions(-) diff --git a/firmware/target/arm/as3525/clock-target.h b/firmware/target/arm/as3525/clock-target.h index 08c385c7cd..fd3a1c7bf4 100644 --- a/firmware/target/arm/as3525/clock-target.h +++ b/firmware/target/arm/as3525/clock-target.h @@ -52,7 +52,7 @@ /* Clock Sources */ #define AS3525_CLK_MAIN 0 #define AS3525_CLK_PLLA 1 -//#define AS3525_CLK_PLLB 2 +#define AS3525_CLK_PLLB 2 #define AS3525_CLK_FCLK 3 /* Available as PCLK input only */ /** ************ Change these to reconfigure clocking scheme *******************/ @@ -70,6 +70,10 @@ /* *5/8 = 155MHz 77.5, 51.67, 38.75 */ #define AS3525_PLLA_SETTING 0x261F +/* PLLB frequencies and settings (audio and USB) */ +#define AS3525_PLLB_FREQ 384000000 /* allows 44.1kHz with 0.04% error*/ +#define AS3525_PLLB_SETTING 0x2630 + #endif /* SANSA_CLIPV2 */ //#define AS3525_PLLA_FREQ 384000000 /*192,128,96,76.8,64,54.9,48,42.7,38.4*/ @@ -107,6 +111,16 @@ #define AS3525_FCLK_SEL AS3525_CLK_PLLA #define AS3525_FCLK_POSTDIV (CLK_DIV((AS3525_PLLA_FREQ*(8-AS3525_FCLK_PREDIV)/8), AS3525_FCLK_FREQ) - 1) /*div=1/(n+1)*/ +/* MCLK */ +#define AS3525_MCLK_SEL AS3525_CLK_PLLA +#if (AS3525_MCLK_SEL==AS3525_CLK_PLLA) +#define AS3525_MCLK_FREQ AS3525_PLLA_FREQ +#elif (AS3525_MCLK_SEL==AS3525_CLK_PLLB) +#define AS3525_MCLK_FREQ AS3525_PLLB_FREQ +#else +#error Choose either PLLA or PLLB for MCLK! +#endif + /* PCLK */ #ifdef ASYNCHRONOUS_BUS #define AS3525_PCLK_SEL AS3525_CLK_PLLA /* PLLA input for asynchronous */ @@ -169,12 +183,12 @@ /* I2SIN / I2SOUT frequencies */ /* low samplerate */ -#if ((AS3525_PLLA_FREQ/(128*8000))) > 512 /* 8kHz = lowest frequency */ -#error PLLA frequency is too low for 8kHz samplerate ! +#if ((AS3525_MCLK_FREQ/(128*8000))) > 512 /* 8kHz = lowest frequency */ +#error AS3525_MCLK_FREQ is too high for 8kHz samplerate ! #endif /* high samplerate */ -#if ((AS3525_PLLA_FREQ/(128*96000))) < 1 /* 96kHz = highest frequency */ -#error PLLA frequency is too high for 96kHz samplerate ! +#if ((AS3525_MCLK_FREQ/(128*96000))) < 1 /* 96kHz = highest frequency */ +#error AS3525_MCLK_FREQ is too low for 96kHz samplerate ! #endif #endif /* CLOCK_TARGET_H */ diff --git a/firmware/target/arm/as3525/pcm-as3525.c b/firmware/target/arm/as3525/pcm-as3525.c index 88aaaf9220..53a3f0c9a3 100644 --- a/firmware/target/arm/as3525/pcm-as3525.c +++ b/firmware/target/arm/as3525/pcm-as3525.c @@ -139,11 +139,13 @@ void pcm_dma_apply_settings(void) unsigned long frequency = pcm_sampr; /* TODO : use a table ? */ - const int divider = (((AS3525_PLLA_FREQ/128) + (frequency/2)) / frequency) - 1; + const int divider = ((AS3525_MCLK_FREQ/128) + (frequency/2)) / frequency; int cgu_audio = CGU_AUDIO; /* read register */ + cgu_audio &= ~(3 << 0); /* clear i2sout MCLK_SEL */ + cgu_audio |= (AS3525_MCLK_SEL << 0); /* set i2sout MCLK_SEL */ cgu_audio &= ~(511 << 2); /* clear i2sout divider */ - cgu_audio |= divider << 2; /* set new i2sout divider */ + cgu_audio |= (divider - 1) << 2; /* set new i2sout divider */ CGU_AUDIO = cgu_audio; /* write back register */ } @@ -318,13 +320,13 @@ void pcm_rec_dma_init(void) unsigned long frequency = pcm_sampr; /* TODO : use a table ? */ - const int divider = (((AS3525_PLLA_FREQ/128) + (frequency/2)) / frequency) - 1; + const int divider = ((AS3525_MCLK_FREQ/128) + (frequency/2)) / frequency; int cgu_audio = CGU_AUDIO; /* read register */ - cgu_audio &= ~(3 << 12); /* clear i2sin clocksource */ - cgu_audio |= (1 << 12); /* set to PLLA */ + cgu_audio &= ~(3 << 12); /* clear i2sin MCLK_SEL */ + cgu_audio |= (AS3525_MCLK_SEL << 12); /* set i2sin MCLK_SEL */ cgu_audio &= ~(511 << 14); /* clear i2sin divider */ - cgu_audio |= divider << 14; /* set new i2sin divider */ + cgu_audio |= (divider - 1) << 14; /* set new i2sin divider */ CGU_AUDIO = cgu_audio; /* write back register */ } diff --git a/firmware/target/arm/as3525/system-as3525.c b/firmware/target/arm/as3525/system-as3525.c index 75539ba8d7..13b406a6b8 100644 --- a/firmware/target/arm/as3525/system-as3525.c +++ b/firmware/target/arm/as3525/system-as3525.c @@ -285,8 +285,15 @@ void system_init(void) CGU_PROC = 0; /* fclk 24 MHz */ CGU_PERI &= ~0x7f; /* pclk 24 MHz */ + CGU_PLLASUP = 0; /* enable PLLA */ CGU_PLLA = AS3525_PLLA_SETTING; while(!(CGU_INTCTRL & (1<<0))); /* wait until PLLA is locked */ + +#if (AS3525_MCLK_SEL == AS3525_CLK_PLLB) + CGU_PLLBSUP = 0; /* enable PLLB */ + CGU_PLLB = AS3525_PLLB_SETTING; + while(!(CGU_INTCTRL & (1<<1))); /* wait until PLLB is locked */ +#endif /* Set FCLK frequency */ CGU_PROC = ((AS3525_FCLK_POSTDIV << 4) | -- cgit v1.2.3