summaryrefslogtreecommitdiff
path: root/firmware/drivers
diff options
context:
space:
mode:
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);
- }
-}