summaryrefslogtreecommitdiffstats
path: root/firmware/target/arm
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/arm')
-rw-r--r--firmware/target/arm/i2s-pp.c6
-rw-r--r--firmware/target/arm/sandisk/audio-c200_e200.c83
2 files changed, 89 insertions, 0 deletions
diff --git a/firmware/target/arm/i2s-pp.c b/firmware/target/arm/i2s-pp.c
index c9d66d53ae..83f39515c4 100644
--- a/firmware/target/arm/i2s-pp.c
+++ b/firmware/target/arm/i2s-pp.c
@@ -28,6 +28,10 @@
#include "system.h"
#include "cpu.h"
#include "i2s.h"
+#if defined (SANSA_E200) || defined (SANSA_C200)
+#include "audiohw.h"
+#include "pcm_sampr.h"
+#endif
#if CONFIG_CPU == PP5002
void i2s_reset(void)
@@ -70,6 +74,8 @@ void i2s_reset(void)
IISCLK = (IISCLK & ~0x1ff) | 31;
IISDIV = (IISDIV & ~0xc0000000) | (2 << 30);
IISDIV = (IISDIV & ~0x3f) | 16;
+#elif defined (SANSA_E200) || defined (SANSA_C200)
+ audiohw_set_sampr_dividers(HW_FREQ_DEFAULT);
#else
IISCLK = (IISCLK & ~0x1ff) | 33;
IISDIV = 7;
diff --git a/firmware/target/arm/sandisk/audio-c200_e200.c b/firmware/target/arm/sandisk/audio-c200_e200.c
index 1d78e71541..0037bac58b 100644
--- a/firmware/target/arm/sandisk/audio-c200_e200.c
+++ b/firmware/target/arm/sandisk/audio-c200_e200.c
@@ -22,6 +22,7 @@
#include "cpu.h"
#include "audio.h"
#include "sound.h"
+#include "general.h"
int audio_channels = 2;
int audio_output_source = AUDIO_SRC_PLAYBACK;
@@ -92,3 +93,85 @@ void audio_input_mux(int source, unsigned flags)
last_source = source;
} /* audio_input_mux */
+
+
+void audiohw_set_sampr_dividers(int fsel)
+{
+ /* Seems to predivide 24MHz by 2 for a source clock of 12MHz. Maybe
+ * there's a way to set that? */
+ static const struct
+ {
+ unsigned char iisclk;
+ unsigned char iisdiv;
+ } regvals[HW_NUM_FREQ] =
+ {
+ /* 8kHz - 24kHz work well but there seems to be a minor crackling
+ * issue for playback at times and all possibilities were checked
+ * for the divisors without any positive change.
+ * 32kHz - 48kHz seem fine all around. */
+#if 0
+ [HW_FREQ_8] = /* CLK / 1500 (8000Hz) */
+ {
+ .iisclk = 24,
+ .iisdiv = 59,
+ },
+ [HW_FREQ_11] = /* CLK / 1088 (~11029.41Hz) */
+ {
+ .iisclk = 33,
+ .iisdiv = 31,
+ },
+ [HW_FREQ_12] = /* CLK / 1000 (120000Hz) */
+ {
+ .iisclk = 49,
+ .iisdiv = 19,
+ },
+ [HW_FREQ_16] = /* CLK / 750 (16000Hz) */
+ {
+ .iisclk = 24,
+ .iisdiv = 29,
+ },
+ [HW_FREQ_22] = /* CLK / 544 (~22058.82Hz) */
+ {
+ .iisclk = 33,
+ .iisdiv = 15,
+ },
+ [HW_FREQ_24] = /* CLK / 500 (24000Hz) */
+ {
+ .iisclk = 49,
+ .iisdiv = 9,
+ },
+#endif
+ [HW_FREQ_32] = /* CLK / 375 (32000Hz) */
+ {
+ .iisclk = 24,
+ .iisdiv = 14,
+ },
+ [HW_FREQ_44] = /* CLK / 272 (~44117.68Hz) */
+ {
+ .iisclk = 33,
+ .iisdiv = 7,
+ },
+ [HW_FREQ_48] = /* CLK / 250 (48000Hz) */
+ {
+ .iisclk = 49,
+ .iisdiv = 4,
+ },
+ /* going a bit higher would be nice to get 64kHz play, 32kHz rec, but a
+ * close enough division isn't obtainable unless CLK can be changed */
+ };
+
+ IISCLK = (IISCLK & ~0x17ff) | regvals[fsel].iisclk;
+ IISDIV = (IISDIV & ~0xc000003f) | regvals[fsel].iisdiv;
+}
+
+unsigned int pcm_sampr_type_rec_to_play(unsigned int samplerate)
+{
+ /* Check if the samplerate is in the list of recordable rates.
+ * Fail to default if not */
+ int index = round_value_to_list32(samplerate, rec_freq_sampr,
+ REC_NUM_FREQ, false);
+ if (samplerate != rec_freq_sampr[index])
+ return HW_SAMPR_DEFAULT;
+
+ return samplerate * 2; /* Recording rates are 1/2 the codec clock */
+}