diff options
author | Michael Sevakis <jethead71@rockbox.org> | 2007-10-02 07:48:50 +0000 |
---|---|---|
committer | Michael Sevakis <jethead71@rockbox.org> | 2007-10-02 07:48:50 +0000 |
commit | 15b7321fe1345a9efd296fe135f19e1da45f0e7c (patch) | |
tree | e2b704e2e0dd20d8d6d46e6fedc159fafc7fdca4 | |
parent | 4d34457cd0a1958ff271bb2d87bfdba1432b678e (diff) | |
download | rockbox-15b7321fe1345a9efd296fe135f19e1da45f0e7c.tar.gz rockbox-15b7321fe1345a9efd296fe135f19e1da45f0e7c.zip |
Split wm8731 and wm8721 drivers. wm8721 can be much simpler since it has no recording. Provide reg bit definitions for those. Add some temporary hacks pcm-pp to prevent crashing when playing after recording. Make playback start after recording on pp5020. Get wm8731 to monitor recording but plans are to do that digitally.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@14948 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r-- | firmware/SOURCES | 6 | ||||
-rw-r--r-- | firmware/drivers/audio/wm8721.c (renamed from firmware/drivers/audio/wm8731l.c) | 126 | ||||
-rw-r--r-- | firmware/drivers/audio/wm8731.c | 324 | ||||
-rw-r--r-- | firmware/export/audiohw.h | 6 | ||||
-rw-r--r-- | firmware/export/wm8731.h | 141 | ||||
-rw-r--r-- | firmware/export/wm8731l.h | 65 | ||||
-rw-r--r-- | firmware/sound.c | 4 | ||||
-rw-r--r-- | firmware/target/arm/pcm-pp.c | 49 | ||||
-rw-r--r-- | firmware/target/arm/wmcodec-pp.c | 10 |
9 files changed, 522 insertions, 209 deletions
diff --git a/firmware/SOURCES b/firmware/SOURCES index 72712b6b6c..1079fabec9 100644 --- a/firmware/SOURCES +++ b/firmware/SOURCES | |||
@@ -214,8 +214,10 @@ drivers/audio/wm8751.c | |||
214 | drivers/audio/wm8975.c | 214 | drivers/audio/wm8975.c |
215 | #elif defined(HAVE_WM8758) | 215 | #elif defined(HAVE_WM8758) |
216 | drivers/audio/wm8758.c | 216 | drivers/audio/wm8758.c |
217 | #elif defined(HAVE_WM8731) || defined(HAVE_WM8721) | 217 | #elif defined(HAVE_WM8721) |
218 | drivers/audio/wm8731l.c | 218 | drivers/audio/wm8721.c |
219 | #elif defined(HAVE_WM8731) | ||
220 | drivers/audio/wm8731.c | ||
219 | #elif defined(HAVE_AS3514) | 221 | #elif defined(HAVE_AS3514) |
220 | drivers/audio/as3514.c | 222 | drivers/audio/as3514.c |
221 | #elif defined(HAVE_TLV320) | 223 | #elif defined(HAVE_TLV320) |
diff --git a/firmware/drivers/audio/wm8731l.c b/firmware/drivers/audio/wm8721.c index 94efc535e2..9b58454ca8 100644 --- a/firmware/drivers/audio/wm8731l.c +++ b/firmware/drivers/audio/wm8721.c | |||
@@ -7,7 +7,7 @@ | |||
7 | * \/ \/ \/ \/ \/ | 7 | * \/ \/ \/ \/ \/ |
8 | * $Id$ | 8 | * $Id$ |
9 | * | 9 | * |
10 | * Driver for WM8731L audio codec | 10 | * Driver for WM8721 audio codec |
11 | * | 11 | * |
12 | * Based on code from the ipodlinux project - http://ipodlinux.org/ | 12 | * Based on code from the ipodlinux project - http://ipodlinux.org/ |
13 | * Adapted for Rockbox in January 2006 | 13 | * Adapted for Rockbox in January 2006 |
@@ -46,11 +46,6 @@ const struct sound_settings_info audiohw_settings[] = { | |||
46 | [SOUND_BALANCE] = {"%", 0, 1,-100, 100, 0}, | 46 | [SOUND_BALANCE] = {"%", 0, 1,-100, 100, 0}, |
47 | [SOUND_CHANNELS] = {"", 0, 1, 0, 5, 0}, | 47 | [SOUND_CHANNELS] = {"", 0, 1, 0, 5, 0}, |
48 | [SOUND_STEREO_WIDTH] = {"%", 0, 1, 0, 255, 100}, | 48 | [SOUND_STEREO_WIDTH] = {"%", 0, 1, 0, 255, 100}, |
49 | #ifdef HAVE_RECORDING | ||
50 | [SOUND_LEFT_GAIN] = {"dB", 1, 1,-128, 96, 0}, | ||
51 | [SOUND_RIGHT_GAIN] = {"dB", 1, 1,-128, 96, 0}, | ||
52 | [SOUND_MIC_GAIN] = {"dB", 1, 1,-128, 108, 16}, | ||
53 | #endif | ||
54 | }; | 49 | }; |
55 | 50 | ||
56 | /* convert tenth of dB volume (-730..60) to master volume register value */ | 51 | /* convert tenth of dB volume (-730..60) to master volume register value */ |
@@ -118,13 +113,8 @@ void audiohw_enable_output(bool enable) | |||
118 | 113 | ||
119 | codec_set_active(0x0); | 114 | codec_set_active(0x0); |
120 | 115 | ||
121 | #ifdef HAVE_WM8721 | ||
122 | /* DACSEL=1 */ | 116 | /* DACSEL=1 */ |
123 | wmcodec_write(0x4, 0x10); | 117 | wmcodec_write(0x4, 0x10); |
124 | #elif defined HAVE_WM8731 | ||
125 | /* DACSEL=1, BYPASS=1 */ | ||
126 | wmcodec_write(0x4, 0x18); | ||
127 | #endif | ||
128 | 118 | ||
129 | /* set power register to POWEROFF=0 on OUTPD=0, DACPD=0 */ | 119 | /* set power register to POWEROFF=0 on OUTPD=0, DACPD=0 */ |
130 | wmcodec_write(PWRMGMT, 0x67); | 120 | wmcodec_write(PWRMGMT, 0x67); |
@@ -133,7 +123,7 @@ void audiohw_enable_output(bool enable) | |||
133 | /* IWL=00(16 bit) FORMAT=10(I2S format) */ | 123 | /* IWL=00(16 bit) FORMAT=10(I2S format) */ |
134 | wmcodec_write(AINTFCE, 0x42); | 124 | wmcodec_write(AINTFCE, 0x42); |
135 | 125 | ||
136 | audiohw_set_sample_rate(WM8731L_44100HZ); | 126 | audiohw_set_sample_rate(WM8721_USB24_44100HZ); |
137 | 127 | ||
138 | /* set the volume to -6dB */ | 128 | /* set the volume to -6dB */ |
139 | wmcodec_write(LOUTVOL, IPOD_PCM_LEVEL); | 129 | wmcodec_write(LOUTVOL, IPOD_PCM_LEVEL); |
@@ -145,16 +135,8 @@ void audiohw_enable_output(bool enable) | |||
145 | /* 5. Set DACMU = 0 to soft-un-mute the audio DACs. */ | 135 | /* 5. Set DACMU = 0 to soft-un-mute the audio DACs. */ |
146 | wmcodec_write(DACCTRL, 0x0); | 136 | wmcodec_write(DACCTRL, 0x0); |
147 | 137 | ||
148 | #if defined(IRIVER_H10) || defined(IRIVER_H10_5GB) | ||
149 | /* We need to enable bit 4 of GPIOL for output for sound on H10 */ | ||
150 | GPIOL_OUTPUT_VAL |= 0x10; | ||
151 | #endif | ||
152 | audiohw_mute(0); | 138 | audiohw_mute(0); |
153 | } else { | 139 | } else { |
154 | #if defined(IRIVER_H10) || defined(IRIVER_H10_5GB) | ||
155 | /* We need to disable bit 4 of GPIOL to disable sound on H10 */ | ||
156 | GPIOL_OUTPUT_VAL &= ~0x10; | ||
157 | #endif | ||
158 | audiohw_mute(1); | 140 | audiohw_mute(1); |
159 | } | 141 | } |
160 | } | 142 | } |
@@ -166,32 +148,13 @@ int audiohw_set_master_vol(int vol_l, int vol_r) | |||
166 | /* 1111001 == 0dB */ | 148 | /* 1111001 == 0dB */ |
167 | /* 0110000 == -73dB */ | 149 | /* 0110000 == -73dB */ |
168 | /* 0101111 == mute (0x2f) */ | 150 | /* 0101111 == mute (0x2f) */ |
169 | |||
170 | wmcodec_write(LOUTVOL, VOLUME_ZC_WAIT | vol_l); | 151 | wmcodec_write(LOUTVOL, VOLUME_ZC_WAIT | vol_l); |
171 | wmcodec_write(ROUTVOL, VOLUME_ZC_WAIT | vol_r); | 152 | wmcodec_write(ROUTVOL, VOLUME_ZC_WAIT | vol_r); |
172 | 153 | ||
173 | return 0; | 154 | return 0; |
174 | } | 155 | } |
175 | 156 | ||
176 | int audiohw_set_mixer_vol(int channel1, int channel2) | 157 | /* Nice shutdown of WM8721 codec */ |
177 | { | ||
178 | (void)channel1; | ||
179 | (void)channel2; | ||
180 | |||
181 | return 0; | ||
182 | } | ||
183 | |||
184 | void audiohw_set_bass(int value) | ||
185 | { | ||
186 | (void)value; | ||
187 | } | ||
188 | |||
189 | void audiohw_set_treble(int value) | ||
190 | { | ||
191 | (void)value; | ||
192 | } | ||
193 | |||
194 | /* Nice shutdown of WM8731 codec */ | ||
195 | void audiohw_close(void) | 158 | void audiohw_close(void) |
196 | { | 159 | { |
197 | /* set DACMU=1 DEEMPH=0 */ | 160 | /* set DACMU=1 DEEMPH=0 */ |
@@ -225,86 +188,3 @@ void audiohw_set_sample_rate(int sampling_control) | |||
225 | wmcodec_write(SAMPCTRL, sampling_control); | 188 | wmcodec_write(SAMPCTRL, sampling_control); |
226 | codec_set_active(0x1); | 189 | codec_set_active(0x1); |
227 | } | 190 | } |
228 | |||
229 | void audiohw_enable_recording(bool source_mic) | ||
230 | { | ||
231 | static int line_level = 0x17; | ||
232 | static int mic_boost = true; | ||
233 | codec_set_active(0x0); | ||
234 | |||
235 | /* set BCLKINV=0(Dont invert BCLK) MS=1(Enable Master) LRSWAP=0 | ||
236 | * LRP=0 IWL=00(16 bit) FORMAT=10(I2S format) */ | ||
237 | wmcodec_write(AINTFCE, 0x42); | ||
238 | |||
239 | wmcodec_write(LOUTVOL, 0x0); /* headphone mute left */ | ||
240 | wmcodec_write(ROUTVOL, 0x0); /* headphone mute right */ | ||
241 | |||
242 | |||
243 | if(source_mic){ | ||
244 | wmcodec_write(LINVOL, 0x80); /* line in mute left */ | ||
245 | wmcodec_write(RINVOL, 0x80); /* line in mute right */ | ||
246 | |||
247 | |||
248 | if (mic_boost) { | ||
249 | wmcodec_write(AAPCTRL, 0x5); /* INSEL=mic, MIC_BOOST=enable */ | ||
250 | } else { | ||
251 | wmcodec_write(AAPCTRL, 0x4); /* INSEL=mic */ | ||
252 | } | ||
253 | } else { | ||
254 | if (line_level == 0) { | ||
255 | wmcodec_write(LINVOL, 0x80); | ||
256 | wmcodec_write(RINVOL, 0x80); | ||
257 | } else { | ||
258 | wmcodec_write(LINVOL, line_level); | ||
259 | wmcodec_write(RINVOL, line_level); | ||
260 | } | ||
261 | wmcodec_write(AAPCTRL, 0xa); /* BY PASS, mute mic, INSEL=line in */ | ||
262 | } | ||
263 | |||
264 | /* disable ADC high pass filter, mute dac */ | ||
265 | wmcodec_write(DACCTRL, 0x9); | ||
266 | |||
267 | /* power on (PWR_OFF=0) */ | ||
268 | if(source_mic){ | ||
269 | /* CLKOUTPD OSCPD OUTPD DACPD LINEINPD */ | ||
270 | wmcodec_write(PWRMGMT, 0x79); | ||
271 | } else { | ||
272 | wmcodec_write(PWRMGMT, 0x7a); /* MICPD */ | ||
273 | } | ||
274 | |||
275 | codec_set_active(0x1); | ||
276 | } | ||
277 | |||
278 | void audiohw_disable_recording(void) | ||
279 | { | ||
280 | /* set DACMU=1 DEEMPH=0 */ | ||
281 | wmcodec_write(DACCTRL, 0x8); | ||
282 | |||
283 | /* ACTIVE=0 */ | ||
284 | codec_set_active(0x0); | ||
285 | |||
286 | /* line in mute left & right*/ | ||
287 | wmcodec_write(LINVOL, 0x80); | ||
288 | wmcodec_write(RINVOL, 0x80); | ||
289 | |||
290 | /* set DACSEL=0, MUTEMIC=1 */ | ||
291 | wmcodec_write(AAPCTRL, 0x2); | ||
292 | |||
293 | /* set POWEROFF=0 OUTPD=0 DACPD=1 */ | ||
294 | wmcodec_write(PWRMGMT, 0x6f); | ||
295 | |||
296 | /* set POWEROFF=1 OUTPD=1 DACPD=1 */ | ||
297 | wmcodec_write(PWRMGMT, 0xff); | ||
298 | } | ||
299 | |||
300 | void audiohw_set_recvol(int left, int right, int type) | ||
301 | { | ||
302 | (void)left; | ||
303 | (void)right; | ||
304 | (void)type; | ||
305 | } | ||
306 | |||
307 | void audiohw_set_monitor(int enable) | ||
308 | { | ||
309 | (void)enable; | ||
310 | } | ||
diff --git a/firmware/drivers/audio/wm8731.c b/firmware/drivers/audio/wm8731.c new file mode 100644 index 0000000000..2e1a978777 --- /dev/null +++ b/firmware/drivers/audio/wm8731.c | |||
@@ -0,0 +1,324 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Driver for WM8731L audio codec | ||
11 | * | ||
12 | * Based on code from the ipodlinux project - http://ipodlinux.org/ | ||
13 | * Adapted for Rockbox in January 2006 | ||
14 | * | ||
15 | * Original file: linux/arch/armnommu/mach-ipod/audio.c | ||
16 | * | ||
17 | * Copyright (c) 2003-2005 Bernard Leach (leachbj@bouncycastle.org) | ||
18 | * | ||
19 | * All files in this archive are subject to the GNU General Public License. | ||
20 | * See the file COPYING in the source tree root for full license agreement. | ||
21 | * | ||
22 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
23 | * KIND, either express or implied. | ||
24 | * | ||
25 | ****************************************************************************/ | ||
26 | #include "config.h" | ||
27 | #include "logf.h" | ||
28 | #include "system.h" | ||
29 | #include "string.h" | ||
30 | #include "audio.h" | ||
31 | |||
32 | #include "wmcodec.h" | ||
33 | #include "audiohw.h" | ||
34 | #include "i2s.h" | ||
35 | |||
36 | const struct sound_settings_info audiohw_settings[] = { | ||
37 | [SOUND_VOLUME] = {"dB", 0, 1, -74, 6, -25}, | ||
38 | /* HAVE_SW_TONE_CONTROLS */ | ||
39 | [SOUND_BASS] = {"dB", 0, 1, -24, 24, 0}, | ||
40 | [SOUND_TREBLE] = {"dB", 0, 1, -24, 24, 0}, | ||
41 | [SOUND_BALANCE] = {"%", 0, 1,-100, 100, 0}, | ||
42 | [SOUND_CHANNELS] = {"", 0, 1, 0, 5, 0}, | ||
43 | [SOUND_STEREO_WIDTH] = {"%", 0, 1, 0, 255, 100}, | ||
44 | #ifdef HAVE_RECORDING | ||
45 | [SOUND_LEFT_GAIN] = {"dB", 1, 1, 0, 31, 23}, | ||
46 | [SOUND_RIGHT_GAIN] = {"dB", 1, 1, 0, 31, 23}, | ||
47 | [SOUND_MIC_GAIN] = {"dB", 1, 1, 0, 1, 0}, | ||
48 | #endif | ||
49 | }; | ||
50 | |||
51 | /* Init values/shadows | ||
52 | * Ignore bit 8 since that only specifies "both" for updating | ||
53 | * gains */ | ||
54 | static unsigned char wm8731_regs[7] = | ||
55 | { | ||
56 | [LINVOL] = LINVOL_LINMUTE, | ||
57 | [RINVOL] = RINVOL_RINMUTE, | ||
58 | [LOUTVOL] = ROUTVOL_RZCEN, | ||
59 | [ROUTVOL] = ROUTVOL_RZCEN, | ||
60 | [AAPCTRL] = AAPCTRL_MUTEMIC | AAPCTRL_DACSEL, | ||
61 | [DAPCTRL] = DAPCTRL_DACMU | DAPCTRL_DEEMP_44KHz | DAPCTRL_ADCHPD, | ||
62 | [PDCTRL] = PDCTRL_LINEINPD | PDCTRL_MICPD | PDCTRL_ADCPD | | ||
63 | PDCTRL_OUTPD | PDCTRL_OSCPD | PDCTRL_CLKOUTPD, | ||
64 | }; | ||
65 | |||
66 | static void wm8731_write(int reg, unsigned val) | ||
67 | { | ||
68 | wm8731_regs[reg] = (unsigned char)val; | ||
69 | wmcodec_write(reg, val); | ||
70 | } | ||
71 | |||
72 | static void wm8731_write_and(int reg, unsigned bits) | ||
73 | { | ||
74 | wm8731_write(reg, wm8731_regs[reg] & bits); | ||
75 | } | ||
76 | |||
77 | static void wm8731_write_or(int reg, unsigned bits) | ||
78 | { | ||
79 | wm8731_write(reg, wm8731_regs[reg] | bits); | ||
80 | } | ||
81 | |||
82 | /* convert tenth of dB volume (-730..60) to master volume register value */ | ||
83 | int tenthdb2master(int db) | ||
84 | { | ||
85 | /* +6 to -73dB 1dB steps (plus mute == 80levels) 7bits */ | ||
86 | /* 1111111 == +6dB (0x7f) */ | ||
87 | /* 1111001 == 0dB (0x79) */ | ||
88 | /* 0110000 == -73dB (0x30 */ | ||
89 | /* 0101111 == mute (0x2f) */ | ||
90 | |||
91 | if (db < VOLUME_MIN) { | ||
92 | return 0x2f; | ||
93 | } else { | ||
94 | return((db/10)+0x30+73); | ||
95 | } | ||
96 | } | ||
97 | |||
98 | /* convert tenth of dB volume (-780..0) to mixer volume register value */ | ||
99 | int tenthdb2mixer(int db) | ||
100 | { | ||
101 | if (db < -660) /* 1.5 dB steps */ | ||
102 | return (2640 - db) / 15; | ||
103 | else if (db < -600) /* 0.75 dB steps */ | ||
104 | return (990 - db) * 2 / 15; | ||
105 | else if (db < -460) /* 0.5 dB steps */ | ||
106 | return (460 - db) / 5; | ||
107 | else /* 0.25 dB steps */ | ||
108 | return -db * 2 / 5; | ||
109 | } | ||
110 | |||
111 | int sound_val2phys(int setting, int value) | ||
112 | { | ||
113 | int result; | ||
114 | |||
115 | switch(setting) | ||
116 | { | ||
117 | case SOUND_LEFT_GAIN: | ||
118 | case SOUND_RIGHT_GAIN: | ||
119 | result = (value - 23) * 15; | ||
120 | break; | ||
121 | case SOUND_MIC_GAIN: | ||
122 | result = value * 200; | ||
123 | break; | ||
124 | default: | ||
125 | result = value; | ||
126 | break; | ||
127 | } | ||
128 | |||
129 | return result; | ||
130 | } | ||
131 | |||
132 | void audiohw_mute(bool mute) | ||
133 | { | ||
134 | if (mute) { | ||
135 | /* Set DACMU = 1 to soft-mute the audio DACs. */ | ||
136 | wm8731_write_or(DAPCTRL, DAPCTRL_DACMU); | ||
137 | } else { | ||
138 | /* Set DACMU = 0 to soft-un-mute the audio DACs. */ | ||
139 | wm8731_write_and(DAPCTRL, ~DAPCTRL_DACMU); | ||
140 | } | ||
141 | } | ||
142 | |||
143 | static void codec_set_active(int active) | ||
144 | { | ||
145 | /* set active to 0x0 or 0x1 */ | ||
146 | wmcodec_write(ACTIVECTRL, active ? ACTIVECTRL_ACTIVE : 0); | ||
147 | } | ||
148 | |||
149 | void audiohw_preinit(void) | ||
150 | { | ||
151 | i2s_reset(); | ||
152 | |||
153 | /* POWER UP SEQUENCE */ | ||
154 | /* 1) Switch on power supplies. By default the WM8731 is in Standby Mode, | ||
155 | * the DAC is digitally muted and the Audio Interface and Outputs are | ||
156 | * all OFF. */ | ||
157 | wmcodec_write(RESET, RESET_RESET); | ||
158 | |||
159 | /* 2) Set all required bits in the Power Down register (0Ch) to '0'; | ||
160 | * EXCEPT the OUTPD bit, this should be set to '1' (Default). */ | ||
161 | wm8731_write(PDCTRL, wm8731_regs[PDCTRL]); | ||
162 | |||
163 | /* 3) Set required values in all other registers except 12h (Active). */ | ||
164 | wmcodec_write(AINTFCE, AINTFCE_FORMAT_I2S | AINTFCE_IWL_16BIT | | ||
165 | AINTFCE_MS); | ||
166 | wm8731_write(AAPCTRL, wm8731_regs[AAPCTRL]); | ||
167 | wm8731_write(DAPCTRL, wm8731_regs[DAPCTRL]); | ||
168 | wmcodec_write(SAMPCTRL, WM8731_USB24_44100HZ); | ||
169 | |||
170 | /* 5) The last write of the sequence should be setting OUTPD to '0' | ||
171 | * (active) in register 0Ch, enabling the DAC signal path, free | ||
172 | * of any significant power-up noise. */ | ||
173 | wm8731_write_and(PDCTRL, ~PDCTRL_OUTPD); | ||
174 | } | ||
175 | |||
176 | void audiohw_postinit(void) | ||
177 | { | ||
178 | sleep(HZ); | ||
179 | |||
180 | /* 4) Set the ‘Active’ bit in register 12h. */ | ||
181 | codec_set_active(true); | ||
182 | |||
183 | audiohw_mute(false); | ||
184 | |||
185 | #if defined(IRIVER_H10) || defined(IRIVER_H10_5GB) | ||
186 | /* We need to enable bit 4 of GPIOL for output for sound on H10 */ | ||
187 | GPIOL_OUTPUT_VAL |= 0x10; | ||
188 | #endif | ||
189 | } | ||
190 | |||
191 | int audiohw_set_master_vol(int vol_l, int vol_r) | ||
192 | { | ||
193 | /* +6 to -73dB 1dB steps (plus mute == 80levels) 7bits */ | ||
194 | /* 1111111 == +6dB */ | ||
195 | /* 1111001 == 0dB */ | ||
196 | /* 0110000 == -73dB */ | ||
197 | /* 0101111 == mute (0x2f) */ | ||
198 | wm8731_write(LOUTVOL, LOUTVOL_LZCEN | (vol_l & LOUTVOL_LHPVOL_MASK)); | ||
199 | wm8731_write(ROUTVOL, ROUTVOL_RZCEN | (vol_r & ROUTVOL_RHPVOL_MASK)); | ||
200 | return 0; | ||
201 | } | ||
202 | |||
203 | /* Nice shutdown of WM8731 codec */ | ||
204 | void audiohw_close(void) | ||
205 | { | ||
206 | /* POWER DOWN SEQUENCE */ | ||
207 | /* 1) Set the OUTPD bit to '1' (power down). */ | ||
208 | wm8731_write_or(PDCTRL, PDCTRL_OUTPD); | ||
209 | /* 2) Remove the WM8731 supplies. */ | ||
210 | } | ||
211 | |||
212 | void audiohw_set_nsorder(int order) | ||
213 | { | ||
214 | static const unsigned char deemp[4] = | ||
215 | { | ||
216 | DAPCTRL_DEEMP_DISABLE, | ||
217 | DAPCTRL_DEEMP_32KHz, | ||
218 | DAPCTRL_DEEMP_44KHz, | ||
219 | DAPCTRL_DEEMP_48KHz | ||
220 | }; | ||
221 | |||
222 | if ((unsigned)order >= ARRAYLEN(deemp)) | ||
223 | order = 0; | ||
224 | |||
225 | wm8731_write(DAPCTRL, | ||
226 | (wm8731_regs[DAPCTRL] & ~DAPCTRL_DEEMP_MASK) | deemp[order]); | ||
227 | } | ||
228 | |||
229 | void audiohw_set_sample_rate(int sampling_control) | ||
230 | { | ||
231 | codec_set_active(false); | ||
232 | wmcodec_write(SAMPCTRL, sampling_control); | ||
233 | codec_set_active(true); | ||
234 | } | ||
235 | |||
236 | void audiohw_enable_recording(bool source_mic) | ||
237 | { | ||
238 | codec_set_active(false); | ||
239 | |||
240 | wm8731_regs[PDCTRL] &= ~PDCTRL_ADCPD; | ||
241 | wm8731_regs[PDCTRL] |= PDCTRL_DACPD; | ||
242 | wm8731_regs[AAPCTRL] &= ~AAPCTRL_DACSEL; | ||
243 | |||
244 | if (source_mic) { | ||
245 | wm8731_write_or(LINVOL, LINVOL_LINMUTE); | ||
246 | wm8731_write_or(RINVOL, RINVOL_RINMUTE); | ||
247 | wm8731_regs[PDCTRL] &= ~PDCTRL_MICPD; | ||
248 | wm8731_regs[PDCTRL] |= PDCTRL_LINEINPD; | ||
249 | wm8731_regs[AAPCTRL] |= AAPCTRL_INSEL | AAPCTRL_SIDETONE; | ||
250 | wm8731_regs[AAPCTRL] &= ~AAPCTRL_MUTEMIC; | ||
251 | } else { | ||
252 | wm8731_regs[PDCTRL] |= PDCTRL_MICPD; | ||
253 | wm8731_regs[PDCTRL] &= ~PDCTRL_LINEINPD; | ||
254 | wm8731_regs[AAPCTRL] |= AAPCTRL_MUTEMIC | AAPCTRL_BYPASS; | ||
255 | wm8731_regs[AAPCTRL] &= ~(AAPCTRL_INSEL | AAPCTRL_SIDETONE); | ||
256 | } | ||
257 | |||
258 | wm8731_write(PDCTRL, wm8731_regs[PDCTRL]); | ||
259 | wm8731_write(AAPCTRL, wm8731_regs[AAPCTRL]); | ||
260 | |||
261 | if (!source_mic) { | ||
262 | wm8731_regs[AAPCTRL] |= AAPCTRL_INSEL | AAPCTRL_SIDETONE; | ||
263 | wm8731_regs[AAPCTRL] &= ~(AAPCTRL_MUTEMIC | AAPCTRL_BYPASS); | ||
264 | } else { | ||
265 | wm8731_write_and(LINVOL, ~LINVOL_LINMUTE); | ||
266 | wm8731_write_and(RINVOL, ~RINVOL_RINMUTE); | ||
267 | } | ||
268 | |||
269 | codec_set_active(true); | ||
270 | } | ||
271 | |||
272 | void audiohw_disable_recording(void) | ||
273 | { | ||
274 | codec_set_active(false); | ||
275 | |||
276 | /* Mute inputs */ | ||
277 | wm8731_write_or(LINVOL, LINVOL_LINMUTE); | ||
278 | wm8731_write_or(RINVOL, RINVOL_RINMUTE); | ||
279 | wm8731_write_or(AAPCTRL, AAPCTRL_MUTEMIC); | ||
280 | |||
281 | /* Turn off input analog audio paths */ | ||
282 | wm8731_regs[AAPCTRL] &= ~(AAPCTRL_BYPASS | AAPCTRL_SIDETONE); | ||
283 | wm8731_write(AAPCTRL, wm8731_regs[AAPCTRL]); | ||
284 | |||
285 | /* Set power config */ | ||
286 | wm8731_regs[PDCTRL] &= ~PDCTRL_DACPD; | ||
287 | wm8731_regs[PDCTRL] |= PDCTRL_MICPD | PDCTRL_LINEINPD | | ||
288 | PDCTRL_ADCPD; | ||
289 | wm8731_write(PDCTRL, wm8731_regs[PDCTRL]); | ||
290 | |||
291 | /* Select DAC */ | ||
292 | wm8731_write_or(AAPCTRL, AAPCTRL_DACSEL); | ||
293 | |||
294 | codec_set_active(true); | ||
295 | } | ||
296 | |||
297 | void audiohw_set_recvol(int left, int right, int type) | ||
298 | { | ||
299 | switch (type) | ||
300 | { | ||
301 | case AUDIO_GAIN_MIC: | ||
302 | if (left > 0) { | ||
303 | wm8731_write_or(AAPCTRL, AAPCTRL_MIC_BOOST); | ||
304 | } | ||
305 | else { | ||
306 | wm8731_write_and(AAPCTRL, ~AAPCTRL_MIC_BOOST); | ||
307 | } | ||
308 | break; | ||
309 | case AUDIO_GAIN_LINEIN: | ||
310 | wm8731_regs[LINVOL] &= ~LINVOL_MASK; | ||
311 | wm8731_write(LINVOL, wm8731_regs[LINVOL] | (left & LINVOL_MASK)); | ||
312 | wm8731_regs[RINVOL] &= ~RINVOL_MASK; | ||
313 | wm8731_write(RINVOL, wm8731_regs[RINVOL] | (right & RINVOL_MASK)); | ||
314 | break; | ||
315 | default: | ||
316 | return; | ||
317 | } | ||
318 | } | ||
319 | |||
320 | void audiohw_set_monitor(int enable) | ||
321 | { | ||
322 | /* TODO: Implement for FM monitoring */ | ||
323 | (void)enable; | ||
324 | } | ||
diff --git a/firmware/export/audiohw.h b/firmware/export/audiohw.h index ec0177d091..9da1a3875f 100644 --- a/firmware/export/audiohw.h +++ b/firmware/export/audiohw.h | |||
@@ -31,8 +31,10 @@ | |||
31 | #include "wm8975.h" | 31 | #include "wm8975.h" |
32 | #elif defined(HAVE_WM8758) | 32 | #elif defined(HAVE_WM8758) |
33 | #include "wm8758.h" | 33 | #include "wm8758.h" |
34 | #elif defined(HAVE_WM8731) || defined(HAVE_WM8721) | 34 | #elif defined(HAVE_WM8721) |
35 | #include "wm8731l.h" | 35 | #include "wm8721.h" |
36 | #elif defined(HAVE_WM8731) | ||
37 | #include "wm8731.h" | ||
36 | #elif defined(HAVE_TLV320) | 38 | #elif defined(HAVE_TLV320) |
37 | #include "tlv320.h" | 39 | #include "tlv320.h" |
38 | #elif defined(HAVE_AS3514) | 40 | #elif defined(HAVE_AS3514) |
diff --git a/firmware/export/wm8731.h b/firmware/export/wm8731.h new file mode 100644 index 0000000000..3fc6bc7a5a --- /dev/null +++ b/firmware/export/wm8731.h | |||
@@ -0,0 +1,141 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2005 by Dave Chapman | ||
11 | * | ||
12 | * All files in this archive are subject to the GNU General Public License. | ||
13 | * See the file COPYING in the source tree root for full license agreement. | ||
14 | * | ||
15 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
16 | * KIND, either express or implied. | ||
17 | * | ||
18 | ****************************************************************************/ | ||
19 | |||
20 | #ifndef _WM8731_H | ||
21 | #define _WM8731_H | ||
22 | |||
23 | /* volume/balance/treble/bass interdependency */ | ||
24 | #define VOLUME_MIN -730 | ||
25 | #define VOLUME_MAX 60 | ||
26 | |||
27 | extern int tenthdb2master(int db); | ||
28 | extern int tenthdb2mixer(int db); | ||
29 | |||
30 | extern void audiohw_reset(void); | ||
31 | extern void audiohw_preinit(void); | ||
32 | extern void audiohw_postinit(void); | ||
33 | extern int audiohw_set_master_vol(int vol_l, int vol_r); | ||
34 | extern void audiohw_set_nsorder(int order); | ||
35 | extern void audiohw_set_sample_rate(int sampling_control); | ||
36 | |||
37 | extern void audiohw_enable_recording(bool source_mic); | ||
38 | extern void audiohw_disable_recording(void); | ||
39 | extern void audiohw_set_recvol(int left, int right, int type); | ||
40 | extern void audiohw_set_monitor(int enable); | ||
41 | |||
42 | /* Register addresses and bits */ | ||
43 | #define LINVOL 0x00 | ||
44 | #define LINVOL_MASK 0x1f | ||
45 | #define LINVOL_LRINBOTH (1 << 8) | ||
46 | #define LINVOL_LINMUTE (1 << 7) | ||
47 | |||
48 | #define RINVOL 0x01 | ||
49 | #define RINVOL_MASK 0x1f | ||
50 | #define RINVOL_RINMUTE (1 << 7) | ||
51 | #define RINVOL_RLINBOTH (1 << 8) | ||
52 | |||
53 | #define LOUTVOL 0x02 | ||
54 | #define LOUTVOL_LHPVOL_MASK 0x7f | ||
55 | #define LOUTVOL_LZCEN (1 << 7) | ||
56 | #define LOUTVOL_LRHP_BOTH (1 << 8) | ||
57 | |||
58 | #define ROUTVOL 0x03 | ||
59 | #define ROUTVOL_RHPVOL_MASK 0x7f | ||
60 | #define ROUTVOL_RZCEN (1 << 7) | ||
61 | #define ROUTVOL_RLHP_BOTH (1 << 8) | ||
62 | |||
63 | #define AAPCTRL 0x04 /* Analog audio path control */ | ||
64 | #define AAPCTRL_MIC_BOOST (1 << 0) | ||
65 | #define AAPCTRL_MUTEMIC (1 << 1) | ||
66 | #define AAPCTRL_INSEL (1 << 2) | ||
67 | #define AAPCTRL_BYPASS (1 << 3) | ||
68 | #define AAPCTRL_DACSEL (1 << 4) | ||
69 | #define AAPCTRL_SIDETONE (1 << 5) | ||
70 | #define AAPCTRL_SIDEATT_6dB (3 << 6) | ||
71 | #define AAPCTRL_SIDEATT_9dB (1 << 6) | ||
72 | #define AAPCTRL_SIDEATT_12dB (2 << 6) | ||
73 | #define AAPCTRL_SIDEATT_15dB (3 << 6) | ||
74 | |||
75 | #define DAPCTRL 0x05 /* Digital audio path control */ | ||
76 | #define DAPCTRL_ADCHPD (1 << 0) | ||
77 | #define DAPCTRL_DEEMP_DISABLE (0 << 2) | ||
78 | #define DAPCTRL_DEEMP_32KHz (1 << 2) | ||
79 | #define DAPCTRL_DEEMP_44KHz (2 << 2) | ||
80 | #define DAPCTRL_DEEMP_48KHz (3 << 2) | ||
81 | #define DAPCTRL_DEEMP_MASK (3 << 2) | ||
82 | #define DAPCTRL_DACMU (1 << 3) | ||
83 | #define DAPCTRL_HPOR (1 << 4) | ||
84 | |||
85 | #define PDCTRL 0x06 | ||
86 | #define PDCTRL_LINEINPD (1 << 0) | ||
87 | #define PDCTRL_MICPD (1 << 1) | ||
88 | #define PDCTRL_ADCPD (1 << 2) | ||
89 | #define PDCTRL_DACPD (1 << 3) | ||
90 | #define PDCTRL_OUTPD (1 << 4) | ||
91 | #define PDCTRL_OSCPD (1 << 5) | ||
92 | #define PDCTRL_CLKOUTPD (1 << 6) | ||
93 | #define PDCTRL_POWEROFF (1 << 7) | ||
94 | |||
95 | #define AINTFCE 0x07 | ||
96 | #define AINTFCE_FORMAT_MSB_RJUST (0 << 0) | ||
97 | #define AINTFCE_FORMAT_MSB_LJUST (1 << 0) | ||
98 | #define AINTFCE_FORMAT_I2S (2 << 0) | ||
99 | #define AINTFCE_FORMAT_DSP (3 << 0) | ||
100 | #define AINTFCE_FORMAT_MASK (3 << 0) | ||
101 | #define AINTFCE_IWL_16BIT (0 << 2) | ||
102 | #define AINTFCE_IWL_20BIT (1 << 2) | ||
103 | #define AINTFCE_IWL_24BIT (2 << 2) | ||
104 | #define AINTFCE_IWL_32BIT (3 << 2) | ||
105 | #define AINTFCE_IWL_MASK (3 << 2) | ||
106 | #define AINTFCE_LRP_I2S_RLO (0 << 4) | ||
107 | #define AINTFCE_LRP_I2S_RHI (1 << 4) | ||
108 | #define AINTFCE_DSP_MODE_A (0 << 4) | ||
109 | #define AINTFCE_DSP_MODE_B (1 << 4) | ||
110 | #define AINTFCE_LRSWAP (1 << 5) | ||
111 | #define AINTFCE_MS (1 << 6) | ||
112 | #define AINTFCE_BCLKINV (1 << 7) | ||
113 | |||
114 | #define SAMPCTRL 0x08 | ||
115 | #define SAMPCTRL_USB (1 << 0) | ||
116 | #define SAMPCTRL_BOSR_NOR_256fs (0 << 1) | ||
117 | #define SAMPCTRL_BOSR_NOR_384fs (1 << 1) | ||
118 | #define SAMPCTRL_BOSR_USB_250fs (0 << 1) | ||
119 | #define SAMPCTRL_BOSR_USB_272fs (1 << 1) | ||
120 | /* Bits 2-5: | ||
121 | * Sample rate setting are device-specific. See WM8731(L) datasheet | ||
122 | * for proper settings for the device's clocking */ | ||
123 | #define SAMPCTRL_SR_MASK (0xf << 2) | ||
124 | #define SAMPCTRL_CLKIDIV2 (1 << 6) | ||
125 | #define SAMPCTRL_CLKODIV2 (1 << 7) | ||
126 | |||
127 | #define ACTIVECTRL 0x09 | ||
128 | #define ACTIVECTRL_ACTIVE (1 << 0) | ||
129 | |||
130 | #define RESET 0x0f | ||
131 | #define RESET_RESET 0x0 | ||
132 | |||
133 | /* SAMPCTRL values for the supported samplerates (24MHz MCLK/USB): */ | ||
134 | #define WM8731_USB24_8000HZ 0x4d | ||
135 | #define WM8731_USB24_32000HZ 0x59 | ||
136 | #define WM8731_USB24_44100HZ 0x63 | ||
137 | #define WM8731_USB24_48000HZ 0x41 | ||
138 | #define WM8731_USB24_88200HZ 0x7f | ||
139 | #define WM8731_USB24_96000HZ 0x5d | ||
140 | |||
141 | #endif /* _WM8731_H */ | ||
diff --git a/firmware/export/wm8731l.h b/firmware/export/wm8731l.h deleted file mode 100644 index f0f63c909a..0000000000 --- a/firmware/export/wm8731l.h +++ /dev/null | |||
@@ -1,65 +0,0 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2005 by Dave Chapman | ||
11 | * | ||
12 | * All files in this archive are subject to the GNU General Public License. | ||
13 | * See the file COPYING in the source tree root for full license agreement. | ||
14 | * | ||
15 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
16 | * KIND, either express or implied. | ||
17 | * | ||
18 | ****************************************************************************/ | ||
19 | |||
20 | #ifndef _WM8731L_H | ||
21 | #define _WM8731L_H | ||
22 | |||
23 | /* volume/balance/treble/bass interdependency */ | ||
24 | #define VOLUME_MIN -730 | ||
25 | #define VOLUME_MAX 60 | ||
26 | |||
27 | extern int tenthdb2master(int db); | ||
28 | extern int tenthdb2mixer(int db); | ||
29 | |||
30 | extern void audiohw_reset(void); | ||
31 | extern void audiohw_enable_output(bool enable); | ||
32 | extern int audiohw_set_master_vol(int vol_l, int vol_r); | ||
33 | extern int audiohw_set_mixer_vol(int channel1, int channel2); | ||
34 | extern void audiohw_set_bass(int value); | ||
35 | extern void audiohw_set_treble(int value); | ||
36 | extern void audiohw_set_nsorder(int order); | ||
37 | extern void audiohw_set_sample_rate(int sampling_control); | ||
38 | |||
39 | extern void audiohw_enable_recording(bool source_mic); | ||
40 | extern void audiohw_disable_recording(void); | ||
41 | extern void audiohw_set_recvol(int left, int right, int type); | ||
42 | extern void audiohw_set_monitor(int enable); | ||
43 | |||
44 | /* Register addresses */ | ||
45 | #define LINVOL 0x00 | ||
46 | #define RINVOL 0x01 | ||
47 | #define LOUTVOL 0x02 | ||
48 | #define ROUTVOL 0x03 | ||
49 | #define AAPCTRL 0x04 /* Analog audio path control */ | ||
50 | #define DACCTRL 0x05 | ||
51 | #define PWRMGMT 0x06 | ||
52 | #define AINTFCE 0x07 | ||
53 | #define SAMPCTRL 0x08 | ||
54 | #define ACTIVECTRL 0x09 | ||
55 | #define RESET 0x0f | ||
56 | |||
57 | /* Register settings for the supported samplerates: */ | ||
58 | #define WM8731L_8000HZ 0x4d | ||
59 | #define WM8731L_32000HZ 0x59 | ||
60 | #define WM8731L_44100HZ 0x63 | ||
61 | #define WM8731L_48000HZ 0x41 | ||
62 | #define WM8731L_88200HZ 0x7f | ||
63 | #define WM8731L_96000HZ 0x5d | ||
64 | |||
65 | #endif /* _WM8975_H */ | ||
diff --git a/firmware/sound.c b/firmware/sound.c index 8b68a5569b..335aa1a640 100644 --- a/firmware/sound.c +++ b/firmware/sound.c | |||
@@ -744,7 +744,7 @@ void sound_set(int setting, int value) | |||
744 | sound_set_val(value); | 744 | sound_set_val(value); |
745 | } | 745 | } |
746 | 746 | ||
747 | #if !defined(HAVE_AS3514) || defined(SIMULATOR) | 747 | #if (!defined(HAVE_AS3514) && !defined (HAVE_WM8731)) || defined(SIMULATOR) |
748 | int sound_val2phys(int setting, int value) | 748 | int sound_val2phys(int setting, int value) |
749 | { | 749 | { |
750 | #if CONFIG_CODEC == MAS3587F | 750 | #if CONFIG_CODEC == MAS3587F |
@@ -782,7 +782,7 @@ int sound_val2phys(int setting, int value) | |||
782 | break; | 782 | break; |
783 | } | 783 | } |
784 | return result; | 784 | return result; |
785 | #elif defined(HAVE_TLV320) | 785 | #elif defined(HAVE_TLV320) || defined(HAVE_WM8751) |
786 | int result = 0; | 786 | int result = 0; |
787 | 787 | ||
788 | switch(setting) | 788 | switch(setting) |
diff --git a/firmware/target/arm/pcm-pp.c b/firmware/target/arm/pcm-pp.c index 5ac15fe00c..42b9aeb6cb 100644 --- a/firmware/target/arm/pcm-pp.c +++ b/firmware/target/arm/pcm-pp.c | |||
@@ -168,7 +168,8 @@ void fiq(void) | |||
168 | 168 | ||
169 | do { | 169 | do { |
170 | while (p_size) { | 170 | while (p_size) { |
171 | if (FIFO_FREE_COUNT < 2) { | 171 | //if (FIFO_FREE_COUNT < 2) { |
172 | if (((IISFIFO_CFG & (0x1f << 16)) >> 16) < 2) { | ||
172 | /* Enable interrupt */ | 173 | /* Enable interrupt */ |
173 | #ifdef CPU_PP502x | 174 | #ifdef CPU_PP502x |
174 | IISCONFIG |= (1 << 1); | 175 | IISCONFIG |= (1 << 1); |
@@ -219,8 +220,10 @@ void pcm_play_dma_start(const void *addr, size_t size) | |||
219 | set_fiq_handler(fiq); | 220 | set_fiq_handler(fiq); |
220 | enable_fiq(); | 221 | enable_fiq(); |
221 | 222 | ||
223 | #if CONFIG_CPU == PP5020 | ||
224 | /* Do nothing */ | ||
225 | #elif defined(CPU_PP502x) | ||
222 | /* Enable playback FIFO */ | 226 | /* Enable playback FIFO */ |
223 | #ifdef CPU_PP502x | ||
224 | IISCONFIG |= (1 << 29); | 227 | IISCONFIG |= (1 << 29); |
225 | #elif CONFIG_CPU == PP5002 | 228 | #elif CONFIG_CPU == PP5002 |
226 | IISCONFIG |= 0x4; | 229 | IISCONFIG |= 0x4; |
@@ -257,11 +260,13 @@ void pcm_play_dma_stop(void) | |||
257 | if (!audio_status()) | 260 | if (!audio_status()) |
258 | pcm_paused = false; | 261 | pcm_paused = false; |
259 | 262 | ||
260 | #ifdef CPU_PP502x | 263 | #if CONFIG_CPU == PP5020 |
264 | /* Disable TX interrupt */ | ||
265 | IISCONFIG &= ~(1 << 1); | ||
266 | #elif defined(CPU_PP502x) | ||
261 | /* Disable playback FIFO and interrupt */ | 267 | /* Disable playback FIFO and interrupt */ |
262 | IISCONFIG &= ~((1 << 29) | (1 << 1)); | 268 | IISCONFIG &= ~((1 << 29) | (1 << 1)); |
263 | #elif CONFIG_CPU == PP5002 | 269 | #elif CONFIG_CPU == PP5002 |
264 | |||
265 | /* Disable playback FIFO */ | 270 | /* Disable playback FIFO */ |
266 | IISCONFIG &= ~0x4; | 271 | IISCONFIG &= ~0x4; |
267 | 272 | ||
@@ -274,7 +279,10 @@ void pcm_play_dma_stop(void) | |||
274 | 279 | ||
275 | void pcm_play_pause_pause(void) | 280 | void pcm_play_pause_pause(void) |
276 | { | 281 | { |
277 | #ifdef CPU_PP502x | 282 | #if CONFIG_CPU == PP5020 |
283 | /* Disable TX interrupt */ | ||
284 | IISCONFIG &= ~(1 << 1); | ||
285 | #elif defined(CPU_PP502x) | ||
278 | /* Disable playback FIFO and interrupt */ | 286 | /* Disable playback FIFO and interrupt */ |
279 | IISCONFIG &= ~((1 << 29) | (1 << 1)); | 287 | IISCONFIG &= ~((1 << 29) | (1 << 1)); |
280 | #elif CONFIG_CPU == PP5002 | 288 | #elif CONFIG_CPU == PP5002 |
@@ -293,8 +301,10 @@ void pcm_play_pause_unpause(void) | |||
293 | set_fiq_handler(fiq); | 301 | set_fiq_handler(fiq); |
294 | enable_fiq(); | 302 | enable_fiq(); |
295 | 303 | ||
304 | #if CONFIG_CPU == PP5020 | ||
305 | /* Do nothing */ | ||
306 | #elif defined(CPU_PP502x) | ||
296 | /* Enable playback FIFO */ | 307 | /* Enable playback FIFO */ |
297 | #ifdef CPU_PP502x | ||
298 | IISCONFIG |= (1 << 29); | 308 | IISCONFIG |= (1 << 29); |
299 | #elif CONFIG_CPU == PP5002 | 309 | #elif CONFIG_CPU == PP5002 |
300 | IISCONFIG |= 0x4; | 310 | IISCONFIG |= 0x4; |
@@ -344,14 +354,20 @@ void pcm_init(void) | |||
344 | /* Initialize default register values. */ | 354 | /* Initialize default register values. */ |
345 | audiohw_init(); | 355 | audiohw_init(); |
346 | 356 | ||
357 | #ifndef HAVE_WM8731 | ||
347 | /* Power on */ | 358 | /* Power on */ |
348 | audiohw_enable_output(true); | 359 | audiohw_enable_output(true); |
349 | |||
350 | /* Unmute the master channel (DAC should be at zero point now). */ | 360 | /* Unmute the master channel (DAC should be at zero point now). */ |
351 | audiohw_mute(false); | 361 | audiohw_mute(false); |
362 | #endif | ||
352 | 363 | ||
353 | /* Call pcm_play_dma_stop to initialize everything. */ | 364 | /* Call pcm_play_dma_stop to initialize everything. */ |
354 | pcm_play_dma_stop(); | 365 | pcm_play_dma_stop(); |
366 | |||
367 | #if CONFIG_CPU == PP5020 | ||
368 | /* This processor doesn't like this disabled */ | ||
369 | IISCONFIG |= (1 << 29); | ||
370 | #endif | ||
355 | } | 371 | } |
356 | 372 | ||
357 | void pcm_postinit(void) | 373 | void pcm_postinit(void) |
@@ -438,12 +454,15 @@ fiq_record_exit: | |||
438 | #else | 454 | #else |
439 | static short peak_l, peak_r IBSS_ATTR; | 455 | static short peak_l, peak_r IBSS_ATTR; |
440 | 456 | ||
441 | void fiq_record(void) ICODE_ATTR __attribute__ ((interrupt ("FIQ"))); | 457 | /* Temporary to stop playback crashing after record */ |
458 | void fiq_record(void) ICODE_ATTR __attribute__((naked)); | ||
442 | void fiq_record(void) | 459 | void fiq_record(void) |
443 | { | 460 | { |
444 | short value; | 461 | asm volatile ("stmfd sp!, {r0-r7, r11, ip, lr} \n"); /* Store context */ |
445 | pcm_more_callback_type2 more_ready; | 462 | |
446 | int status = 0; | 463 | register short value; |
464 | register pcm_more_callback_type2 more_ready; | ||
465 | register int status = 0; | ||
447 | 466 | ||
448 | /* Clear interrupt */ | 467 | /* Clear interrupt */ |
449 | #ifdef CPU_PP502x | 468 | #ifdef CPU_PP502x |
@@ -460,7 +479,7 @@ void fiq_record(void) | |||
460 | #elif CONFIG_CPU == PP5002 | 479 | #elif CONFIG_CPU == PP5002 |
461 | /* TODO */ | 480 | /* TODO */ |
462 | #endif | 481 | #endif |
463 | return; | 482 | goto fiq_record_exit; |
464 | } | 483 | } |
465 | 484 | ||
466 | value = (unsigned short)(IISFIFO_RD >> 16); | 485 | value = (unsigned short)(IISFIFO_RD >> 16); |
@@ -486,10 +505,14 @@ void fiq_record(void) | |||
486 | more_ready = pcm_callback_more_ready; | 505 | more_ready = pcm_callback_more_ready; |
487 | 506 | ||
488 | if (more_ready != NULL && more_ready(status) >= 0) | 507 | if (more_ready != NULL && more_ready(status) >= 0) |
489 | return; | 508 | goto fiq_record_exit; |
490 | 509 | ||
491 | /* Finished recording */ | 510 | /* Finished recording */ |
492 | pcm_rec_dma_stop(); | 511 | pcm_rec_dma_stop(); |
512 | |||
513 | fiq_record_exit: | ||
514 | asm volatile("ldmfd sp!, {r0-r7, r11, ip, lr} \n" /* Restore context */ | ||
515 | "subs pc, lr, #4 \n"); /* Return from FIQ */ | ||
493 | } | 516 | } |
494 | 517 | ||
495 | #endif /* HAVE_AS3514 */ | 518 | #endif /* HAVE_AS3514 */ |
diff --git a/firmware/target/arm/wmcodec-pp.c b/firmware/target/arm/wmcodec-pp.c index 455e3e1087..a2c83f33b3 100644 --- a/firmware/target/arm/wmcodec-pp.c +++ b/firmware/target/arm/wmcodec-pp.c | |||
@@ -25,6 +25,7 @@ | |||
25 | ****************************************************************************/ | 25 | ****************************************************************************/ |
26 | 26 | ||
27 | #include "system.h" | 27 | #include "system.h" |
28 | #include "audiohw.h" | ||
28 | #include "i2c-pp.h" | 29 | #include "i2c-pp.h" |
29 | 30 | ||
30 | #if defined(IRIVER_H10) || defined(IRIVER_H10_5GB) | 31 | #if defined(IRIVER_H10) || defined(IRIVER_H10_5GB) |
@@ -39,7 +40,7 @@ | |||
39 | /* | 40 | /* |
40 | * Initialise the PP I2C and I2S. | 41 | * Initialise the PP I2C and I2S. |
41 | */ | 42 | */ |
42 | int audiohw_init(void) { | 43 | void audiohw_init(void) { |
43 | /* reset I2C */ | 44 | /* reset I2C */ |
44 | i2c_init(); | 45 | i2c_init(); |
45 | 46 | ||
@@ -95,12 +96,17 @@ int audiohw_init(void) { | |||
95 | #endif /* IPOD_1G2G/3G */ | 96 | #endif /* IPOD_1G2G/3G */ |
96 | #endif | 97 | #endif |
97 | 98 | ||
98 | return 0; | 99 | #ifdef HAVE_WM8731 |
100 | audiohw_preinit(); | ||
101 | #endif | ||
102 | |||
99 | } | 103 | } |
100 | 104 | ||
105 | #ifndef HAVE_WM8731 | ||
101 | void audiohw_postinit(void) | 106 | void audiohw_postinit(void) |
102 | { | 107 | { |
103 | } | 108 | } |
109 | #endif | ||
104 | 110 | ||
105 | void wmcodec_write(int reg, int data) | 111 | void wmcodec_write(int reg, int data) |
106 | { | 112 | { |