diff options
author | Dave Chapman <dave@dchapman.com> | 2006-02-26 15:59:46 +0000 |
---|---|---|
committer | Dave Chapman <dave@dchapman.com> | 2006-02-26 15:59:46 +0000 |
commit | 2f76763d73c7be641cd55c30ff15f6ff9dda5fe0 (patch) | |
tree | 29179e6843bf4de0bdedf9ed40e07cfb520bdad8 /firmware | |
parent | 4b9fbd168713e572f9a73a7bacaa850e8c961994 (diff) | |
download | rockbox-2f76763d73c7be641cd55c30ff15f6ff9dda5fe0.tar.gz rockbox-2f76763d73c7be641cd55c30ff15f6ff9dda5fe0.zip |
iPod 3G - initial (completely untested) attempt at audio support
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@8847 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware')
-rw-r--r-- | firmware/SOURCES | 2 | ||||
-rw-r--r-- | firmware/drivers/wm8731l.c | 106 | ||||
-rw-r--r-- | firmware/export/config-ipod3g.h | 2 | ||||
-rw-r--r-- | firmware/export/wm8731l.h | 36 | ||||
-rw-r--r-- | firmware/pcm_playback.c | 76 | ||||
-rw-r--r-- | firmware/sound.c | 54 | ||||
-rw-r--r-- | firmware/system.c | 4 |
7 files changed, 184 insertions, 96 deletions
diff --git a/firmware/SOURCES b/firmware/SOURCES index 4c6fbd7c2a..23c3a6dddc 100644 --- a/firmware/SOURCES +++ b/firmware/SOURCES | |||
@@ -180,7 +180,7 @@ drivers/uda1380.c | |||
180 | drivers/wm8975.c | 180 | drivers/wm8975.c |
181 | #elif defined(HAVE_WM8758) && !defined(SIMULATOR) | 181 | #elif defined(HAVE_WM8758) && !defined(SIMULATOR) |
182 | drivers/wm8758.c | 182 | drivers/wm8758.c |
183 | #elif defined(HAVE_WM8731L) && !defined(SIMULATOR) | 183 | #elif defined(HAVE_WM8731) && !defined(SIMULATOR) |
184 | drivers/wm8731l.c | 184 | drivers/wm8731l.c |
185 | #elif defined(HAVE_TLV320) && !defined(SIMULATOR) | 185 | #elif defined(HAVE_TLV320) && !defined(SIMULATOR) |
186 | drivers/tlv320.c | 186 | drivers/tlv320.c |
diff --git a/firmware/drivers/wm8731l.c b/firmware/drivers/wm8731l.c index d49e8f4476..990ad0ebbc 100644 --- a/firmware/drivers/wm8731l.c +++ b/firmware/drivers/wm8731l.c | |||
@@ -41,40 +41,46 @@ | |||
41 | #include "wm8731l.h" | 41 | #include "wm8731l.h" |
42 | #include "pcf50605.h" | 42 | #include "pcf50605.h" |
43 | 43 | ||
44 | void wm8731l_reset(void); | ||
45 | |||
46 | #define IPOD_PCM_LEVEL 0x65 /* -6dB */ | 44 | #define IPOD_PCM_LEVEL 0x65 /* -6dB */ |
47 | 45 | ||
48 | #define RESET (0x0f<<1) | 46 | #define LINVOL 0x00 |
49 | #define PWRMGMT1 (0x19<<1) | 47 | #define RINVOL 0x01 |
50 | #define PWRMGMT2 (0x1a<<1) | 48 | #define LOUTVOL 0x02 |
51 | #define AINTFCE (0x07<<1) | 49 | #define ROUTVOL 0x03 |
52 | #define LOUT1VOL (0x02<<1) | 50 | #define DACCTRL 0x05 |
53 | #define ROUT1VOL (0x03<<1) | 51 | #define PWRMGMT 0x06 |
54 | #define LOUT2VOL (0x28<<1) | 52 | #define AINTFCE 0x07 |
55 | #define ROUT2VOL (0x29<<1) | 53 | #define SAMPCTRL 0x08 |
54 | #define ACTIVECTRL 0x09 | ||
55 | #define RESET 0x0f | ||
56 | |||
57 | void wm8731_write(int reg, int data) | ||
58 | { | ||
59 | ipod_i2c_send(0x1a, (reg<<1) | ((data&0x100)>>8),data&0xff); | ||
60 | } | ||
56 | 61 | ||
57 | int wm8731l_mute(int mute) | 62 | int wmcodec_mute(int mute) |
58 | { | 63 | { |
59 | if (mute) | 64 | if (mute) |
60 | { | 65 | { |
61 | /* Set DACMU = 1 to soft-mute the audio DACs. */ | 66 | /* Set DACMU = 1 to soft-mute the audio DACs. */ |
62 | ipod_i2c_send(0x1a, 0xa, 0x8); | 67 | wm8731_write(DACCTRL, 0x8); |
63 | } else { | 68 | } else { |
64 | /* Set DACMU = 0 to soft-un-mute the audio DACs. */ | 69 | /* Set DACMU = 0 to soft-un-mute the audio DACs. */ |
65 | ipod_i2c_send(0x1a, 0xa, 0x0); | 70 | wm8731_write(DACCTRL, 0x0); |
66 | } | 71 | } |
67 | 72 | ||
68 | return 0; | 73 | return 0; |
69 | } | 74 | } |
75 | |||
70 | /** From ipodLinux **/ | 76 | /** From ipodLinux **/ |
71 | static void codec_set_active(int active) | 77 | static void codec_set_active(int active) |
72 | { | 78 | { |
73 | /* set active to 0x0 or 0x1 */ | 79 | /* set active to 0x0 or 0x1 */ |
74 | if (active) { | 80 | if (active) { |
75 | ipod_i2c_send(0x1a, 0x12, 0x01); | 81 | wm8731_write(ACTIVECTRL, 0x01); |
76 | } else { | 82 | } else { |
77 | ipod_i2c_send(0x1a, 0x12, 0x00); | 83 | wm8731_write(ACTIVECTRL, 0x00); |
78 | } | 84 | } |
79 | } | 85 | } |
80 | 86 | ||
@@ -102,7 +108,7 @@ static void i2s_reset(void) | |||
102 | * Initialise the WM8975 for playback via headphone and line out. | 108 | * Initialise the WM8975 for playback via headphone and line out. |
103 | * Note, I'm using the WM8750 datasheet as its apparently close. | 109 | * Note, I'm using the WM8750 datasheet as its apparently close. |
104 | */ | 110 | */ |
105 | int wm8731l_init(void) { | 111 | int wmcodec_init(void) { |
106 | /* reset I2C */ | 112 | /* reset I2C */ |
107 | i2c_init(); | 113 | i2c_init(); |
108 | 114 | ||
@@ -134,64 +140,61 @@ int wm8731l_init(void) { | |||
134 | } | 140 | } |
135 | 141 | ||
136 | /* Silently enable / disable audio output */ | 142 | /* Silently enable / disable audio output */ |
137 | void wm8731l_enable_output(bool enable) | 143 | void wmcodec_enable_output(bool enable) |
138 | { | 144 | { |
139 | if (enable) | 145 | if (enable) |
140 | { | 146 | { |
141 | /* reset the I2S controller into known state */ | 147 | /* reset the I2S controller into known state */ |
142 | i2s_reset(); | 148 | i2s_reset(); |
143 | 149 | ||
144 | ipod_i2c_send(0x1a, 0x1e, 0x0); /*Reset*/ | 150 | wm8731_write(RESET, 0x0); /*Reset*/ |
145 | 151 | ||
146 | codec_set_active(0x0); | 152 | codec_set_active(0x0); |
147 | 153 | ||
148 | /* DACSEL=1 */ | 154 | /* DACSEL=1 */ |
149 | /* BYPASS=1 */ | 155 | /* BYPASS=1 */ |
150 | ipod_i2c_send(0x1a, 0x8, 0x18); | 156 | wm8731_write(0x4, 0x18); |
151 | 157 | ||
152 | /* set power register to POWEROFF=0 on OUTPD=0, DACPD=0 */ | 158 | /* set power register to POWEROFF=0 on OUTPD=0, DACPD=0 */ |
153 | ipod_i2c_send(0x1a, 0xc, 0x67); | 159 | wm8731_write(PWRMGMT, 0x67); |
154 | 160 | ||
155 | /* BCLKINV=0(Dont invert BCLK) MS=1(Enable Master) LRSWAP=0 LRP=0 */ | 161 | /* BCLKINV=0(Dont invert BCLK) MS=1(Enable Master) LRSWAP=0 LRP=0 */ |
156 | /* IWL=00(16 bit) FORMAT=10(I2S format) */ | 162 | /* IWL=00(16 bit) FORMAT=10(I2S format) */ |
157 | ipod_i2c_send(0x1a, 0xe, 0x42); | 163 | wm8731_write(AINTFCE, 0x42); |
158 | 164 | ||
159 | wm8731l_set_sample_rate(WM8731L_44100HZ); | 165 | wmcodec_set_sample_rate(WM8731L_44100HZ); |
160 | 166 | ||
161 | /* set the volume to -6dB */ | 167 | /* set the volume to -6dB */ |
162 | ipod_i2c_send(0x1a, 0x4, IPOD_PCM_LEVEL); | 168 | wm8731_write(LOUTVOL, IPOD_PCM_LEVEL); |
163 | ipod_i2c_send(0x1a, 0x6 | 0x1, IPOD_PCM_LEVEL); | 169 | wm8731_write(ROUTVOL, 0x100 | IPOD_PCM_LEVEL); |
164 | 170 | ||
165 | /* ACTIVE=1 */ | 171 | /* ACTIVE=1 */ |
166 | codec_set_active(1); | 172 | codec_set_active(1); |
167 | 173 | ||
168 | /* 5. Set DACMU = 0 to soft-un-mute the audio DACs. */ | 174 | /* 5. Set DACMU = 0 to soft-un-mute the audio DACs. */ |
169 | ipod_i2c_send(0x1a, 0xa, 0x0); | 175 | wm8731_write(DACCTRL, 0x0); |
170 | 176 | ||
171 | wm8731l_mute(0); | 177 | wmcodec_mute(0); |
172 | } else { | 178 | } else { |
173 | wm8731l_mute(1); | 179 | wmcodec_mute(1); |
174 | } | 180 | } |
175 | } | 181 | } |
176 | 182 | ||
177 | int wm8731l_set_master_vol(int vol_l, int vol_r) | 183 | int wmcodec_set_master_vol(int vol_l, int vol_r) |
178 | { | 184 | { |
179 | /* +6 to -73dB 1dB steps (plus mute == 80levels) 7bits */ | 185 | /* +6 to -73dB 1dB steps (plus mute == 80levels) 7bits */ |
180 | /* 1111111 == +6dB */ | 186 | /* 1111111 == +6dB */ |
181 | /* 1111001 == 0dB */ | 187 | /* 1111001 == 0dB */ |
182 | /* 0110000 == -73dB */ | 188 | /* 0110000 == -73dB */ |
183 | /* 0101111 == mute (0x2f) */ | 189 | /* 0101111 == mute (0x2f) */ |
184 | if (vol_l == vol_r) { | 190 | |
185 | ipod_i2c_send(0x1a, 0x4 | 0x1, vol_l); | 191 | wm8731_write(LOUTVOL, vol_l); |
186 | } else { | 192 | wm8731_write(ROUTVOL, vol_r); |
187 | ipod_i2c_send(0x1a, 0x4, vol_l); | ||
188 | ipod_i2c_send(0x1a, 0x6, vol_r); | ||
189 | } | ||
190 | 193 | ||
191 | return 0; | 194 | return 0; |
192 | } | 195 | } |
193 | 196 | ||
194 | int wm8975_set_mixer_vol(int channel1, int channel2) | 197 | int wmcodec_set_mixer_vol(int channel1, int channel2) |
195 | { | 198 | { |
196 | (void)channel1; | 199 | (void)channel1; |
197 | (void)channel2; | 200 | (void)channel2; |
@@ -199,70 +202,69 @@ int wm8975_set_mixer_vol(int channel1, int channel2) | |||
199 | return 0; | 202 | return 0; |
200 | } | 203 | } |
201 | 204 | ||
202 | void wm8731l_set_bass(int value) | 205 | void wmcodec_set_bass(int value) |
203 | { | 206 | { |
204 | (void)value; | 207 | (void)value; |
205 | } | 208 | } |
206 | 209 | ||
207 | void wm8731l_set_treble(int value) | 210 | void wmcodec_set_treble(int value) |
208 | { | 211 | { |
209 | (void)value; | 212 | (void)value; |
210 | } | 213 | } |
211 | 214 | ||
212 | /* Nice shutdown of WM8975 codec */ | 215 | /* Nice shutdown of WM8731 codec */ |
213 | void wm8731l_close(void) | 216 | void wmcodec_close(void) |
214 | { | 217 | { |
215 | /* set DACMU=1 DEEMPH=0 */ | 218 | /* set DACMU=1 DEEMPH=0 */ |
216 | ipod_i2c_send(0x1a, 0xa, 0x8); | 219 | wm8731_write(DACCTRL, 0x8); |
217 | 220 | ||
218 | /* ACTIVE=0 */ | 221 | /* ACTIVE=0 */ |
219 | codec_set_active(0x0); | 222 | codec_set_active(0x0); |
220 | 223 | ||
221 | /* line in mute left & right*/ | 224 | /* line in mute left & right*/ |
222 | ipod_i2c_send(0x1a, 0x0 | 0x1, 0x80); | 225 | wm8731_write(LINVOL, 0x100 | 0x80); |
223 | 226 | ||
224 | /* set DACSEL=0, MUTEMIC=1 */ | 227 | /* set DACSEL=0, MUTEMIC=1 */ |
225 | ipod_i2c_send(0x1a, 0x8, 0x2); | 228 | wm8731_write(0x4, 0x2); |
226 | 229 | ||
227 | /* set POWEROFF=0 OUTPD=0 DACPD=1 */ | 230 | /* set POWEROFF=0 OUTPD=0 DACPD=1 */ |
228 | ipod_i2c_send(0x1a, 0xc, 0x6f); | 231 | wm8731_write(PWRMGMT, 0x6f); |
229 | 232 | ||
230 | /* set POWEROFF=1 OUTPD=1 DACPD=1 */ | 233 | /* set POWEROFF=1 OUTPD=1 DACPD=1 */ |
231 | ipod_i2c_send(0x1a, 0xc, 0xff); | 234 | wm8731_write(PWRMGMT, 0xff); |
232 | } | 235 | } |
233 | 236 | ||
234 | /* Change the order of the noise shaper, 5th order is recommended above 32kHz */ | 237 | /* Change the order of the noise shaper, 5th order is recommended above 32kHz */ |
235 | void wm8731l_set_nsorder(int order) | 238 | void wmcodec_set_nsorder(int order) |
236 | { | 239 | { |
237 | (void)order; | 240 | (void)order; |
238 | } | 241 | } |
239 | 242 | ||
240 | /* */ | 243 | void wmcodec_set_sample_rate(int sampling_control) |
241 | void wm8731l_set_sample_rate(int sampling_control) | ||
242 | { | 244 | { |
243 | codec_set_active(0x0); | 245 | codec_set_active(0x0); |
244 | ipod_i2c_send(0x1a, 0x10, sampling_control); | 246 | wm8731_write(SAMPCTRL, sampling_control); |
245 | codec_set_active(0x1); | 247 | codec_set_active(0x1); |
246 | } | 248 | } |
247 | 249 | ||
248 | void wm8731l_enable_recording(bool source_mic) | 250 | void wmcodec_enable_recording(bool source_mic) |
249 | { | 251 | { |
250 | (void)source_mic; | 252 | (void)source_mic; |
251 | } | 253 | } |
252 | 254 | ||
253 | void wm8731l_disable_recording(void) | 255 | void wmcodec_disable_recording(void) |
254 | { | 256 | { |
255 | 257 | ||
256 | } | 258 | } |
257 | 259 | ||
258 | void wm8731l_set_recvol(int left, int right, int type) | 260 | void wmcodec_set_recvol(int left, int right, int type) |
259 | { | 261 | { |
260 | (void)left; | 262 | (void)left; |
261 | (void)right; | 263 | (void)right; |
262 | (void)type; | 264 | (void)type; |
263 | } | 265 | } |
264 | 266 | ||
265 | void wm8731l_set_monitor(int enable) | 267 | void wmcodec_set_monitor(int enable) |
266 | { | 268 | { |
267 | (void)enable; | 269 | (void)enable; |
268 | } | 270 | } |
diff --git a/firmware/export/config-ipod3g.h b/firmware/export/config-ipod3g.h index e809afa6c9..072d6027fc 100644 --- a/firmware/export/config-ipod3g.h +++ b/firmware/export/config-ipod3g.h | |||
@@ -41,7 +41,7 @@ | |||
41 | #define PLUGIN_BUFFER_SIZE 0x80000 | 41 | #define PLUGIN_BUFFER_SIZE 0x80000 |
42 | 42 | ||
43 | /* Define this if you have the WM8731L audio codec */ | 43 | /* Define this if you have the WM8731L audio codec */ |
44 | #define HAVE_WM8731L | 44 | #define HAVE_WM8731 |
45 | 45 | ||
46 | /* Define this for LCD backlight available */ | 46 | /* Define this for LCD backlight available */ |
47 | #define CONFIG_BACKLIGHT BL_IPOD3G /* port controlled */ | 47 | #define CONFIG_BACKLIGHT BL_IPOD3G /* port controlled */ |
diff --git a/firmware/export/wm8731l.h b/firmware/export/wm8731l.h index 6ed845c714..d384976226 100644 --- a/firmware/export/wm8731l.h +++ b/firmware/export/wm8731l.h | |||
@@ -20,31 +20,25 @@ | |||
20 | #ifndef _WM8731L_H | 20 | #ifndef _WM8731L_H |
21 | #define _WM8731L_H | 21 | #define _WM8731L_H |
22 | 22 | ||
23 | extern void wm8731l_reset(void); | 23 | extern void wmcodec_reset(void); |
24 | extern int wm8731l_init(void); | 24 | extern int wmcodec_init(void); |
25 | extern void wm8731l_enable_output(bool enable); | 25 | extern void wmcodec_enable_output(bool enable); |
26 | extern int wm8731l_set_master_vol(int vol_l, int vol_r); | 26 | extern int wmcodec_set_master_vol(int vol_l, int vol_r); |
27 | extern int wm8731l_set_mixer_vol(int channel1, int channel2); | 27 | extern int wmcodec_set_mixer_vol(int channel1, int channel2); |
28 | extern void wm8731l_set_bass(int value); | 28 | extern void wmcodec_set_bass(int value); |
29 | extern void wm8731l_set_treble(int value); | 29 | extern void wmcodec_set_treble(int value); |
30 | extern int wm8731l_mute(int mute); | 30 | extern int wmcodec_mute(int mute); |
31 | extern void wm8731l_close(void); | 31 | extern void wmcodec_close(void); |
32 | extern void wm8731l_set_nsorder(int order); | 32 | extern void wmcodec_set_nsorder(int order); |
33 | extern void wm8731l_set_sample_rate(int sampling_control); | 33 | extern void wmcodec_set_sample_rate(int sampling_control); |
34 | 34 | ||
35 | extern void wm8731l_enable_recording(bool source_mic); | 35 | extern void wmcodec_enable_recording(bool source_mic); |
36 | extern void wm8731l_disable_recording(void); | 36 | extern void wmcodec_disable_recording(void); |
37 | extern void wm8731l_set_recvol(int left, int right, int type); | 37 | extern void wmcodec_set_recvol(int left, int right, int type); |
38 | extern void wm8731l_set_monitor(int enable); | 38 | extern void wmcodec_set_monitor(int enable); |
39 | 39 | ||
40 | /* Register settings for the supported samplerates: */ | 40 | /* Register settings for the supported samplerates: */ |
41 | #define WM8731L_8000HZ 0x4d | 41 | #define WM8731L_8000HZ 0x4d |
42 | /* | ||
43 | IpodLinux don't seem to support those sampling rate with the wm8731L chip | ||
44 | #define WM8975_16000HZ 0x55 | ||
45 | #define WM8975_22050HZ 0x77 | ||
46 | #define WM8975_24000HZ 0x79 | ||
47 | */ | ||
48 | #define WM8731L_32000HZ 0x59 | 42 | #define WM8731L_32000HZ 0x59 |
49 | #define WM8731L_44100HZ 0x63 | 43 | #define WM8731L_44100HZ 0x63 |
50 | #define WM8731L_48000HZ 0x41 | 44 | #define WM8731L_48000HZ 0x41 |
diff --git a/firmware/pcm_playback.c b/firmware/pcm_playback.c index a9d9ecd9e6..af642e4d43 100644 --- a/firmware/pcm_playback.c +++ b/firmware/pcm_playback.c | |||
@@ -31,7 +31,7 @@ | |||
31 | #include "wm8758.h" | 31 | #include "wm8758.h" |
32 | #elif defined(HAVE_TLV320) | 32 | #elif defined(HAVE_TLV320) |
33 | #include "tlv320.h" | 33 | #include "tlv320.h" |
34 | #elif defined(HAVE_WM8731L) | 34 | #elif defined(HAVE_WM8731) |
35 | #include "wm8731l.h" | 35 | #include "wm8731l.h" |
36 | #endif | 36 | #endif |
37 | #include "system.h" | 37 | #include "system.h" |
@@ -314,13 +314,17 @@ void pcm_init(void) | |||
314 | dma_stop(); | 314 | dma_stop(); |
315 | } | 315 | } |
316 | 316 | ||
317 | #elif defined(HAVE_WM8975) || defined(HAVE_WM8758) | 317 | #elif defined(HAVE_WM8975) || defined(HAVE_WM8758) || defined(HAVE_WM8731) |
318 | 318 | ||
319 | /* We need to unify this code with the uda1380 code as much as possible, but | 319 | /* We need to unify this code with the uda1380 code as much as possible, but |
320 | we will keep it separate during early development. | 320 | we will keep it separate during early development. |
321 | */ | 321 | */ |
322 | 322 | ||
323 | #if CONFIG_CPU == PP5020 | ||
323 | #define FIFO_FREE_COUNT ((IISFIFO_CFG & 0x3f0000) >> 16) | 324 | #define FIFO_FREE_COUNT ((IISFIFO_CFG & 0x3f0000) >> 16) |
325 | #elif CONFIG_CPU == PP5002 | ||
326 | #define FIFO_FREE_COUNT ((IISFIFO_CFG & 0x7800000) >> 23) | ||
327 | #endif | ||
324 | 328 | ||
325 | static bool pcm_playing; | 329 | static bool pcm_playing; |
326 | static bool pcm_paused; | 330 | static bool pcm_paused; |
@@ -329,6 +333,8 @@ static int pcm_freq = 0x6; /* 44.1 is default */ | |||
329 | unsigned short* p IBSS_ATTR; | 333 | unsigned short* p IBSS_ATTR; |
330 | long p_size IBSS_ATTR; | 334 | long p_size IBSS_ATTR; |
331 | 335 | ||
336 | #define PP5002_DMA_OUT_MASK (1 << DMA_OUT_IRQ) | ||
337 | |||
332 | static void dma_start(const void *addr, size_t size) | 338 | static void dma_start(const void *addr, size_t size) |
333 | { | 339 | { |
334 | p=(unsigned short*)addr; | 340 | p=(unsigned short*)addr; |
@@ -336,22 +342,36 @@ static void dma_start(const void *addr, size_t size) | |||
336 | 342 | ||
337 | pcm_playing = true; | 343 | pcm_playing = true; |
338 | 344 | ||
345 | #if CONFIG_CPU == PP5020 | ||
339 | /* setup I2S interrupt for FIQ */ | 346 | /* setup I2S interrupt for FIQ */ |
340 | outl(inl(0x6000402c) | I2S_MASK, 0x6000402c); | 347 | outl(inl(0x6000402c) | I2S_MASK, 0x6000402c); |
341 | outl(I2S_MASK, 0x60004024); | 348 | outl(I2S_MASK, 0x60004024); |
349 | #else | ||
350 | /* setup I2S interrupt for FIQ */ | ||
351 | outl(inl(0xcf00103c) | PP5002_DMA_OUT_MASK, 0xcf00103c); | ||
352 | outl(PP5002_DMA_OUT_MASK, 0xcf001034); | ||
353 | #endif | ||
342 | 354 | ||
343 | /* Clear the FIQ disable bit in cpsr_c */ | 355 | /* Clear the FIQ disable bit in cpsr_c */ |
344 | enable_fiq(); | 356 | enable_fiq(); |
345 | 357 | ||
346 | /* Enable playback FIFO */ | 358 | /* Enable playback FIFO */ |
359 | #if CONFIG_CPU == PP5020 | ||
347 | IISCONFIG |= 0x20000000; | 360 | IISCONFIG |= 0x20000000; |
361 | #elif CONFIG_CPU == PP5002 | ||
362 | IISCONFIG |= 0x4; | ||
363 | #endif | ||
348 | 364 | ||
349 | /* Fill the FIFO - we assume there are enough bytes in the pcm buffer to | 365 | /* Fill the FIFO - we assume there are enough bytes in the pcm buffer to |
350 | fill the 32-byte FIFO. */ | 366 | fill the 32-byte FIFO. */ |
351 | while (p_size > 0) { | 367 | while (p_size > 0) { |
352 | if (FIFO_FREE_COUNT < 2) { | 368 | if (FIFO_FREE_COUNT < 2) { |
353 | /* Enable interrupt */ | 369 | /* Enable interrupt */ |
370 | #if CONFIG_CPU == PP5020 | ||
354 | IISCONFIG |= 0x2; | 371 | IISCONFIG |= 0x2; |
372 | #elif CONFIG_CPU == PP5002 | ||
373 | IISFIFO_CFG &= ~(1<<9); | ||
374 | #endif | ||
355 | return; | 375 | return; |
356 | } | 376 | } |
357 | 377 | ||
@@ -366,12 +386,23 @@ static void dma_stop(void) | |||
366 | { | 386 | { |
367 | pcm_playing = false; | 387 | pcm_playing = false; |
368 | 388 | ||
389 | #if CONFIG_CPU == PP5020 | ||
390 | |||
369 | /* Disable playback FIFO */ | 391 | /* Disable playback FIFO */ |
370 | IISCONFIG &= ~0x20000000; | 392 | IISCONFIG &= ~0x20000000; |
371 | 393 | ||
372 | /* Disable the interrupt */ | 394 | /* Disable the interrupt */ |
373 | IISCONFIG &= ~0x2; | 395 | IISCONFIG &= ~0x2; |
374 | 396 | ||
397 | #elif CONFIG_CPU == PP5002 | ||
398 | |||
399 | /* Disable playback FIFO */ | ||
400 | IISCONFIG &= ~0x4; | ||
401 | |||
402 | /* Disable the interrupt */ | ||
403 | IISFIFO_CFG &= ~(1<<9); | ||
404 | #endif | ||
405 | |||
375 | disable_fiq(); | 406 | disable_fiq(); |
376 | 407 | ||
377 | pcm_paused = false; | 408 | pcm_paused = false; |
@@ -438,14 +469,22 @@ void pcm_play_pause(bool play) | |||
438 | enable_fiq(); | 469 | enable_fiq(); |
439 | 470 | ||
440 | /* Enable playback FIFO */ | 471 | /* Enable playback FIFO */ |
472 | #if CONFIG_CPU == PP5020 | ||
441 | IISCONFIG |= 0x20000000; | 473 | IISCONFIG |= 0x20000000; |
474 | #elif CONFIG_CPU == PP5002 | ||
475 | IISCONFIG |= 0x4; | ||
476 | #endif | ||
442 | 477 | ||
443 | /* Fill the FIFO - we assume there are enough bytes in the | 478 | /* Fill the FIFO - we assume there are enough bytes in the |
444 | pcm buffer to fill the 32-byte FIFO. */ | 479 | pcm buffer to fill the 32-byte FIFO. */ |
445 | while (p_size > 0) { | 480 | while (p_size > 0) { |
446 | if (FIFO_FREE_COUNT < 2) { | 481 | if (FIFO_FREE_COUNT < 2) { |
447 | /* Enable interrupt */ | 482 | /* Enable interrupt */ |
483 | #if CONFIG_CPU == PP5020 | ||
448 | IISCONFIG |= 0x2; | 484 | IISCONFIG |= 0x2; |
485 | #elif CONFIG_CPU == PP5002 | ||
486 | IISFIFO_CFG &= ~(1<<9); | ||
487 | #endif | ||
449 | return; | 488 | return; |
450 | } | 489 | } |
451 | 490 | ||
@@ -473,12 +512,23 @@ void pcm_play_pause(bool play) | |||
473 | { | 512 | { |
474 | logf("pause"); | 513 | logf("pause"); |
475 | 514 | ||
515 | #if CONFIG_CPU == PP5020 | ||
516 | |||
476 | /* Disable the interrupt */ | 517 | /* Disable the interrupt */ |
477 | IISCONFIG &= ~0x2; | 518 | IISCONFIG &= ~0x2; |
478 | 519 | ||
479 | /* Disable playback FIFO */ | 520 | /* Disable playback FIFO */ |
480 | IISCONFIG &= ~0x20000000; | 521 | IISCONFIG &= ~0x20000000; |
481 | 522 | ||
523 | #elif CONFIG_CPU == PP5002 | ||
524 | |||
525 | /* Disable the interrupt */ | ||
526 | IISFIFO_CFG &= ~(1<<9); | ||
527 | |||
528 | /* Disable playback FIFO */ | ||
529 | IISCONFIG &= ~0x4; | ||
530 | #endif | ||
531 | |||
482 | disable_fiq(); | 532 | disable_fiq(); |
483 | } | 533 | } |
484 | pcm_paused = !play; | 534 | pcm_paused = !play; |
@@ -500,7 +550,7 @@ bool pcm_is_playing(void) | |||
500 | actually needs to do so when calling callback_for_more. C version is still | 550 | actually needs to do so when calling callback_for_more. C version is still |
501 | included below for reference. | 551 | included below for reference. |
502 | */ | 552 | */ |
503 | #if 1 | 553 | #if CONFIG_CPU == PP5020 |
504 | void fiq(void) ICODE_ATTR __attribute__((naked)); | 554 | void fiq(void) ICODE_ATTR __attribute__((naked)); |
505 | void fiq(void) | 555 | void fiq(void) |
506 | { | 556 | { |
@@ -579,13 +629,22 @@ void fiq(void) ICODE_ATTR __attribute__ ((interrupt ("FIQ"))); | |||
579 | void fiq(void) | 629 | void fiq(void) |
580 | { | 630 | { |
581 | /* Clear interrupt */ | 631 | /* Clear interrupt */ |
632 | #if CONFIG_CPU == PP5020 | ||
582 | IISCONFIG &= ~0x2; | 633 | IISCONFIG &= ~0x2; |
634 | #elif CONFIG_CPU == PP5002 | ||
635 | inl(0xcf001040); | ||
636 | IISFIFO_CFG &= ~(1<<9); | ||
637 | #endif | ||
583 | 638 | ||
584 | do { | 639 | do { |
585 | while (p_size) { | 640 | while (p_size) { |
586 | if (FIFO_FREE_COUNT < 2) { | 641 | if (FIFO_FREE_COUNT < 2) { |
587 | /* Enable interrupt */ | 642 | /* Enable interrupt */ |
643 | #if CONFIG_CPU == PP5020 | ||
588 | IISCONFIG |= 0x2; | 644 | IISCONFIG |= 0x2; |
645 | #elif CONFIG_CPU == PP5002 | ||
646 | IISFIFO_CFG &= ~(1<<9); | ||
647 | #endif | ||
589 | return; | 648 | return; |
590 | } | 649 | } |
591 | 650 | ||
@@ -625,9 +684,9 @@ void pcm_init(void) | |||
625 | dma_stop(); | 684 | dma_stop(); |
626 | } | 685 | } |
627 | 686 | ||
628 | #elif (CONFIG_CPU == PNX0101) || (CONFIG_CPU == PP5002) | 687 | #elif (CONFIG_CPU == PNX0101) |
629 | 688 | ||
630 | /* TODO: Implement for iFP7xx and iPod 3G | 689 | /* TODO: Implement for iFP7xx |
631 | For now, just implement some dummy functions. | 690 | For now, just implement some dummy functions. |
632 | */ | 691 | */ |
633 | 692 | ||
@@ -686,7 +745,7 @@ size_t pcm_get_bytes_waiting(void) | |||
686 | 745 | ||
687 | #endif | 746 | #endif |
688 | 747 | ||
689 | #if (CONFIG_CPU != PNX0101) && (CONFIG_CPU != PP5002) | 748 | #if (CONFIG_CPU != PNX0101) |
690 | /* | 749 | /* |
691 | * This function goes directly into the DMA buffer to calculate the left and | 750 | * This function goes directly into the DMA buffer to calculate the left and |
692 | * right peak values. To avoid missing peaks it tries to look forward two full | 751 | * right peak values. To avoid missing peaks it tries to look forward two full |
@@ -704,12 +763,9 @@ void pcm_calculate_peaks(int *left, int *right) | |||
704 | #ifdef HAVE_UDA1380 | 763 | #ifdef HAVE_UDA1380 |
705 | long samples = (BCR0 & 0xffffff) / 4; | 764 | long samples = (BCR0 & 0xffffff) / 4; |
706 | short *addr = (short *) (SAR0 & ~3); | 765 | short *addr = (short *) (SAR0 & ~3); |
707 | #elif defined(HAVE_WM8975) || defined(HAVE_WM8758) | 766 | #elif defined(HAVE_WM8975) || defined(HAVE_WM8758) || defined(HAVE_WM8731) |
708 | long samples = p_size / 4; | 767 | long samples = p_size / 4; |
709 | short *addr = p; | 768 | short *addr = p; |
710 | #elif defined(HAVE_WM8731L) | ||
711 | long samples = next_size / 4; | ||
712 | short *addr = (short *)next_start; | ||
713 | #elif defined(HAVE_TLV320) | 769 | #elif defined(HAVE_TLV320) |
714 | long samples = 4; /* TODO X5 */ | 770 | long samples = 4; /* TODO X5 */ |
715 | short *addr = NULL; | 771 | short *addr = NULL; |
diff --git a/firmware/sound.c b/firmware/sound.c index a039cca609..f1c9ff79e7 100644 --- a/firmware/sound.c +++ b/firmware/sound.c | |||
@@ -30,6 +30,8 @@ | |||
30 | #include "wm8975.h" | 30 | #include "wm8975.h" |
31 | #elif defined(HAVE_WM8758) | 31 | #elif defined(HAVE_WM8758) |
32 | #include "wm8758.h" | 32 | #include "wm8758.h" |
33 | #elif defined(HAVE_WM8731) | ||
34 | #include "wm8731l.h" | ||
33 | #elif defined(HAVE_TLV320) | 35 | #elif defined(HAVE_TLV320) |
34 | #include "tlv320.h" | 36 | #include "tlv320.h" |
35 | #endif | 37 | #endif |
@@ -77,6 +79,10 @@ static const struct sound_settings_info sound_settings_table[] = { | |||
77 | [SOUND_VOLUME] = {"dB", 0, 1, -57, 6, -25, sound_set_volume}, | 79 | [SOUND_VOLUME] = {"dB", 0, 1, -57, 6, -25, sound_set_volume}, |
78 | [SOUND_BASS] = {"dB", 0, 1, -6, 9, 0, sound_set_bass}, | 80 | [SOUND_BASS] = {"dB", 0, 1, -6, 9, 0, sound_set_bass}, |
79 | [SOUND_TREBLE] = {"dB", 0, 1, -6, 9, 0, sound_set_treble}, | 81 | [SOUND_TREBLE] = {"dB", 0, 1, -6, 9, 0, sound_set_treble}, |
82 | #elif defined(HAVE_WM8731) | ||
83 | [SOUND_VOLUME] = {"dB", 0, 1, -73, 6, -25, sound_set_volume}, | ||
84 | [SOUND_BASS] = {"dB", 0, 1, -6, 9, 0, sound_set_bass}, | ||
85 | [SOUND_TREBLE] = {"dB", 0, 1, -6, 9, 0, sound_set_treble}, | ||
80 | #else /* MAS3507D */ | 86 | #else /* MAS3507D */ |
81 | [SOUND_VOLUME] = {"dB", 0, 1, -78, 18, -18, sound_set_volume}, | 87 | [SOUND_VOLUME] = {"dB", 0, 1, -78, 18, -18, sound_set_volume}, |
82 | [SOUND_BASS] = {"dB", 0, 1, -15, 15, 7, sound_set_bass}, | 88 | [SOUND_BASS] = {"dB", 0, 1, -15, 15, 7, sound_set_bass}, |
@@ -350,10 +356,44 @@ static int tenthdb2mixer(int db) | |||
350 | return -db * 2 / 5; | 356 | return -db * 2 / 5; |
351 | } | 357 | } |
352 | 358 | ||
359 | #elif defined(HAVE_WM8731) | ||
360 | /* volume/balance/treble/bass interdependency */ | ||
361 | #define VOLUME_MIN -730 | ||
362 | #define VOLUME_MAX 60 | ||
363 | |||
364 | /* convert tenth of dB volume (-730..60) to master volume register value */ | ||
365 | static int tenthdb2master(int db) | ||
366 | { | ||
367 | /* +6 to -73dB 1dB steps (plus mute == 80levels) 7bits */ | ||
368 | /* 1111111 == +6dB (0x7f) */ | ||
369 | /* 1111001 == 0dB (0x79) */ | ||
370 | /* 0110000 == -73dB (0x30 */ | ||
371 | /* 0101111 == mute (0x2f) */ | ||
372 | |||
373 | if (db <= -570) { | ||
374 | return 0x0; | ||
375 | } else { | ||
376 | return((db/10)+57); | ||
377 | } | ||
378 | } | ||
379 | |||
380 | /* convert tenth of dB volume (-780..0) to mixer volume register value */ | ||
381 | static int tenthdb2mixer(int db) | ||
382 | { | ||
383 | if (db < -660) /* 1.5 dB steps */ | ||
384 | return (2640 - db) / 15; | ||
385 | else if (db < -600) /* 0.75 dB steps */ | ||
386 | return (990 - db) * 2 / 15; | ||
387 | else if (db < -460) /* 0.5 dB steps */ | ||
388 | return (460 - db) / 5; | ||
389 | else /* 0.25 dB steps */ | ||
390 | return -db * 2 / 5; | ||
391 | } | ||
392 | |||
353 | #endif | 393 | #endif |
354 | 394 | ||
355 | #if (CONFIG_CODEC == MAS3507D) || defined HAVE_UDA1380 || \ | 395 | #if (CONFIG_CODEC == MAS3507D) || defined HAVE_UDA1380 || \ |
356 | defined HAVE_WM8975 || defined HAVE_WM8758 | 396 | defined HAVE_WM8975 || defined HAVE_WM8758 || defined(HAVE_WM8731) |
357 | /* volume/balance/treble/bass interdependency main part */ | 397 | /* volume/balance/treble/bass interdependency main part */ |
358 | #define VOLUME_RANGE (VOLUME_MAX - VOLUME_MIN) | 398 | #define VOLUME_RANGE (VOLUME_MAX - VOLUME_MIN) |
359 | 399 | ||
@@ -383,7 +423,7 @@ static void set_prescaled_volume(void) | |||
383 | mas_writereg(MAS_REG_KPRESCALE, prescale_table[prescale/10]); | 423 | mas_writereg(MAS_REG_KPRESCALE, prescale_table[prescale/10]); |
384 | #elif defined(HAVE_UDA1380) | 424 | #elif defined(HAVE_UDA1380) |
385 | uda1380_set_mixer_vol(tenthdb2mixer(-prescale), tenthdb2mixer(-prescale)); | 425 | uda1380_set_mixer_vol(tenthdb2mixer(-prescale), tenthdb2mixer(-prescale)); |
386 | #elif defined(HAVE_WM8975) || defined(HAVE_WM8758) | 426 | #elif defined(HAVE_WM8975) || defined(HAVE_WM8758) || defined(HAVE_WM8731) |
387 | wmcodec_set_mixer_vol(tenthdb2mixer(-prescale), tenthdb2mixer(-prescale)); | 427 | wmcodec_set_mixer_vol(tenthdb2mixer(-prescale), tenthdb2mixer(-prescale)); |
388 | #endif | 428 | #endif |
389 | 429 | ||
@@ -409,7 +449,7 @@ static void set_prescaled_volume(void) | |||
409 | dac_volume(tenthdb2reg(l), tenthdb2reg(r), false); | 449 | dac_volume(tenthdb2reg(l), tenthdb2reg(r), false); |
410 | #elif defined(HAVE_UDA1380) | 450 | #elif defined(HAVE_UDA1380) |
411 | uda1380_set_master_vol(tenthdb2master(l), tenthdb2master(r)); | 451 | uda1380_set_master_vol(tenthdb2master(l), tenthdb2master(r)); |
412 | #elif defined(HAVE_WM8975) || defined(HAVE_WM8758) | 452 | #elif defined(HAVE_WM8975) || defined(HAVE_WM8758) || defined(HAVE_WM8731) |
413 | wmcodec_set_master_vol(tenthdb2master(l), tenthdb2master(r)); | 453 | wmcodec_set_master_vol(tenthdb2master(l), tenthdb2master(r)); |
414 | #endif | 454 | #endif |
415 | } | 455 | } |
@@ -511,7 +551,7 @@ void sound_set_volume(int value) | |||
511 | unsigned tmp = ((unsigned)(value + 115) & 0xff) << 8; | 551 | unsigned tmp = ((unsigned)(value + 115) & 0xff) << 8; |
512 | mas_codec_writereg(0x10, tmp); | 552 | mas_codec_writereg(0x10, tmp); |
513 | #elif (CONFIG_CODEC == MAS3507D) || defined HAVE_UDA1380 || \ | 553 | #elif (CONFIG_CODEC == MAS3507D) || defined HAVE_UDA1380 || \ |
514 | defined HAVE_WM8975 || defined HAVE_WM8758 | 554 | defined HAVE_WM8975 || defined HAVE_WM8758 || defined HAVE_WM8731 |
515 | current_volume = value * 10; /* tenth of dB */ | 555 | current_volume = value * 10; /* tenth of dB */ |
516 | set_prescaled_volume(); | 556 | set_prescaled_volume(); |
517 | #elif CONFIG_CPU == PNX0101 | 557 | #elif CONFIG_CPU == PNX0101 |
@@ -528,7 +568,7 @@ void sound_set_balance(int value) | |||
528 | unsigned tmp = ((unsigned)(value * 127 / 100) & 0xff) << 8; | 568 | unsigned tmp = ((unsigned)(value * 127 / 100) & 0xff) << 8; |
529 | mas_codec_writereg(0x11, tmp); | 569 | mas_codec_writereg(0x11, tmp); |
530 | #elif CONFIG_CODEC == MAS3507D || defined HAVE_UDA1380 || \ | 570 | #elif CONFIG_CODEC == MAS3507D || defined HAVE_UDA1380 || \ |
531 | defined HAVE_WM8975 || defined HAVE_WM8758 | 571 | defined HAVE_WM8975 || defined HAVE_WM8758 || defined HAVE_WM8731 |
532 | current_balance = value * VOLUME_RANGE / 100; /* tenth of dB */ | 572 | current_balance = value * VOLUME_RANGE / 100; /* tenth of dB */ |
533 | set_prescaled_volume(); | 573 | set_prescaled_volume(); |
534 | #elif CONFIG_CPU == PNX0101 | 574 | #elif CONFIG_CPU == PNX0101 |
@@ -552,7 +592,7 @@ void sound_set_bass(int value) | |||
552 | uda1380_set_bass(value >> 1); | 592 | uda1380_set_bass(value >> 1); |
553 | current_bass = value * 10; | 593 | current_bass = value * 10; |
554 | set_prescaled_volume(); | 594 | set_prescaled_volume(); |
555 | #elif defined HAVE_WM8975 || defined HAVE_WM8758 | 595 | #elif defined HAVE_WM8975 || defined HAVE_WM8758 || defined HAVE_WM8731 |
556 | current_bass = value * 10; | 596 | current_bass = value * 10; |
557 | wmcodec_set_bass(value); | 597 | wmcodec_set_bass(value); |
558 | set_prescaled_volume(); | 598 | set_prescaled_volume(); |
@@ -577,7 +617,7 @@ void sound_set_treble(int value) | |||
577 | uda1380_set_treble(value >> 1); | 617 | uda1380_set_treble(value >> 1); |
578 | current_treble = value * 10; | 618 | current_treble = value * 10; |
579 | set_prescaled_volume(); | 619 | set_prescaled_volume(); |
580 | #elif defined(HAVE_WM8975) || defined(HAVE_WM8758) | 620 | #elif defined(HAVE_WM8975) || defined(HAVE_WM8758) || defined(HAVE_WM8731) |
581 | wmcodec_set_treble(value); | 621 | wmcodec_set_treble(value); |
582 | current_treble = value * 10; | 622 | current_treble = value * 10; |
583 | set_prescaled_volume(); | 623 | set_prescaled_volume(); |
diff --git a/firmware/system.c b/firmware/system.c index b47d983595..79004f8284 100644 --- a/firmware/system.c +++ b/firmware/system.c | |||
@@ -1237,10 +1237,6 @@ void irq(void) | |||
1237 | TIMER1(); | 1237 | TIMER1(); |
1238 | } | 1238 | } |
1239 | 1239 | ||
1240 | void fiq(void) | ||
1241 | { | ||
1242 | /** TODO: implement this function **/ | ||
1243 | } | ||
1244 | #endif | 1240 | #endif |
1245 | 1241 | ||
1246 | /* TODO: The following two function have been lifted straight from IPL, and | 1242 | /* TODO: The following two function have been lifted straight from IPL, and |