diff options
Diffstat (limited to 'firmware/target/arm/sandisk/audio-c200_e200.c')
-rw-r--r-- | firmware/target/arm/sandisk/audio-c200_e200.c | 83 |
1 files changed, 83 insertions, 0 deletions
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 */ +} |