diff options
author | Dave Chapman <dave@dchapman.com> | 2006-02-13 13:48:08 +0000 |
---|---|---|
committer | Dave Chapman <dave@dchapman.com> | 2006-02-13 13:48:08 +0000 |
commit | 9581ad39ec15cf20350d01d2787dea0c7db6074d (patch) | |
tree | 28ead339e852346eb9f4e947e3494353cb687d72 | |
parent | b55f20a12d6b68d0f4f53ab19db76e8b5388d8bb (diff) | |
download | rockbox-9581ad39ec15cf20350d01d2787dea0c7db6074d.tar.gz rockbox-9581ad39ec15cf20350d01d2787dea0c7db6074d.zip |
iPod: Audio driver for iPod Video/5G. Rename wm8971_* functions to wmcodec_* to enable unification of the audio code for WM codecs
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@8676 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r-- | firmware/SOURCES | 2 | ||||
-rw-r--r-- | firmware/drivers/wm8758.c | 276 | ||||
-rw-r--r-- | firmware/drivers/wm8975.c | 36 | ||||
-rw-r--r-- | firmware/export/config-ipodvideo.h | 4 | ||||
-rw-r--r-- | firmware/export/wm8758.h | 74 | ||||
-rw-r--r-- | firmware/export/wm8975.h | 31 | ||||
-rw-r--r-- | firmware/pcm_playback.c | 14 | ||||
-rw-r--r-- | firmware/sound.c | 72 |
8 files changed, 453 insertions, 56 deletions
diff --git a/firmware/SOURCES b/firmware/SOURCES index 53923b3c35..15a5de8b7c 100644 --- a/firmware/SOURCES +++ b/firmware/SOURCES | |||
@@ -165,6 +165,8 @@ drivers/lcd-h100-remote.c | |||
165 | drivers/uda1380.c | 165 | drivers/uda1380.c |
166 | #elif defined(HAVE_WM8975) && !defined(SIMULATOR) | 166 | #elif defined(HAVE_WM8975) && !defined(SIMULATOR) |
167 | drivers/wm8975.c | 167 | drivers/wm8975.c |
168 | #elif defined(HAVE_WM8758) && !defined(SIMULATOR) | ||
169 | drivers/wm8758.c | ||
168 | #elif defined(HAVE_WM8731L) && !defined(SIMULATOR) | 170 | #elif defined(HAVE_WM8731L) && !defined(SIMULATOR) |
169 | drivers/wm8731l.c | 171 | drivers/wm8731l.c |
170 | #elif defined(HAVE_TLV320) && !defined(SIMULATOR) | 172 | #elif defined(HAVE_TLV320) && !defined(SIMULATOR) |
diff --git a/firmware/drivers/wm8758.c b/firmware/drivers/wm8758.c new file mode 100644 index 0000000000..3069b3cba7 --- /dev/null +++ b/firmware/drivers/wm8758.c | |||
@@ -0,0 +1,276 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Driver for WM8758 audio codec | ||
11 | * | ||
12 | * Based on code from the ipodlinux project - http://ipodlinux.org/ | ||
13 | * Adapted for Rockbox in December 2005 | ||
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 "lcd.h" | ||
27 | #include "cpu.h" | ||
28 | #include "kernel.h" | ||
29 | #include "thread.h" | ||
30 | #include "power.h" | ||
31 | #include "debug.h" | ||
32 | #include "system.h" | ||
33 | #include "sprintf.h" | ||
34 | #include "button.h" | ||
35 | #include "string.h" | ||
36 | #include "file.h" | ||
37 | #include "buffer.h" | ||
38 | #include "audio.h" | ||
39 | |||
40 | #include "i2c-pp5020.h" | ||
41 | #include "wm8758.h" | ||
42 | #include "pcf50605.h" | ||
43 | |||
44 | void wmcodec_reset(void); | ||
45 | |||
46 | #define IPOD_PCM_LEVEL 0x65 /* -6dB */ | ||
47 | |||
48 | //#define BASSCTRL 0x | ||
49 | //#define TREBCTRL 0x0b | ||
50 | |||
51 | /* | ||
52 | * Reset the I2S BIT.FORMAT I2S, 16bit, FIFO.FORMAT 32bit | ||
53 | */ | ||
54 | static void i2s_reset(void) | ||
55 | { | ||
56 | /* PP502x */ | ||
57 | |||
58 | /* I2S soft reset */ | ||
59 | outl(inl(0x70002800) | 0x80000000, 0x70002800); | ||
60 | outl(inl(0x70002800) & ~0x80000000, 0x70002800); | ||
61 | |||
62 | /* BIT.FORMAT [11:10] = I2S (default) */ | ||
63 | outl(inl(0x70002800) & ~0xc00, 0x70002800); | ||
64 | /* BIT.SIZE [9:8] = 16bit (default) */ | ||
65 | outl(inl(0x70002800) & ~0x300, 0x70002800); | ||
66 | |||
67 | /* FIFO.FORMAT [6:4] = 32 bit LSB */ | ||
68 | /* since BIT.SIZ < FIFO.FORMAT low 16 bits will be 0 */ | ||
69 | outl(inl(0x70002800) | 0x30, 0x70002800); | ||
70 | |||
71 | /* RX_ATN_LVL=1 == when 12 slots full */ | ||
72 | /* TX_ATN_LVL=1 == when 12 slots empty */ | ||
73 | outl(inl(0x7000280c) | 0x33, 0x7000280c); | ||
74 | |||
75 | /* Rx.CLR = 1, TX.CLR = 1 */ | ||
76 | outl(inl(0x7000280c) | 0x1100, 0x7000280c); | ||
77 | } | ||
78 | |||
79 | void wm8758_write(int reg, int data) | ||
80 | { | ||
81 | ipod_i2c_send(0x1a, (reg<<1) | ((data&0x100)>>8),data&0xff); | ||
82 | } | ||
83 | |||
84 | /* | ||
85 | * Initialise the WM8758 for playback via headphone and line out. | ||
86 | * Note, I'm using the WM8750 datasheet as its apparently close. | ||
87 | */ | ||
88 | int wmcodec_init(void) { | ||
89 | /* reset I2C */ | ||
90 | i2c_init(); | ||
91 | |||
92 | /* normal outputs for CDI and I2S pin groups */ | ||
93 | outl(inl(0x70000020) & ~0x300, 0x70000020); | ||
94 | |||
95 | /*mini2?*/ | ||
96 | outl(inl(0x70000010) & ~0x3000000, 0x70000010); | ||
97 | /*mini2?*/ | ||
98 | |||
99 | /* device reset */ | ||
100 | outl(inl(0x60006004) | 0x800, 0x60006004); | ||
101 | outl(inl(0x60006004) & ~0x800, 0x60006004); | ||
102 | |||
103 | /* device enable */ | ||
104 | outl(inl(0x6000600C) | 0x807, 0x6000600C); | ||
105 | |||
106 | /* enable external dev clock clocks */ | ||
107 | outl(inl(0x6000600c) | 0x2, 0x6000600c); | ||
108 | |||
109 | /* external dev clock to 24MHz */ | ||
110 | outl(inl(0x70000018) & ~0xc, 0x70000018); | ||
111 | |||
112 | return 0; | ||
113 | } | ||
114 | |||
115 | /* Silently enable / disable audio output */ | ||
116 | void wmcodec_enable_output(bool enable) | ||
117 | { | ||
118 | if (enable) | ||
119 | { | ||
120 | /* reset the I2S controller into known state */ | ||
121 | i2s_reset(); | ||
122 | |||
123 | wm8758_write(RESET, 0x1ff); /*Reset*/ | ||
124 | |||
125 | wm8758_write(PWRMGMT1, 0x2b); | ||
126 | wm8758_write(PWRMGMT2, 0x180); | ||
127 | wm8758_write(PWRMGMT3, 0x6f); | ||
128 | |||
129 | wm8758_write(AINTFCE, 0x10); | ||
130 | wm8758_write(CLKCTRL, 0x49); | ||
131 | |||
132 | wm8758_write(OUTCTRL, 1 | (0x3 << 5)); | ||
133 | |||
134 | /* The iPod can handle multiple frequencies, but fix at 44.1KHz | ||
135 | for now */ | ||
136 | wmcodec_set_sample_rate(WM8758_44100HZ); | ||
137 | |||
138 | wm8758_write(LOUTMIX,0x1); /* Enable mixer */ | ||
139 | wm8758_write(ROUTMIX,0x1); /* Enable mixer */ | ||
140 | wmcodec_mute(0); | ||
141 | } else { | ||
142 | wmcodec_mute(1); | ||
143 | } | ||
144 | } | ||
145 | |||
146 | int wmcodec_set_master_vol(int vol_l, int vol_r) | ||
147 | { | ||
148 | /* +6 to -73dB 1dB steps (plus mute == 80levels) 7bits */ | ||
149 | /* 1111111 == +6dB */ | ||
150 | /* 1111001 == 0dB */ | ||
151 | /* 0110000 == -73dB */ | ||
152 | /* 0101111 == mute (0x2f) */ | ||
153 | |||
154 | /* OUT1 */ | ||
155 | wm8758_write(LOUT1VOL, vol_l); | ||
156 | wm8758_write(ROUT1VOL, 0x100 | vol_r); | ||
157 | |||
158 | /* OUT2 */ | ||
159 | wm8758_write(LOUT2VOL, vol_l); | ||
160 | wm8758_write(ROUT2VOL, 0x100 | vol_r); | ||
161 | |||
162 | return 0; | ||
163 | } | ||
164 | |||
165 | int wmcodec_set_mixer_vol(int channel1, int channel2) | ||
166 | { | ||
167 | (void)channel1; | ||
168 | (void)channel2; | ||
169 | |||
170 | return 0; | ||
171 | } | ||
172 | |||
173 | /* We are using Linear bass control */ | ||
174 | void wmcodec_set_bass(int value) | ||
175 | { | ||
176 | (void)value; | ||
177 | #if 0 | ||
178 | /* Not yet implemented - this is the wm8975 code*/ | ||
179 | int regvalues[]={11, 10, 10, 9, 8, 8, 0xf , 6, 6, 5, 4, 4, 3, 2, 1, 0}; | ||
180 | |||
181 | if ((value >= -6) && (value <= 9)) { | ||
182 | /* We use linear bass control with 130Hz cutoff */ | ||
183 | wm8758_write(BASSCTRL, regvalues[value+6]); | ||
184 | } | ||
185 | #endif | ||
186 | } | ||
187 | |||
188 | void wmcodec_set_treble(int value) | ||
189 | { | ||
190 | (void)value; | ||
191 | #if 0 | ||
192 | /* Not yet implemented - this is the wm8975 code*/ | ||
193 | int regvalues[]={11, 10, 10, 9, 8, 8, 0xf , 6, 6, 5, 4, 4, 3, 2, 1, 0}; | ||
194 | |||
195 | if ((value >= -6) && (value <= 9)) { | ||
196 | /* We use a 8Khz cutoff */ | ||
197 | wm8758_write(TREBCTRL, regvalues[value+6]); | ||
198 | } | ||
199 | #endif | ||
200 | |||
201 | } | ||
202 | |||
203 | int wmcodec_mute(int mute) | ||
204 | { | ||
205 | if (mute) | ||
206 | { | ||
207 | /* Set DACMU = 1 to soft-mute the audio DACs. */ | ||
208 | wm8758_write(DACCTRL, 0x40); | ||
209 | } else { | ||
210 | /* Set DACMU = 0 to soft-un-mute the audio DACs. */ | ||
211 | wm8758_write(DACCTRL, 0x0); | ||
212 | } | ||
213 | |||
214 | return 0; | ||
215 | } | ||
216 | |||
217 | /* Nice shutdown of WM8758 codec */ | ||
218 | void wmcodec_close(void) | ||
219 | { | ||
220 | wmcodec_mute(1); | ||
221 | |||
222 | wm8758_write(PWRMGMT3, 0x0); | ||
223 | |||
224 | wm8758_write(PWRMGMT1, 0x0); | ||
225 | |||
226 | wm8758_write(PWRMGMT2, 0x40); | ||
227 | } | ||
228 | |||
229 | /* Change the order of the noise shaper, 5th order is recommended above 32kHz */ | ||
230 | void wmcodec_set_nsorder(int order) | ||
231 | { | ||
232 | (void)order; | ||
233 | } | ||
234 | |||
235 | /* Note: Disable output before calling this function */ | ||
236 | void wmcodec_set_sample_rate(int sampling_control) | ||
237 | { | ||
238 | /**** We force 44.1KHz for now. ****/ | ||
239 | (void)sampling_control; | ||
240 | |||
241 | /* set clock div */ | ||
242 | wm8758_write(CLKCTRL, 1 | (0 << 2) | (2 << 5)); | ||
243 | |||
244 | /* setup PLL for MHZ=11.2896 */ | ||
245 | wm8758_write(PLLN, (1 << 4) | 0x7); | ||
246 | wm8758_write(PLLK1, 0x21); | ||
247 | wm8758_write(PLLK2, 0x161); | ||
248 | wm8758_write(PLLK3, 0x26); | ||
249 | |||
250 | /* set clock div */ | ||
251 | wm8758_write(CLKCTRL, 1 | (0 << 2) | (2 << 5) | (1 << 8)); | ||
252 | |||
253 | /* set srate */ | ||
254 | wm8758_write(SRATECTRL, (0 << 1)); | ||
255 | } | ||
256 | |||
257 | void wmcodec_enable_recording(bool source_mic) | ||
258 | { | ||
259 | (void)source_mic; | ||
260 | } | ||
261 | |||
262 | void wmcodec_disable_recording(void) { | ||
263 | |||
264 | } | ||
265 | |||
266 | void wmcodec_set_recvol(int left, int right, int type) { | ||
267 | |||
268 | (void)left; | ||
269 | (void)right; | ||
270 | (void)type; | ||
271 | } | ||
272 | |||
273 | void wmcodec_set_monitor(int enable) { | ||
274 | |||
275 | (void)enable; | ||
276 | } | ||
diff --git a/firmware/drivers/wm8975.c b/firmware/drivers/wm8975.c index 54e245b61a..51c12f1505 100644 --- a/firmware/drivers/wm8975.c +++ b/firmware/drivers/wm8975.c | |||
@@ -41,7 +41,7 @@ | |||
41 | #include "wm8975.h" | 41 | #include "wm8975.h" |
42 | #include "pcf50605.h" | 42 | #include "pcf50605.h" |
43 | 43 | ||
44 | void wm8975_reset(void); | 44 | void wmcodec_reset(void); |
45 | 45 | ||
46 | #define IPOD_PCM_LEVEL 0x65 /* -6dB */ | 46 | #define IPOD_PCM_LEVEL 0x65 /* -6dB */ |
47 | 47 | ||
@@ -82,7 +82,7 @@ void wm8975_write(int reg, int data) | |||
82 | * Initialise the WM8975 for playback via headphone and line out. | 82 | * Initialise the WM8975 for playback via headphone and line out. |
83 | * Note, I'm using the WM8750 datasheet as its apparently close. | 83 | * Note, I'm using the WM8750 datasheet as its apparently close. |
84 | */ | 84 | */ |
85 | int wm8975_init(void) { | 85 | int wmcodec_init(void) { |
86 | /* reset I2C */ | 86 | /* reset I2C */ |
87 | i2c_init(); | 87 | i2c_init(); |
88 | 88 | ||
@@ -110,7 +110,7 @@ int wm8975_init(void) { | |||
110 | } | 110 | } |
111 | 111 | ||
112 | /* Silently enable / disable audio output */ | 112 | /* Silently enable / disable audio output */ |
113 | void wm8975_enable_output(bool enable) | 113 | void wmcodec_enable_output(bool enable) |
114 | { | 114 | { |
115 | if (enable) | 115 | if (enable) |
116 | { | 116 | { |
@@ -141,7 +141,7 @@ void wm8975_enable_output(bool enable) | |||
141 | wm8975_write(AINTFCE, 0x42); | 141 | wm8975_write(AINTFCE, 0x42); |
142 | 142 | ||
143 | /* The iPod can handle multiple frequencies, but fix at 44.1KHz for now */ | 143 | /* The iPod can handle multiple frequencies, but fix at 44.1KHz for now */ |
144 | wm8975_set_sample_rate(WM8975_44100HZ); | 144 | wmcodec_set_sample_rate(WM8975_44100HZ); |
145 | 145 | ||
146 | /* set the volume to -6dB */ | 146 | /* set the volume to -6dB */ |
147 | wm8975_write(LOUT1VOL, IPOD_PCM_LEVEL); | 147 | wm8975_write(LOUT1VOL, IPOD_PCM_LEVEL); |
@@ -158,13 +158,13 @@ void wm8975_enable_output(bool enable) | |||
158 | wm8975_write(MOUTMIX1, 0x0); /* Mono out Mix */ | 158 | wm8975_write(MOUTMIX1, 0x0); /* Mono out Mix */ |
159 | wm8975_write(MOUTMIX2, 0x0); | 159 | wm8975_write(MOUTMIX2, 0x0); |
160 | 160 | ||
161 | wm8975_mute(0); | 161 | wmcodec_mute(0); |
162 | } else { | 162 | } else { |
163 | wm8975_mute(1); | 163 | wmcodec_mute(1); |
164 | } | 164 | } |
165 | } | 165 | } |
166 | 166 | ||
167 | int wm8975_set_master_vol(int vol_l, int vol_r) | 167 | int wmcodec_set_master_vol(int vol_l, int vol_r) |
168 | { | 168 | { |
169 | /* +6 to -73dB 1dB steps (plus mute == 80levels) 7bits */ | 169 | /* +6 to -73dB 1dB steps (plus mute == 80levels) 7bits */ |
170 | /* 1111111 == +6dB */ | 170 | /* 1111111 == +6dB */ |
@@ -183,7 +183,7 @@ int wm8975_set_master_vol(int vol_l, int vol_r) | |||
183 | return 0; | 183 | return 0; |
184 | } | 184 | } |
185 | 185 | ||
186 | int wm8975_set_mixer_vol(int channel1, int channel2) | 186 | int wmcodec_set_mixer_vol(int channel1, int channel2) |
187 | { | 187 | { |
188 | (void)channel1; | 188 | (void)channel1; |
189 | (void)channel2; | 189 | (void)channel2; |
@@ -192,7 +192,7 @@ int wm8975_set_mixer_vol(int channel1, int channel2) | |||
192 | } | 192 | } |
193 | 193 | ||
194 | /* We are using Linear bass control */ | 194 | /* We are using Linear bass control */ |
195 | void wm8975_set_bass(int value) | 195 | void wmcodec_set_bass(int value) |
196 | { | 196 | { |
197 | int regvalues[]={11, 10, 10, 9, 8, 8, 0xf , 6, 6, 5, 4, 4, 3, 2, 1, 0}; | 197 | int regvalues[]={11, 10, 10, 9, 8, 8, 0xf , 6, 6, 5, 4, 4, 3, 2, 1, 0}; |
198 | 198 | ||
@@ -202,7 +202,7 @@ void wm8975_set_bass(int value) | |||
202 | } | 202 | } |
203 | } | 203 | } |
204 | 204 | ||
205 | void wm8975_set_treble(int value) | 205 | void wmcodec_set_treble(int value) |
206 | { | 206 | { |
207 | int regvalues[]={11, 10, 10, 9, 8, 8, 0xf , 6, 6, 5, 4, 4, 3, 2, 1, 0}; | 207 | int regvalues[]={11, 10, 10, 9, 8, 8, 0xf , 6, 6, 5, 4, 4, 3, 2, 1, 0}; |
208 | 208 | ||
@@ -212,7 +212,7 @@ void wm8975_set_treble(int value) | |||
212 | } | 212 | } |
213 | } | 213 | } |
214 | 214 | ||
215 | int wm8975_mute(int mute) | 215 | int wmcodec_mute(int mute) |
216 | { | 216 | { |
217 | if (mute) | 217 | if (mute) |
218 | { | 218 | { |
@@ -227,7 +227,7 @@ int wm8975_mute(int mute) | |||
227 | } | 227 | } |
228 | 228 | ||
229 | /* Nice shutdown of WM8975 codec */ | 229 | /* Nice shutdown of WM8975 codec */ |
230 | void wm8975_close(void) | 230 | void wmcodec_close(void) |
231 | { | 231 | { |
232 | /* 1. Set DACMU = 1 to soft-mute the audio DACs. */ | 232 | /* 1. Set DACMU = 1 to soft-mute the audio DACs. */ |
233 | wm8975_write(DACCTRL, 0x8); | 233 | wm8975_write(DACCTRL, 0x8); |
@@ -240,35 +240,35 @@ void wm8975_close(void) | |||
240 | } | 240 | } |
241 | 241 | ||
242 | /* Change the order of the noise shaper, 5th order is recommended above 32kHz */ | 242 | /* Change the order of the noise shaper, 5th order is recommended above 32kHz */ |
243 | void wm8975_set_nsorder(int order) | 243 | void wmcodec_set_nsorder(int order) |
244 | { | 244 | { |
245 | (void)order; | 245 | (void)order; |
246 | } | 246 | } |
247 | 247 | ||
248 | /* Note: Disable output before calling this function */ | 248 | /* Note: Disable output before calling this function */ |
249 | void wm8975_set_sample_rate(int sampling_control) { | 249 | void wmcodec_set_sample_rate(int sampling_control) { |
250 | 250 | ||
251 | wm8975_write(0x08, sampling_control); | 251 | wm8975_write(0x08, sampling_control); |
252 | 252 | ||
253 | } | 253 | } |
254 | 254 | ||
255 | void wm8975_enable_recording(bool source_mic) { | 255 | void wmcodec_enable_recording(bool source_mic) { |
256 | 256 | ||
257 | (void)source_mic; | 257 | (void)source_mic; |
258 | } | 258 | } |
259 | 259 | ||
260 | void wm8975_disable_recording(void) { | 260 | void wmcodec_disable_recording(void) { |
261 | 261 | ||
262 | } | 262 | } |
263 | 263 | ||
264 | void wm8975_set_recvol(int left, int right, int type) { | 264 | void wmcodec_set_recvol(int left, int right, int type) { |
265 | 265 | ||
266 | (void)left; | 266 | (void)left; |
267 | (void)right; | 267 | (void)right; |
268 | (void)type; | 268 | (void)type; |
269 | } | 269 | } |
270 | 270 | ||
271 | void wm8975_set_monitor(int enable) { | 271 | void wmcodec_set_monitor(int enable) { |
272 | 272 | ||
273 | (void)enable; | 273 | (void)enable; |
274 | } | 274 | } |
diff --git a/firmware/export/config-ipodvideo.h b/firmware/export/config-ipodvideo.h index 160a2db383..2bf0396a21 100644 --- a/firmware/export/config-ipodvideo.h +++ b/firmware/export/config-ipodvideo.h | |||
@@ -42,8 +42,8 @@ | |||
42 | /* The number of bytes reserved for loadable plugins */ | 42 | /* The number of bytes reserved for loadable plugins */ |
43 | #define PLUGIN_BUFFER_SIZE 0x80000 | 43 | #define PLUGIN_BUFFER_SIZE 0x80000 |
44 | 44 | ||
45 | /* Define this if you have the WM8975 audio codec */ | 45 | /* Define this if you have the WM8758 audio codec */ |
46 | #define HAVE_WM8975 | 46 | #define HAVE_WM8758 |
47 | 47 | ||
48 | /* Define this for LCD backlight available */ | 48 | /* Define this for LCD backlight available */ |
49 | #define CONFIG_BACKLIGHT BL_IPODNANO /* port controlled */ | 49 | #define CONFIG_BACKLIGHT BL_IPODNANO /* port controlled */ |
diff --git a/firmware/export/wm8758.h b/firmware/export/wm8758.h new file mode 100644 index 0000000000..adc17f86d7 --- /dev/null +++ b/firmware/export/wm8758.h | |||
@@ -0,0 +1,74 @@ | |||
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 _WM8758_H | ||
21 | #define _WM8758_H | ||
22 | |||
23 | extern void wmcodec_reset(void); | ||
24 | extern int wmcodec_init(void); | ||
25 | extern void wmcodec_enable_output(bool enable); | ||
26 | extern int wmcodec_set_master_vol(int vol_l, int vol_r); | ||
27 | extern int wmcodec_set_mixer_vol(int channel1, int channel2); | ||
28 | extern void wmcodec_set_bass(int value); | ||
29 | extern void wmcodec_set_treble(int value); | ||
30 | extern int wmcodec_mute(int mute); | ||
31 | extern void wmcodec_close(void); | ||
32 | extern void wmcodec_set_nsorder(int order); | ||
33 | extern void wmcodec_set_sample_rate(int sampling_control); | ||
34 | |||
35 | extern void wmcodec_enable_recording(bool source_mic); | ||
36 | extern void wmcodec_disable_recording(void); | ||
37 | extern void wmcodec_set_recvol(int left, int right, int type); | ||
38 | extern void wmcodec_set_monitor(int enable); | ||
39 | |||
40 | #define RESET 0x00 | ||
41 | #define PWRMGMT1 0x01 | ||
42 | #define PWRMGMT2 0x02 | ||
43 | #define PWRMGMT3 0x03 | ||
44 | #define AINTFCE 0x04 | ||
45 | #define CLKCTRL 0x06 | ||
46 | #define SRATECTRL 0x07 | ||
47 | #define DACCTRL 0x0a | ||
48 | #define OUTCTRL 0x31 | ||
49 | #define LOUTMIX 0x32 | ||
50 | #define ROUTMIX 0x33 | ||
51 | |||
52 | #define LOUT1VOL 0x34 | ||
53 | #define ROUT1VOL 0x35 | ||
54 | #define LOUT2VOL 0x36 | ||
55 | #define ROUT2VOL 0x37 | ||
56 | |||
57 | #define PLLN 0x24 | ||
58 | #define PLLK1 0x25 | ||
59 | #define PLLK2 0x26 | ||
60 | #define PLLK3 0x27 | ||
61 | |||
62 | /* Register settings for the supported samplerates: */ | ||
63 | #define WM8758_8000HZ 0x4d | ||
64 | #define WM8758_12000HZ 0x61 | ||
65 | #define WM8758_16000HZ 0x55 | ||
66 | #define WM8758_22050HZ 0x77 | ||
67 | #define WM8758_24000HZ 0x79 | ||
68 | #define WM8758_32000HZ 0x59 | ||
69 | #define WM8758_44100HZ 0x63 | ||
70 | #define WM8758_48000HZ 0x41 | ||
71 | #define WM8758_88200HZ 0x7f | ||
72 | #define WM8758_96000HZ 0x5d | ||
73 | |||
74 | #endif /* _WM8758_H */ | ||
diff --git a/firmware/export/wm8975.h b/firmware/export/wm8975.h index 1d63159748..4d575c3d90 100644 --- a/firmware/export/wm8975.h +++ b/firmware/export/wm8975.h | |||
@@ -20,22 +20,22 @@ | |||
20 | #ifndef _WM8975_H | 20 | #ifndef _WM8975_H |
21 | #define _WM8975_H | 21 | #define _WM8975_H |
22 | 22 | ||
23 | extern void wm8975_reset(void); | 23 | extern void wmcodec_reset(void); |
24 | extern int wm8975_init(void); | 24 | extern int wmcodec_init(void); |
25 | extern void wm8975_enable_output(bool enable); | 25 | extern void wmcodec_enable_output(bool enable); |
26 | extern int wm8975_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 wm8975_set_mixer_vol(int channel1, int channel2); | 27 | extern int wmcodec_set_mixer_vol(int channel1, int channel2); |
28 | extern void wm8975_set_bass(int value); | 28 | extern void wmcodec_set_bass(int value); |
29 | extern void wm8975_set_treble(int value); | 29 | extern void wmcodec_set_treble(int value); |
30 | extern int wm8975_mute(int mute); | 30 | extern int wmcodec_mute(int mute); |
31 | extern void wm8975_close(void); | 31 | extern void wmcodec_close(void); |
32 | extern void wm8975_set_nsorder(int order); | 32 | extern void wmcodec_set_nsorder(int order); |
33 | extern void wm8975_set_sample_rate(int sampling_control); | 33 | extern void wmcodec_set_sample_rate(int sampling_control); |
34 | 34 | ||
35 | extern void wm8975_enable_recording(bool source_mic); | 35 | extern void wmcodec_enable_recording(bool source_mic); |
36 | extern void wm8975_disable_recording(void); | 36 | extern void wmcodec_disable_recording(void); |
37 | extern void wm8975_set_recvol(int left, int right, int type); | 37 | extern void wmcodec_set_recvol(int left, int right, int type); |
38 | extern void wm8975_set_monitor(int enable); | 38 | extern void wmcodec_set_monitor(int enable); |
39 | 39 | ||
40 | /* Register addresses */ | 40 | /* Register addresses */ |
41 | #define LOUT1VOL 0x02 | 41 | #define LOUT1VOL 0x02 |
@@ -56,7 +56,6 @@ extern void wm8975_set_monitor(int enable); | |||
56 | #define LOUT2VOL 0x28 | 56 | #define LOUT2VOL 0x28 |
57 | #define ROUT2VOL 0x29 | 57 | #define ROUT2VOL 0x29 |
58 | 58 | ||
59 | |||
60 | /* Register settings for the supported samplerates: */ | 59 | /* Register settings for the supported samplerates: */ |
61 | #define WM8975_8000HZ 0x4d | 60 | #define WM8975_8000HZ 0x4d |
62 | #define WM8975_12000HZ 0x61 | 61 | #define WM8975_12000HZ 0x61 |
diff --git a/firmware/pcm_playback.c b/firmware/pcm_playback.c index c55b48699b..1e9cac31f5 100644 --- a/firmware/pcm_playback.c +++ b/firmware/pcm_playback.c | |||
@@ -28,6 +28,8 @@ | |||
28 | #include "uda1380.h" | 28 | #include "uda1380.h" |
29 | #elif defined(HAVE_WM8975) | 29 | #elif defined(HAVE_WM8975) |
30 | #include "wm8975.h" | 30 | #include "wm8975.h" |
31 | #elif defined(HAVE_WM8758) | ||
32 | #include "wm8758.h" | ||
31 | #elif defined(HAVE_TLV320) | 33 | #elif defined(HAVE_TLV320) |
32 | #include "tlv320.h" | 34 | #include "tlv320.h" |
33 | #elif defined(HAVE_WM8731L) | 35 | #elif defined(HAVE_WM8731L) |
@@ -314,7 +316,7 @@ void pcm_init(void) | |||
314 | dma_stop(); | 316 | dma_stop(); |
315 | } | 317 | } |
316 | 318 | ||
317 | #elif defined(HAVE_WM8975) | 319 | #elif defined(HAVE_WM8975) || defined(HAVE_WM8758) |
318 | 320 | ||
319 | /* We need to unify this code with the uda1380 code as much as possible, but | 321 | /* We need to unify this code with the uda1380 code as much as possible, but |
320 | we will keep it separate during early development. | 322 | we will keep it separate during early development. |
@@ -408,7 +410,7 @@ size_t pcm_get_bytes_waiting(void) | |||
408 | 410 | ||
409 | void pcm_mute(bool mute) | 411 | void pcm_mute(bool mute) |
410 | { | 412 | { |
411 | wm8975_mute(mute); | 413 | wmcodec_mute(mute); |
412 | if (mute) | 414 | if (mute) |
413 | sleep(HZ/16); | 415 | sleep(HZ/16); |
414 | } | 416 | } |
@@ -532,15 +534,15 @@ void pcm_init(void) | |||
532 | pcm_paused = false; | 534 | pcm_paused = false; |
533 | 535 | ||
534 | /* Initialize default register values. */ | 536 | /* Initialize default register values. */ |
535 | wm8975_init(); | 537 | wmcodec_init(); |
536 | 538 | ||
537 | /* The uda1380 needs a sleep(HZ) here - do we need one? */ | 539 | /* The uda1380 needs a sleep(HZ) here - do we need one? */ |
538 | 540 | ||
539 | /* Power on */ | 541 | /* Power on */ |
540 | wm8975_enable_output(true); | 542 | wmcodec_enable_output(true); |
541 | 543 | ||
542 | /* Unmute the master channel (DAC should be at zero point now). */ | 544 | /* Unmute the master channel (DAC should be at zero point now). */ |
543 | wm8975_mute(false); | 545 | wmcodec_mute(false); |
544 | 546 | ||
545 | /* Call dma_stop to initialize everything. */ | 547 | /* Call dma_stop to initialize everything. */ |
546 | dma_stop(); | 548 | dma_stop(); |
@@ -625,7 +627,7 @@ void pcm_calculate_peaks(int *left, int *right) | |||
625 | #ifdef HAVE_UDA1380 | 627 | #ifdef HAVE_UDA1380 |
626 | long samples = (BCR0 & 0xffffff) / 4; | 628 | long samples = (BCR0 & 0xffffff) / 4; |
627 | short *addr = (short *) (SAR0 & ~3); | 629 | short *addr = (short *) (SAR0 & ~3); |
628 | #elif defined(HAVE_WM8975) | 630 | #elif defined(HAVE_WM8975) || defined(HAVE_WM8758) |
629 | long samples = p_size / 4; | 631 | long samples = p_size / 4; |
630 | short *addr = p; | 632 | short *addr = p; |
631 | #elif defined(HAVE_WM8731L) | 633 | #elif defined(HAVE_WM8731L) |
diff --git a/firmware/sound.c b/firmware/sound.c index 110c2c91b8..a039cca609 100644 --- a/firmware/sound.c +++ b/firmware/sound.c | |||
@@ -28,6 +28,8 @@ | |||
28 | #include "uda1380.h" | 28 | #include "uda1380.h" |
29 | #elif defined(HAVE_WM8975) | 29 | #elif defined(HAVE_WM8975) |
30 | #include "wm8975.h" | 30 | #include "wm8975.h" |
31 | #elif defined(HAVE_WM8758) | ||
32 | #include "wm8758.h" | ||
31 | #elif defined(HAVE_TLV320) | 33 | #elif defined(HAVE_TLV320) |
32 | #include "tlv320.h" | 34 | #include "tlv320.h" |
33 | #endif | 35 | #endif |
@@ -71,6 +73,10 @@ static const struct sound_settings_info sound_settings_table[] = { | |||
71 | [SOUND_VOLUME] = {"dB", 0, 1, -73, 6, -25, sound_set_volume}, | 73 | [SOUND_VOLUME] = {"dB", 0, 1, -73, 6, -25, sound_set_volume}, |
72 | [SOUND_BASS] = {"dB", 0, 1, -6, 9, 0, sound_set_bass}, | 74 | [SOUND_BASS] = {"dB", 0, 1, -6, 9, 0, sound_set_bass}, |
73 | [SOUND_TREBLE] = {"dB", 0, 1, -6, 9, 0, sound_set_treble}, | 75 | [SOUND_TREBLE] = {"dB", 0, 1, -6, 9, 0, sound_set_treble}, |
76 | #elif defined(HAVE_WM8758) | ||
77 | [SOUND_VOLUME] = {"dB", 0, 1, -57, 6, -25, sound_set_volume}, | ||
78 | [SOUND_BASS] = {"dB", 0, 1, -6, 9, 0, sound_set_bass}, | ||
79 | [SOUND_TREBLE] = {"dB", 0, 1, -6, 9, 0, sound_set_treble}, | ||
74 | #else /* MAS3507D */ | 80 | #else /* MAS3507D */ |
75 | [SOUND_VOLUME] = {"dB", 0, 1, -78, 18, -18, sound_set_volume}, | 81 | [SOUND_VOLUME] = {"dB", 0, 1, -78, 18, -18, sound_set_volume}, |
76 | [SOUND_BASS] = {"dB", 0, 1, -15, 15, 7, sound_set_bass}, | 82 | [SOUND_BASS] = {"dB", 0, 1, -15, 15, 7, sound_set_bass}, |
@@ -276,7 +282,8 @@ static int tenthdb2mixer(int db) | |||
276 | return -db * 2 / 5; | 282 | return -db * 2 / 5; |
277 | } | 283 | } |
278 | 284 | ||
279 | #elif defined(HAVE_WM8975) /* volume/balance/treble/bass interdependency */ | 285 | #elif defined(HAVE_WM8975) |
286 | /* volume/balance/treble/bass interdependency */ | ||
280 | #define VOLUME_MIN -730 | 287 | #define VOLUME_MIN -730 |
281 | #define VOLUME_MAX 60 | 288 | #define VOLUME_MAX 60 |
282 | 289 | ||
@@ -290,9 +297,43 @@ static int tenthdb2master(int db) | |||
290 | /* 0101111 == mute (0x2f) */ | 297 | /* 0101111 == mute (0x2f) */ |
291 | 298 | ||
292 | if (db <= -730) { | 299 | if (db <= -730) { |
293 | return 0x2f; | 300 | return 0x0; |
294 | } else { | 301 | } else { |
295 | return((db/10)+74+0x2f); | 302 | return((db/10)+73+0x2f); |
303 | } | ||
304 | } | ||
305 | |||
306 | /* convert tenth of dB volume (-780..0) to mixer volume register value */ | ||
307 | static int tenthdb2mixer(int db) | ||
308 | { | ||
309 | if (db < -660) /* 1.5 dB steps */ | ||
310 | return (2640 - db) / 15; | ||
311 | else if (db < -600) /* 0.75 dB steps */ | ||
312 | return (990 - db) * 2 / 15; | ||
313 | else if (db < -460) /* 0.5 dB steps */ | ||
314 | return (460 - db) / 5; | ||
315 | else /* 0.25 dB steps */ | ||
316 | return -db * 2 / 5; | ||
317 | } | ||
318 | |||
319 | #elif defined(HAVE_WM8758) | ||
320 | /* volume/balance/treble/bass interdependency */ | ||
321 | #define VOLUME_MIN -730 | ||
322 | #define VOLUME_MAX 60 | ||
323 | |||
324 | /* convert tenth of dB volume (-730..60) to master volume register value */ | ||
325 | static int tenthdb2master(int db) | ||
326 | { | ||
327 | /* +6 to -73dB 1dB steps (plus mute == 80levels) 7bits */ | ||
328 | /* 1111111 == +6dB (0x7f) */ | ||
329 | /* 1111001 == 0dB (0x79) */ | ||
330 | /* 0110000 == -73dB (0x30 */ | ||
331 | /* 0101111 == mute (0x2f) */ | ||
332 | |||
333 | if (db <= -570) { | ||
334 | return 0x0; | ||
335 | } else { | ||
336 | return((db/10)+57); | ||
296 | } | 337 | } |
297 | } | 338 | } |
298 | 339 | ||
@@ -311,7 +352,8 @@ static int tenthdb2mixer(int db) | |||
311 | 352 | ||
312 | #endif | 353 | #endif |
313 | 354 | ||
314 | #if (CONFIG_CODEC == MAS3507D) || defined HAVE_UDA1380 || defined HAVE_WM8975 | 355 | #if (CONFIG_CODEC == MAS3507D) || defined HAVE_UDA1380 || \ |
356 | defined HAVE_WM8975 || defined HAVE_WM8758 | ||
315 | /* volume/balance/treble/bass interdependency main part */ | 357 | /* volume/balance/treble/bass interdependency main part */ |
316 | #define VOLUME_RANGE (VOLUME_MAX - VOLUME_MIN) | 358 | #define VOLUME_RANGE (VOLUME_MAX - VOLUME_MIN) |
317 | 359 | ||
@@ -341,8 +383,8 @@ static void set_prescaled_volume(void) | |||
341 | mas_writereg(MAS_REG_KPRESCALE, prescale_table[prescale/10]); | 383 | mas_writereg(MAS_REG_KPRESCALE, prescale_table[prescale/10]); |
342 | #elif defined(HAVE_UDA1380) | 384 | #elif defined(HAVE_UDA1380) |
343 | uda1380_set_mixer_vol(tenthdb2mixer(-prescale), tenthdb2mixer(-prescale)); | 385 | uda1380_set_mixer_vol(tenthdb2mixer(-prescale), tenthdb2mixer(-prescale)); |
344 | #elif defined(HAVE_WM8975) | 386 | #elif defined(HAVE_WM8975) || defined(HAVE_WM8758) |
345 | wm8975_set_mixer_vol(tenthdb2mixer(-prescale), tenthdb2mixer(-prescale)); | 387 | wmcodec_set_mixer_vol(tenthdb2mixer(-prescale), tenthdb2mixer(-prescale)); |
346 | #endif | 388 | #endif |
347 | 389 | ||
348 | if (current_volume == VOLUME_MIN) | 390 | if (current_volume == VOLUME_MIN) |
@@ -367,8 +409,8 @@ static void set_prescaled_volume(void) | |||
367 | dac_volume(tenthdb2reg(l), tenthdb2reg(r), false); | 409 | dac_volume(tenthdb2reg(l), tenthdb2reg(r), false); |
368 | #elif defined(HAVE_UDA1380) | 410 | #elif defined(HAVE_UDA1380) |
369 | uda1380_set_master_vol(tenthdb2master(l), tenthdb2master(r)); | 411 | uda1380_set_master_vol(tenthdb2master(l), tenthdb2master(r)); |
370 | #elif defined(HAVE_WM8975) | 412 | #elif defined(HAVE_WM8975) || defined(HAVE_WM8758) |
371 | wm8975_set_master_vol(tenthdb2master(l), tenthdb2master(r)); | 413 | wmcodec_set_master_vol(tenthdb2master(l), tenthdb2master(r)); |
372 | #endif | 414 | #endif |
373 | } | 415 | } |
374 | #endif /* (CONFIG_CODEC == MAS3507D) || defined HAVE_UDA1380 */ | 416 | #endif /* (CONFIG_CODEC == MAS3507D) || defined HAVE_UDA1380 */ |
@@ -468,7 +510,8 @@ void sound_set_volume(int value) | |||
468 | #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) | 510 | #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) |
469 | unsigned tmp = ((unsigned)(value + 115) & 0xff) << 8; | 511 | unsigned tmp = ((unsigned)(value + 115) & 0xff) << 8; |
470 | mas_codec_writereg(0x10, tmp); | 512 | mas_codec_writereg(0x10, tmp); |
471 | #elif (CONFIG_CODEC == MAS3507D) || defined HAVE_UDA1380 || defined HAVE_WM8975 | 513 | #elif (CONFIG_CODEC == MAS3507D) || defined HAVE_UDA1380 || \ |
514 | defined HAVE_WM8975 || defined HAVE_WM8758 | ||
472 | current_volume = value * 10; /* tenth of dB */ | 515 | current_volume = value * 10; /* tenth of dB */ |
473 | set_prescaled_volume(); | 516 | set_prescaled_volume(); |
474 | #elif CONFIG_CPU == PNX0101 | 517 | #elif CONFIG_CPU == PNX0101 |
@@ -484,7 +527,8 @@ void sound_set_balance(int value) | |||
484 | #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) | 527 | #if (CONFIG_CODEC == MAS3587F) || (CONFIG_CODEC == MAS3539F) |
485 | unsigned tmp = ((unsigned)(value * 127 / 100) & 0xff) << 8; | 528 | unsigned tmp = ((unsigned)(value * 127 / 100) & 0xff) << 8; |
486 | mas_codec_writereg(0x11, tmp); | 529 | mas_codec_writereg(0x11, tmp); |
487 | #elif CONFIG_CODEC == MAS3507D || defined HAVE_UDA1380 || defined HAVE_WM8975 | 530 | #elif CONFIG_CODEC == MAS3507D || defined HAVE_UDA1380 || \ |
531 | defined HAVE_WM8975 || defined HAVE_WM8758 | ||
488 | current_balance = value * VOLUME_RANGE / 100; /* tenth of dB */ | 532 | current_balance = value * VOLUME_RANGE / 100; /* tenth of dB */ |
489 | set_prescaled_volume(); | 533 | set_prescaled_volume(); |
490 | #elif CONFIG_CPU == PNX0101 | 534 | #elif CONFIG_CPU == PNX0101 |
@@ -508,9 +552,9 @@ void sound_set_bass(int value) | |||
508 | uda1380_set_bass(value >> 1); | 552 | uda1380_set_bass(value >> 1); |
509 | current_bass = value * 10; | 553 | current_bass = value * 10; |
510 | set_prescaled_volume(); | 554 | set_prescaled_volume(); |
511 | #elif defined(HAVE_WM8975) | 555 | #elif defined HAVE_WM8975 || defined HAVE_WM8758 |
512 | current_bass = value * 10; | 556 | current_bass = value * 10; |
513 | wm8975_set_bass(value); | 557 | wmcodec_set_bass(value); |
514 | set_prescaled_volume(); | 558 | set_prescaled_volume(); |
515 | #elif CONFIG_CPU == PNX0101 | 559 | #elif CONFIG_CPU == PNX0101 |
516 | /* TODO: implement for iFP */ | 560 | /* TODO: implement for iFP */ |
@@ -533,8 +577,8 @@ void sound_set_treble(int value) | |||
533 | uda1380_set_treble(value >> 1); | 577 | uda1380_set_treble(value >> 1); |
534 | current_treble = value * 10; | 578 | current_treble = value * 10; |
535 | set_prescaled_volume(); | 579 | set_prescaled_volume(); |
536 | #elif defined(HAVE_WM8975) | 580 | #elif defined(HAVE_WM8975) || defined(HAVE_WM8758) |
537 | wm8975_set_treble(value); | 581 | wmcodec_set_treble(value); |
538 | current_treble = value * 10; | 582 | current_treble = value * 10; |
539 | set_prescaled_volume(); | 583 | set_prescaled_volume(); |
540 | #elif CONFIG_CPU == PNX0101 | 584 | #elif CONFIG_CPU == PNX0101 |