summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDmitry Gamza <gamzad@yahoo.com>2013-04-09 09:57:03 +0400
committerMarcin Bukat <marcin.bukat@gmail.com>2014-09-05 09:14:53 +0200
commit50778c82f1311979ca3d3a6a7d0021367bb26ef4 (patch)
tree842a07a0936b0b6b1d86233ac7d9cf9f96ab4b3e
parent489c9a6f64dc6121abf52b81a1ef73506d6e25bf (diff)
downloadrockbox-50778c8.tar.gz
rockbox-50778c8.tar.bz2
rockbox-50778c8.zip
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 <marcin.bukat@gmail.com>
-rw-r--r--firmware/drivers/audio/uda1380.c48
1 files changed, 40 insertions, 8 deletions
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);