summaryrefslogtreecommitdiff
path: root/firmware/target
diff options
context:
space:
mode:
authorMichael Sevakis <jethead71@rockbox.org>2010-06-26 10:07:17 +0000
committerMichael Sevakis <jethead71@rockbox.org>2010-06-26 10:07:17 +0000
commitb15a523870d6aa45b38b92547053beb986b92d9a (patch)
tree8b75fe5f13a3418186cb11c01062ad415490036b /firmware/target
parentac622c6d673c708d48527db8a189401422a5d03c (diff)
downloadrockbox-b15a523870d6aa45b38b92547053beb986b92d9a.tar.gz
rockbox-b15a523870d6aa45b38b92547053beb986b92d9a.zip
e200v1/c200v1: Implement limited samplerate switching. Rates 24kHz and below are being a bear as far as minor crackling at higher amplitude-- leave them out for the time being since no solution is currently evident. 48, 44, 32 (rec rates 24, 22, 16) seem perfectly fine. I'm betting c200 is ok to include because it uses the same setup as e200.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@27139 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/target')
-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 @@
28#include "system.h" 28#include "system.h"
29#include "cpu.h" 29#include "cpu.h"
30#include "i2s.h" 30#include "i2s.h"
31#if defined (SANSA_E200) || defined (SANSA_C200)
32#include "audiohw.h"
33#include "pcm_sampr.h"
34#endif
31 35
32#if CONFIG_CPU == PP5002 36#if CONFIG_CPU == PP5002
33void i2s_reset(void) 37void i2s_reset(void)
@@ -70,6 +74,8 @@ void i2s_reset(void)
70 IISCLK = (IISCLK & ~0x1ff) | 31; 74 IISCLK = (IISCLK & ~0x1ff) | 31;
71 IISDIV = (IISDIV & ~0xc0000000) | (2 << 30); 75 IISDIV = (IISDIV & ~0xc0000000) | (2 << 30);
72 IISDIV = (IISDIV & ~0x3f) | 16; 76 IISDIV = (IISDIV & ~0x3f) | 16;
77#elif defined (SANSA_E200) || defined (SANSA_C200)
78 audiohw_set_sampr_dividers(HW_FREQ_DEFAULT);
73#else 79#else
74 IISCLK = (IISCLK & ~0x1ff) | 33; 80 IISCLK = (IISCLK & ~0x1ff) | 33;
75 IISDIV = 7; 81 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 @@
22#include "cpu.h" 22#include "cpu.h"
23#include "audio.h" 23#include "audio.h"
24#include "sound.h" 24#include "sound.h"
25#include "general.h"
25 26
26int audio_channels = 2; 27int audio_channels = 2;
27int audio_output_source = AUDIO_SRC_PLAYBACK; 28int audio_output_source = AUDIO_SRC_PLAYBACK;
@@ -92,3 +93,85 @@ void audio_input_mux(int source, unsigned flags)
92 93
93 last_source = source; 94 last_source = source;
94} /* audio_input_mux */ 95} /* audio_input_mux */
96
97
98void audiohw_set_sampr_dividers(int fsel)
99{
100 /* Seems to predivide 24MHz by 2 for a source clock of 12MHz. Maybe
101 * there's a way to set that? */
102 static const struct
103 {
104 unsigned char iisclk;
105 unsigned char iisdiv;
106 } regvals[HW_NUM_FREQ] =
107 {
108 /* 8kHz - 24kHz work well but there seems to be a minor crackling
109 * issue for playback at times and all possibilities were checked
110 * for the divisors without any positive change.
111 * 32kHz - 48kHz seem fine all around. */
112#if 0
113 [HW_FREQ_8] = /* CLK / 1500 (8000Hz) */
114 {
115 .iisclk = 24,
116 .iisdiv = 59,
117 },
118 [HW_FREQ_11] = /* CLK / 1088 (~11029.41Hz) */
119 {
120 .iisclk = 33,
121 .iisdiv = 31,
122 },
123 [HW_FREQ_12] = /* CLK / 1000 (120000Hz) */
124 {
125 .iisclk = 49,
126 .iisdiv = 19,
127 },
128 [HW_FREQ_16] = /* CLK / 750 (16000Hz) */
129 {
130 .iisclk = 24,
131 .iisdiv = 29,
132 },
133 [HW_FREQ_22] = /* CLK / 544 (~22058.82Hz) */
134 {
135 .iisclk = 33,
136 .iisdiv = 15,
137 },
138 [HW_FREQ_24] = /* CLK / 500 (24000Hz) */
139 {
140 .iisclk = 49,
141 .iisdiv = 9,
142 },
143#endif
144 [HW_FREQ_32] = /* CLK / 375 (32000Hz) */
145 {
146 .iisclk = 24,
147 .iisdiv = 14,
148 },
149 [HW_FREQ_44] = /* CLK / 272 (~44117.68Hz) */
150 {
151 .iisclk = 33,
152 .iisdiv = 7,
153 },
154 [HW_FREQ_48] = /* CLK / 250 (48000Hz) */
155 {
156 .iisclk = 49,
157 .iisdiv = 4,
158 },
159 /* going a bit higher would be nice to get 64kHz play, 32kHz rec, but a
160 * close enough division isn't obtainable unless CLK can be changed */
161 };
162
163 IISCLK = (IISCLK & ~0x17ff) | regvals[fsel].iisclk;
164 IISDIV = (IISDIV & ~0xc000003f) | regvals[fsel].iisdiv;
165}
166
167unsigned int pcm_sampr_type_rec_to_play(unsigned int samplerate)
168{
169 /* Check if the samplerate is in the list of recordable rates.
170 * Fail to default if not */
171 int index = round_value_to_list32(samplerate, rec_freq_sampr,
172 REC_NUM_FREQ, false);
173 if (samplerate != rec_freq_sampr[index])
174 return HW_SAMPR_DEFAULT;
175
176 return samplerate * 2; /* Recording rates are 1/2 the codec clock */
177}