summaryrefslogtreecommitdiff
path: root/firmware/drivers
diff options
context:
space:
mode:
authorMichael Sevakis <jethead71@rockbox.org>2006-11-06 18:07:30 +0000
committerMichael Sevakis <jethead71@rockbox.org>2006-11-06 18:07:30 +0000
commit0f5cb94aa4a334366a746fcbb22f3335ca413265 (patch)
tree8f89a96628c1810d51ee9816daf78edb8c76fcd4 /firmware/drivers
parent0b22795e26ee09de14f6ac23219adeda12f2fd5b (diff)
downloadrockbox-0f5cb94aa4a334366a746fcbb22f3335ca413265.zip
rockbox-0f5cb94aa4a334366a746fcbb22f3335ca413265.tar.gz
rockbox-0f5cb94aa4a334366a746fcbb22f3335ca413265.tar.bz2
rockbox-0f5cb94aa4a334366a746fcbb22f3335ca413265.tar.xz
Big Patch adds primarily: Samplerate and format selection to recording for SWCODEC. Supprort for samplerates changing in playback (just goes with the recording part inseparably). Samplerates to all encoders. Encoders can be configured individually on a menu specific to the encoder in the recording menu. File creation is delayed until flush time to reduce spinups when splitting. Misc: statusbar icons for numbers are individual digits to display any number. Audio buffer was rearranged to maximize memory available to recording and properly reinitialized when trashed. ColdFire PCM stuff moved to target tree to avoid a complicated mess when adding samplerate switching. Some needed API changes and to neaten up growing gap between hardware and software codecs.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@11452 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/drivers')
-rw-r--r--firmware/drivers/tlv320.c45
-rw-r--r--firmware/drivers/uda1380.c84
2 files changed, 88 insertions, 41 deletions
diff --git a/firmware/drivers/tlv320.c b/firmware/drivers/tlv320.c
index abce31e..7c4bbbd 100644
--- a/firmware/drivers/tlv320.c
+++ b/firmware/drivers/tlv320.c
@@ -82,7 +82,7 @@ void tlv320_init(void)
tlv320_write_reg(REG_DAP, 0x00); /* No deemphasis */
tlv320_write_reg(REG_DAIF, DAIF_IWL_16 | DAIF_FOR_I2S);
tlv320_write_reg(REG_DIA, DIA_ACT);
- tlv320_write_reg(REG_SRC, (1 << 5)); /* 44.1kHz */
+ tlv320_set_frequency(-1); /* default */
/* All ON except ADC, MIC and LINE */
tlv320_write_reg(REG_PC, PC_ADC | PC_MIC | PC_LINE);
}
@@ -96,6 +96,32 @@ void tlv320_reset(void)
}
/**
+ * Sets internal sample rate for DAC and ADC relative to MCLK
+ * Selection for frequency:
+ * Fs: tlv: with:
+ * 11025: 0 = MCLK/2 MCLK/2 SCLK, LRCK: Audio Clk / 16
+ * 22050: 0 = MCLK/2 MCLK SCLK, LRCK: Audio Clk / 8
+ * 44100: 1 = MCLK MCLK SCLK, LRCK: Audio Clk / 4 (default)
+ * 88200: 2 = MCLK*2 MCLK SCLK, LRCK: Audio Clk / 2
+ */
+void tlv320_set_frequency(unsigned fsel)
+{
+ /* All rates available for 11.2896MHz besides 8.021 */
+ unsigned char values_src[3] =
+ {
+ /* Fs: */
+ (0x8 << 2) | SRC_CLKIN, /* 11025, 22050 */
+ (0x8 << 2), /* 44100 */
+ (0xf << 2), /* 88200 */
+ };
+
+ if (fsel >= ARRAYLEN(values_src))
+ fsel = 1;
+
+ tlv320_write_reg(REG_SRC, values_src[fsel]);
+}
+
+/**
* Sets left and right headphone volume
*
* Left & Right: 48 .. 121 .. 127 => Volume -73dB (mute) .. +0 dB .. +6 dB
@@ -142,7 +168,6 @@ void tlv320_set_recvol(int left, int right, int type)
value_aap &= ~AAP_MICB;
tlv320_write_reg(REG_AAP, value_aap);
-
}
else if (type == AUDIO_GAIN_LINEIN)
{
@@ -180,15 +205,17 @@ void tlv320_mute(bool mute)
}
/* Nice shutdown of TLV320 codec */
-void tlv320_close()
+void tlv320_close(void)
{
+ tlv320_mute(true);
+ sleep(HZ/8);
+
tlv320_write_reg(REG_PC, PC_OFF | PC_CLK | PC_OSC | PC_OUT |
PC_DAC | PC_ADC | PC_MIC | PC_LINE); /* All OFF */
}
void tlv320_enable_recording(bool source_mic)
{
- unsigned value_daif = tlv320_regs[REG_DAIF];
unsigned value_aap, value_pc;
if (source_mic)
@@ -205,20 +232,12 @@ void tlv320_enable_recording(bool source_mic)
tlv320_write_reg(REG_PC, value_pc);
tlv320_write_reg(REG_AAP, value_aap);
-
- /* Enable MASTER mode (start sending I2S data to the CPU) */
- value_daif |= DAIF_MS;
- tlv320_write_reg(REG_DAIF, value_daif);
}
-void tlv320_disable_recording()
+void tlv320_disable_recording(void)
{
unsigned value_pc = tlv320_regs[REG_PC];
unsigned value_aap = tlv320_regs[REG_AAP];
- unsigned value_daif = tlv320_regs[REG_DAIF];
-
- value_daif &= ~DAIF_MS; /* disable MASTER mode */
- tlv320_write_reg(REG_DAIF, value_daif);
value_aap |= AAP_MICM; /* mute MIC */
tlv320_write_reg(REG_PC, value_aap);
diff --git a/firmware/drivers/uda1380.c b/firmware/drivers/uda1380.c
index 241a117..d6dfe66 100644
--- a/firmware/drivers/uda1380.c
+++ b/firmware/drivers/uda1380.c
@@ -49,9 +49,10 @@ short recgain_line;
#define NUM_DEFAULT_REGS 13
unsigned short uda1380_defaults[2*NUM_DEFAULT_REGS] =
{
- REG_0, EN_DAC | EN_INT | EN_DEC | SYSCLK_256FS | WSPLL_25_50,
+ REG_0, EN_DAC | EN_INT | EN_DEC | ADC_CLK | DAC_CLK |
+ SYSCLK_256FS | WSPLL_25_50,
REG_I2S, I2S_IFMT_IIS,
- REG_PWR, PON_BIAS,
+ REG_PWR, PON_PLL | PON_BIAS,
/* PON_HP & PON_DAC is enabled later */
REG_AMIX, AMIX_RIGHT(0x3f) | AMIX_LEFT(0x3f),
/* 00=max, 3f=mute */
@@ -60,7 +61,7 @@ unsigned short uda1380_defaults[2*NUM_DEFAULT_REGS] =
REG_MIX_VOL, MIX_VOL_CH_1(0) | MIX_VOL_CH_2(0xff),
/* 00=max, ff=mute */
REG_EQ, EQ_MODE_MAX,
- /* Bass and tremble = 0 dB */
+ /* Bass and treble = 0 dB */
REG_MUTE, MUTE_MASTER | MUTE_CH2,
/* Mute everything to start with */
REG_MIX_CTL, MIX_CTL_MIX,
@@ -192,6 +193,43 @@ void uda1380_reset(void)
#endif
}
+/**
+ * Sets frequency settings for DAC and ADC relative to MCLK
+ *
+ * Selection for frequency ranges:
+ * Fs: range: with:
+ * 11025: 0 = 6.25 to 12.5 MCLK/2 SCLK, LRCK: Audio Clk / 16
+ * 22050: 1 = 12.5 to 25 MCLK/2 SCLK, LRCK: Audio Clk / 8
+ * 44100: 2 = 25 to 50 MCLK SCLK, LRCK: Audio Clk / 4 (default)
+ * 88200: 3 = 50 to 100 MCLK SCLK, LRCK: Audio Clk / 2 <= TODO: Needs WSPLL
+ */
+void uda1380_set_frequency(unsigned fsel)
+{
+ static const unsigned short values_reg[4][2] =
+ {
+ /* Fs: */
+ { 0, WSPLL_625_125 | SYSCLK_512FS }, /* 11025 */
+ { 0, WSPLL_125_25 | SYSCLK_256FS }, /* 22050 */
+ { MIX_CTL_SEL_NS, WSPLL_25_50 | SYSCLK_256FS }, /* 44100 */
+ { MIX_CTL_SEL_NS, WSPLL_50_100 | SYSCLK_256FS }, /* 88200 */
+ };
+
+ const unsigned short *ent;
+
+ if (fsel >= ARRAYLEN(values_reg))
+ fsel = 2;
+
+ ent = values_reg[fsel];
+
+ /* Set WSPLL input frequency range or SYSCLK divider */
+ uda1380_regs[REG_0] &= ~0xf;
+ uda1380_write_reg(REG_0, uda1380_regs[REG_0] | ent[1]);
+
+ /* Choose 3rd order or 5th order noise shaper */
+ uda1380_regs[REG_MIX_CTL] &= ~MIX_CTL_SEL_NS;
+ uda1380_write_reg(REG_MIX_CTL, uda1380_regs[REG_MIX_CTL] | ent[0]);
+}
+
/* Initialize UDA1380 codec with default register values (uda1380_defaults) */
int uda1380_init(void)
{
@@ -227,30 +265,34 @@ void uda1380_close(void)
*/
void uda1380_enable_recording(bool source_mic)
{
+ uda1380_regs[REG_0] &= ~(ADC_CLK | DAC_CLK);
uda1380_write_reg(REG_0, uda1380_regs[REG_0] | EN_ADC);
if (source_mic)
{
/* VGA_GAIN: 0=0 dB, F=30dB */
+ /* Output of left ADC is fed into right bitstream */
+ uda1380_regs[REG_PWR] &= ~(PON_PLL | PON_PGAR | PON_ADCR);
uda1380_write_reg(REG_PWR, uda1380_regs[REG_PWR] | PON_LNA | PON_ADCL);
+ uda1380_regs[REG_ADC] &= ~SKIP_DCFIL;
uda1380_write_reg(REG_ADC, (uda1380_regs[REG_ADC] & VGA_GAIN_MASK)
| SEL_LNA | SEL_MIC | EN_DCFIL);
uda1380_write_reg(REG_PGA, 0);
- } else
+ }
+ else
{
/* PGA_GAIN: 0=0 dB, F=24dB */
+ uda1380_regs[REG_PWR] &= ~(PON_PLL | PON_LNA);
uda1380_write_reg(REG_PWR, uda1380_regs[REG_PWR] | PON_PGAL | PON_ADCL
| PON_PGAR | PON_ADCR);
uda1380_write_reg(REG_ADC, EN_DCFIL);
- uda1380_write_reg(REG_PGA, (uda1380_regs[REG_PGA] & PGA_GAIN_MASK)
- | PGA_GAINL(0) | PGA_GAINR(0));
+ uda1380_write_reg(REG_PGA, uda1380_regs[REG_PGA] & PGA_GAIN_MASK);
}
sleep(HZ/8);
uda1380_write_reg(REG_I2S, uda1380_regs[REG_I2S] | I2S_MODE_MASTER);
uda1380_write_reg(REG_MIX_CTL, MIX_MODE(1));
-
}
/**
@@ -262,10 +304,13 @@ void uda1380_disable_recording(void)
sleep(HZ/8);
uda1380_write_reg(REG_I2S, I2S_IFMT_IIS);
- uda1380_write_reg(REG_PWR, uda1380_regs[REG_PWR] & ~(PON_LNA | PON_ADCL
- | PON_ADCR | PON_PGAL
- | PON_PGAR));
- uda1380_write_reg(REG_0, uda1380_regs[REG_0] & ~EN_ADC);
+
+ uda1380_regs[REG_PWR] &= ~(PON_LNA | PON_ADCL | PON_ADCR | PON_PGAL | PON_PGAR);
+ uda1380_write_reg(REG_PWR, uda1380_regs[REG_PWR] | PON_PLL);
+
+ uda1380_regs[REG_0] &= ~EN_ADC;
+ uda1380_write_reg(REG_0, uda1380_regs[REG_0] | ADC_CLK | DAC_CLK);
+
uda1380_write_reg(REG_ADC, SKIP_DCFIL);
}
@@ -373,20 +418,3 @@ void uda1380_set_monitor(int enable)
else /* mute channel 2 */
uda1380_write_reg(REG_MUTE, uda1380_regs[REG_MUTE] | MUTE_CH2);
}
-
-/* Change the order of the noise chaper,
- 5th order is recommended above 32kHz */
-void uda1380_set_nsorder(int order)
-{
- switch(order)
- {
- case 5:
- uda1380_write_reg(REG_MIX_CTL, uda1380_regs[REG_MIX_CTL]
- | MIX_CTL_SEL_NS);
- break;
- case 3:
- default:
- uda1380_write_reg(REG_MIX_CTL, uda1380_regs[REG_MIX_CTL]
- & ~MIX_CTL_SEL_NS);
- }
-}