diff options
author | Rob Purchase <shotofadds@rockbox.org> | 2008-06-22 18:48:22 +0000 |
---|---|---|
committer | Rob Purchase <shotofadds@rockbox.org> | 2008-06-22 18:48:22 +0000 |
commit | d6159ea7d7cea65c4bed46f07b5e70da2b9aa0f7 (patch) | |
tree | 0f8d6a8355d270fb86bb9fbad41732981c2a8f46 /firmware/drivers | |
parent | 20baeca44d123c8a7a6c10d36949efa7ba6773f6 (diff) | |
download | rockbox-d6159ea7d7cea65c4bed46f07b5e70da2b9aa0f7.tar.gz rockbox-d6159ea7d7cea65c4bed46f07b5e70da2b9aa0f7.zip |
Initial D2 sound playback support (known issues to follow on the CowonD2Info wiki page).
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@17753 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/drivers')
-rw-r--r-- | firmware/drivers/audio/wm8985.c | 111 |
1 files changed, 41 insertions, 70 deletions
diff --git a/firmware/drivers/audio/wm8985.c b/firmware/drivers/audio/wm8985.c index 6f8d65998b..411bd97c59 100644 --- a/firmware/drivers/audio/wm8985.c +++ b/firmware/drivers/audio/wm8985.c | |||
@@ -86,18 +86,6 @@ | |||
86 | #define OUT4MIX 0x39 | 86 | #define OUT4MIX 0x39 |
87 | #define BIASCTL 0x3d | 87 | #define BIASCTL 0x3d |
88 | 88 | ||
89 | /* Register settings for the supported samplerates: */ | ||
90 | #define WM8985_8000HZ 0x4d | ||
91 | #define WM8985_12000HZ 0x61 | ||
92 | #define WM8985_16000HZ 0x55 | ||
93 | #define WM8985_22050HZ 0x77 | ||
94 | #define WM8985_24000HZ 0x79 | ||
95 | #define WM8985_32000HZ 0x59 | ||
96 | #define WM8985_44100HZ 0x63 | ||
97 | #define WM8985_48000HZ 0x41 | ||
98 | #define WM8985_88200HZ 0x7f | ||
99 | #define WM8985_96000HZ 0x5d | ||
100 | |||
101 | const struct sound_settings_info audiohw_settings[] = { | 89 | const struct sound_settings_info audiohw_settings[] = { |
102 | [SOUND_VOLUME] = {"dB", 0, 1, -58, 6, -25}, | 90 | [SOUND_VOLUME] = {"dB", 0, 1, -58, 6, -25}, |
103 | [SOUND_BASS] = {"dB", 0, 1, -12, 12, 0}, | 91 | [SOUND_BASS] = {"dB", 0, 1, -12, 12, 0}, |
@@ -136,19 +124,6 @@ int tenthdb2master(int db) | |||
136 | } | 124 | } |
137 | } | 125 | } |
138 | 126 | ||
139 | /* convert tenth of dB volume (-780..0) to mixer volume register value */ | ||
140 | int tenthdb2mixer(int db) | ||
141 | { | ||
142 | if (db < -660) /* 1.5 dB steps */ | ||
143 | return (2640 - db) / 15; | ||
144 | else if (db < -600) /* 0.75 dB steps */ | ||
145 | return (990 - db) * 2 / 15; | ||
146 | else if (db < -460) /* 0.5 dB steps */ | ||
147 | return (460 - db) / 5; | ||
148 | else /* 0.25 dB steps */ | ||
149 | return -db * 2 / 5; | ||
150 | } | ||
151 | |||
152 | /* Silently enable / disable audio output */ | 127 | /* Silently enable / disable audio output */ |
153 | void audiohw_enable_output(bool enable) | 128 | void audiohw_enable_output(bool enable) |
154 | { | 129 | { |
@@ -157,32 +132,53 @@ void audiohw_enable_output(bool enable) | |||
157 | /* TODO: reset the I2S controller into known state */ | 132 | /* TODO: reset the I2S controller into known state */ |
158 | //i2s_reset(); | 133 | //i2s_reset(); |
159 | 134 | ||
160 | /* TODO: Review the power-up sequence to prevent pops (see datasheet) */ | 135 | wmcodec_write(RESET, 0x1ff); /* Reset */ |
161 | 136 | ||
162 | wmcodec_write(RESET, 0x1ff); /*Reset*/ | 137 | wmcodec_write(BIASCTL, 0x100); /* BIASCUT = 1 */ |
138 | wmcodec_write(OUTCTRL, 0x6); /* Thermal shutdown */ | ||
163 | 139 | ||
164 | wmcodec_write(PWRMGMT1, 0x2b); | 140 | wmcodec_write(PWRMGMT1, 0x8); /* BIASEN = 1 */ |
165 | wmcodec_write(PWRMGMT2, 0x180); | 141 | |
142 | /* Volume zero, mute all outputs */ | ||
143 | wmcodec_write(LOUT1VOL, 0x140); | ||
144 | wmcodec_write(ROUT1VOL, 0x140); | ||
145 | wmcodec_write(LOUT2VOL, 0x140); | ||
146 | wmcodec_write(ROUT2VOL, 0x140); | ||
147 | wmcodec_write(OUT3MIX, 0x40); | ||
148 | wmcodec_write(OUT4MIX, 0x40); | ||
149 | |||
150 | /* DAC softmute, automute, 128OSR */ | ||
151 | wmcodec_write(DACCTRL, 0x4c); | ||
152 | |||
153 | wmcodec_write(OUT4ADC, 0x2); /* POBCTRL = 1 */ | ||
154 | |||
155 | /* Enable output, DAC and mixer */ | ||
166 | wmcodec_write(PWRMGMT3, 0x6f); | 156 | wmcodec_write(PWRMGMT3, 0x6f); |
157 | wmcodec_write(PWRMGMT2, 0x180); | ||
158 | wmcodec_write(PWRMGMT1, 0xd); | ||
159 | wmcodec_write(LOUTMIX, 0x1); | ||
160 | wmcodec_write(ROUTMIX, 0x1); | ||
167 | 161 | ||
168 | wmcodec_write(AINTFCE, 0x10); | 162 | /* Disable clock since we're acting as slave to the SoC */ |
169 | wmcodec_write(CLKCTRL, 0x49); | 163 | wmcodec_write(CLKGEN, 0x0); |
164 | wmcodec_write(AINTFCE, 0x10); /* 16-bit, I2S format */ | ||
170 | 165 | ||
171 | wmcodec_write(OUTCTRL, 1); | 166 | wmcodec_write(LDACVOL, 0x1ff); /* Full DAC digital vol */ |
167 | wmcodec_write(RDACVOL, 0x1ff); | ||
172 | 168 | ||
173 | /* The iPod can handle multiple frequencies, but fix at 44.1KHz | 169 | wmcodec_write(OUT4ADC, 0x0); /* POBCTRL = 0 */ |
174 | for now */ | 170 | |
175 | audiohw_set_sample_rate(WM8985_44100HZ); | 171 | sleep(HZ/2); |
176 | 172 | ||
177 | wmcodec_write(LOUTMIX,0x1); /* Enable mixer */ | ||
178 | wmcodec_write(ROUTMIX,0x1); /* Enable mixer */ | ||
179 | audiohw_mute(0); | 173 | audiohw_mute(0); |
180 | } else { | 174 | } |
175 | else | ||
176 | { | ||
181 | audiohw_mute(1); | 177 | audiohw_mute(1); |
182 | } | 178 | } |
183 | } | 179 | } |
184 | 180 | ||
185 | void audiohw_set_master_vol(int vol_l, int vol_r) | 181 | void audiohw_set_headphone_vol(int vol_l, int vol_r) |
186 | { | 182 | { |
187 | /* OUT1 */ | 183 | /* OUT1 */ |
188 | wmcodec_write(LOUT1VOL, 0x080 | vol_l); | 184 | wmcodec_write(LOUT1VOL, 0x080 | vol_l); |
@@ -196,12 +192,6 @@ void audiohw_set_lineout_vol(int vol_l, int vol_r) | |||
196 | wmcodec_write(ROUT2VOL, 0x100 | vol_r); | 192 | wmcodec_write(ROUT2VOL, 0x100 | vol_r); |
197 | } | 193 | } |
198 | 194 | ||
199 | void audiohw_set_mixer_vol(int channel1, int channel2) | ||
200 | { | ||
201 | (void)channel1; | ||
202 | (void)channel2; | ||
203 | } | ||
204 | |||
205 | void audiohw_set_bass(int value) | 195 | void audiohw_set_bass(int value) |
206 | { | 196 | { |
207 | eq1_reg = (eq1_reg & ~EQ_GAIN_MASK) | EQ_GAIN_VALUE(value); | 197 | eq1_reg = (eq1_reg & ~EQ_GAIN_MASK) | EQ_GAIN_VALUE(value); |
@@ -231,14 +221,14 @@ void audiohw_mute(bool mute) | |||
231 | if (mute) | 221 | if (mute) |
232 | { | 222 | { |
233 | /* Set DACMU = 1 to soft-mute the audio DACs. */ | 223 | /* Set DACMU = 1 to soft-mute the audio DACs. */ |
234 | wmcodec_write(DACCTRL, 0x40); | 224 | wmcodec_write(DACCTRL, 0x4c); |
235 | } else { | 225 | } else { |
236 | /* Set DACMU = 0 to soft-un-mute the audio DACs. */ | 226 | /* Set DACMU = 0 to soft-un-mute the audio DACs. */ |
237 | wmcodec_write(DACCTRL, 0x0); | 227 | wmcodec_write(DACCTRL, 0xc); |
238 | } | 228 | } |
239 | } | 229 | } |
240 | 230 | ||
241 | /* Nice shutdown of WM8758 codec */ | 231 | /* Nice shutdown of WM8985 codec */ |
242 | void audiohw_close(void) | 232 | void audiohw_close(void) |
243 | { | 233 | { |
244 | audiohw_mute(1); | 234 | audiohw_mute(1); |
@@ -250,32 +240,13 @@ void audiohw_close(void) | |||
250 | wmcodec_write(PWRMGMT2, 0x40); | 240 | wmcodec_write(PWRMGMT2, 0x40); |
251 | } | 241 | } |
252 | 242 | ||
253 | /* Change the order of the noise shaper, 5th order is recommended above 32kHz */ | ||
254 | void audiohw_set_nsorder(int order) | ||
255 | { | ||
256 | (void)order; | ||
257 | } | ||
258 | |||
259 | /* Note: Disable output before calling this function */ | 243 | /* Note: Disable output before calling this function */ |
260 | void audiohw_set_sample_rate(int sampling_control) | 244 | void audiohw_set_sample_rate(int sampling_control) |
261 | { | 245 | { |
262 | /**** We force 44.1KHz for now. ****/ | 246 | /* Currently the WM8985 acts as slave to the SoC I2S controller, so no |
247 | setup is needed here. This seems to be in contrast to every other WM | ||
248 | driver in Rockbox, so this may need to change in the future. */ | ||
263 | (void)sampling_control; | 249 | (void)sampling_control; |
264 | |||
265 | /* set clock div */ | ||
266 | wmcodec_write(CLKCTRL, 1 | (0 << 2) | (2 << 5)); | ||
267 | |||
268 | /* setup PLL for MHZ=11.2896 */ | ||
269 | wmcodec_write(PLLN, (1 << 4) | 0x7); | ||
270 | wmcodec_write(PLLK1, 0x21); | ||
271 | wmcodec_write(PLLK2, 0x161); | ||
272 | wmcodec_write(PLLK3, 0x26); | ||
273 | |||
274 | /* set clock div */ | ||
275 | wmcodec_write(CLKCTRL, 1 | (1 << 2) | (2 << 5) | (1 << 8)); | ||
276 | |||
277 | /* set srate */ | ||
278 | wmcodec_write(SRATECTRL, (0 << 1)); | ||
279 | } | 250 | } |
280 | 251 | ||
281 | #ifdef HAVE_RECORDING | 252 | #ifdef HAVE_RECORDING |