From 50778c82f1311979ca3d3a6a7d0021367bb26ef4 Mon Sep 17 00:00:00 2001 From: Dmitry Gamza Date: Tue, 9 Apr 2013 09:57:03 +0400 Subject: optimize WSPLL work for iriver h100 and h300 series For Iriver h100 & h300 series we don't need always use WSPLL, because in most cases WSPLL clock and SYSCLK has the same value, and we have additional WSPLL errors to the output clock. Now that is fixed. Change-Id: I04aebee659c57c45dc8603e409b9db42bdde534a Reviewed-on: http://gerrit.rockbox.org/434 Reviewed-by: Marcin Bukat --- firmware/drivers/audio/uda1380.c | 48 +++++++++++++++++++++++++++++++++------- 1 file changed, 40 insertions(+), 8 deletions(-) (limited to 'firmware/drivers/audio') diff --git a/firmware/drivers/audio/uda1380.c b/firmware/drivers/audio/uda1380.c index 2fe562f865..156eb822b6 100644 --- a/firmware/drivers/audio/uda1380.c +++ b/firmware/drivers/audio/uda1380.c @@ -76,18 +76,34 @@ static unsigned short uda1380_regs[0x30]; static short recgain_mic; static short recgain_line; +#ifdef USE_WSPLL + +/* Internal control of WSPLL */ +static bool wspll_enable = false; + +static void wspll_on(bool on) +{ + uda1380_regs[REG_0] &= ~(ADC_CLK | DAC_CLK); + uda1380_regs[REG_PWR] &= ~PON_PLL; + + unsigned short pll_ena = (on) ? (ADC_CLK | DAC_CLK) : 0; + unsigned short pll_pow = (on) ? PON_PLL : 0; + + uda1380_write_reg(REG_0, uda1380_regs[REG_0] | pll_ena); + uda1380_write_reg(REG_PWR, uda1380_regs[REG_PWR] | pll_pow); + + wspll_enable = on; +} +#endif + /* Definition of a playback configuration to start with */ #define NUM_DEFAULT_REGS 13 static const unsigned short uda1380_defaults[2*NUM_DEFAULT_REGS] = { - REG_0, EN_DAC | EN_INT | EN_DEC | -#ifdef USE_WSPLL - ADC_CLK | DAC_CLK | WSPLL_25_50 | -#endif - SYSCLK_256FS, + REG_0, EN_DAC | EN_INT | EN_DEC | WSPLL_25_50 | SYSCLK_256FS, REG_I2S, I2S_IFMT_IIS, - REG_PWR, PON_PLL | PON_BIAS, + REG_PWR, PON_BIAS, /* PON_HP & PON_DAC is enabled later */ REG_AMIX, AMIX_RIGHT(0x3f) | AMIX_LEFT(0x3f), /* 00=max, 3f=mute */ @@ -225,6 +241,22 @@ void audiohw_set_frequency(int fsel) ent = values_reg[fsel]; +#ifdef USE_WSPLL + /* Enable WSPLL if needed (for Iriver H100 and H300 series) */ + if (fsel == HW_FREQ_88) + { + /* Only at this case we need use WSPLL on DAC part for Iriver H100 and H300 series, because Coldfire work + at 11289600 Hz frequency and SYSCLK of UDA1380 can only be 256fs, 384fs, 512fs and 768fs. But in this case SYSCLK + is 128fs : 11289600 / 88200 = 128 */ + if (!wspll_enable) wspll_on(true); + } + else + { + /* At this case WSPLL clock and SYSCLK has same value and we don't use WSPLL to avoid WSPLL errors */ + if (wspll_enable) wspll_on(false); + } +#endif + /* Set WSPLL input frequency range or SYSCLK divider */ uda1380_regs[REG_0] &= ~0xf; uda1380_write_reg(REG_0, uda1380_regs[REG_0] | ent[1]); @@ -292,7 +324,7 @@ void audiohw_close(void) void audiohw_enable_recording(bool source_mic) { #ifdef USE_WSPLL - uda1380_regs[REG_0] &= ~(ADC_CLK | DAC_CLK); + if (wspll_enable) uda1380_regs[REG_0] &= ~(ADC_CLK | DAC_CLK); #endif uda1380_write_reg(REG_0, uda1380_regs[REG_0] | EN_ADC); @@ -339,7 +371,7 @@ void audiohw_disable_recording(void) uda1380_regs[REG_0] &= ~EN_ADC; #ifdef USE_WSPLL - uda1380_write_reg(REG_0, uda1380_regs[REG_0] | ADC_CLK | DAC_CLK); + if (wspll_enable) uda1380_write_reg(REG_0, uda1380_regs[REG_0] | ADC_CLK | DAC_CLK); #endif uda1380_write_reg(REG_ADC, SKIP_DCFIL); -- cgit v1.2.3