summaryrefslogtreecommitdiff
path: root/firmware/drivers/wm8731l.c
diff options
context:
space:
mode:
authorDave Chapman <dave@dchapman.com>2006-02-05 17:16:34 +0000
committerDave Chapman <dave@dchapman.com>2006-02-05 17:16:34 +0000
commit465596b1639393ef320decced442537133ab09e8 (patch)
tree79c88e59c7ab15e2dab33caf045835b5a118a2e9 /firmware/drivers/wm8731l.c
parentd16a8b8845ed496e9375c5dfac6da2011c9eb362 (diff)
downloadrockbox-465596b1639393ef320decced442537133ab09e8.tar.gz
rockbox-465596b1639393ef320decced442537133ab09e8.zip
More iPod 3G code from Seven Le Mesle
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@8582 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/drivers/wm8731l.c')
-rw-r--r--firmware/drivers/wm8731l.c268
1 files changed, 268 insertions, 0 deletions
diff --git a/firmware/drivers/wm8731l.c b/firmware/drivers/wm8731l.c
new file mode 100644
index 0000000000..d49e8f4476
--- /dev/null
+++ b/firmware/drivers/wm8731l.c
@@ -0,0 +1,268 @@
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 "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-pp5002.h"
41#include "wm8731l.h"
42#include "pcf50605.h"
43
44void wm8731l_reset(void);
45
46#define IPOD_PCM_LEVEL 0x65 /* -6dB */
47
48#define RESET (0x0f<<1)
49#define PWRMGMT1 (0x19<<1)
50#define PWRMGMT2 (0x1a<<1)
51#define AINTFCE (0x07<<1)
52#define LOUT1VOL (0x02<<1)
53#define ROUT1VOL (0x03<<1)
54#define LOUT2VOL (0x28<<1)
55#define ROUT2VOL (0x29<<1)
56
57int wm8731l_mute(int mute)
58{
59 if (mute)
60 {
61 /* Set DACMU = 1 to soft-mute the audio DACs. */
62 ipod_i2c_send(0x1a, 0xa, 0x8);
63 } else {
64 /* Set DACMU = 0 to soft-un-mute the audio DACs. */
65 ipod_i2c_send(0x1a, 0xa, 0x0);
66 }
67
68 return 0;
69}
70/** From ipodLinux **/
71static void codec_set_active(int active)
72{
73 /* set active to 0x0 or 0x1 */
74 if (active) {
75 ipod_i2c_send(0x1a, 0x12, 0x01);
76 } else {
77 ipod_i2c_send(0x1a, 0x12, 0x00);
78 }
79}
80
81/*
82 * Reset the I2S BIT.FORMAT I2S, 16bit, FIFO.FORMAT 32bit
83 */
84static void i2s_reset(void)
85{
86 /* I2S device reset */
87 outl(inl(0xcf005030) | 0x80, 0xcf005030);
88 outl(inl(0xcf005030) & ~0x80, 0xcf005030);
89
90 /* I2S controller enable */
91 outl(inl(0xc0002500) | 0x1, 0xc0002500);
92
93 /* BIT.FORMAT [11:10] = I2S (default) */
94 /* BIT.SIZE [9:8] = 24bit */
95 /* FIFO.FORMAT = 24 bit LSB */
96
97 /* reset DAC and ADC fifo */
98 outl(inl(0xc000251c) | 0x30000, 0xc000251c);
99}
100
101/*
102 * Initialise the WM8975 for playback via headphone and line out.
103 * Note, I'm using the WM8750 datasheet as its apparently close.
104 */
105int wm8731l_init(void) {
106 /* reset I2C */
107 i2c_init();
108
109 /* device reset */
110 outl(inl(0xcf005030) | 0x80, 0xcf005030);
111 outl(inl(0xcf005030) & ~0x80, 0xcf005030);
112
113 /* device enable */
114 outl(inl(0xcf005000) | 0x80, 0xcf005000);
115
116 /* GPIO D06 enable for output */
117 outl(inl(0xcf00000c) | 0x40, 0xcf00000c);
118 outl(inl(0xcf00001c) & ~0x40, 0xcf00001c);
119 /* bits 11,10 == 01 */
120 outl(inl(0xcf004040) | 0x400, 0xcf004040);
121 outl(inl(0xcf004040) & ~0x800, 0xcf004040);
122
123 outl(inl(0xcf004048) & ~0x1, 0xcf004048);
124
125 outl(inl(0xcf000004) & ~0xf, 0xcf000004);
126 outl(inl(0xcf004044) & ~0xf, 0xcf004044);
127
128 /* C03 = 0 */
129 outl(inl(0xcf000008) | 0x8, 0xcf000008);
130 outl(inl(0xcf000018) | 0x8, 0xcf000018);
131 outl(inl(0xcf000028) & ~0x8, 0xcf000028);
132
133 return 0;
134}
135
136/* Silently enable / disable audio output */
137void wm8731l_enable_output(bool enable)
138{
139 if (enable)
140 {
141 /* reset the I2S controller into known state */
142 i2s_reset();
143
144 ipod_i2c_send(0x1a, 0x1e, 0x0); /*Reset*/
145
146 codec_set_active(0x0);
147
148 /* DACSEL=1 */
149 /* BYPASS=1 */
150 ipod_i2c_send(0x1a, 0x8, 0x18);
151
152 /* set power register to POWEROFF=0 on OUTPD=0, DACPD=0 */
153 ipod_i2c_send(0x1a, 0xc, 0x67);
154
155 /* BCLKINV=0(Dont invert BCLK) MS=1(Enable Master) LRSWAP=0 LRP=0 */
156 /* IWL=00(16 bit) FORMAT=10(I2S format) */
157 ipod_i2c_send(0x1a, 0xe, 0x42);
158
159 wm8731l_set_sample_rate(WM8731L_44100HZ);
160
161 /* set the volume to -6dB */
162 ipod_i2c_send(0x1a, 0x4, IPOD_PCM_LEVEL);
163 ipod_i2c_send(0x1a, 0x6 | 0x1, IPOD_PCM_LEVEL);
164
165 /* ACTIVE=1 */
166 codec_set_active(1);
167
168 /* 5. Set DACMU = 0 to soft-un-mute the audio DACs. */
169 ipod_i2c_send(0x1a, 0xa, 0x0);
170
171 wm8731l_mute(0);
172 } else {
173 wm8731l_mute(1);
174 }
175}
176
177int wm8731l_set_master_vol(int vol_l, int vol_r)
178{
179 /* +6 to -73dB 1dB steps (plus mute == 80levels) 7bits */
180 /* 1111111 == +6dB */
181 /* 1111001 == 0dB */
182 /* 0110000 == -73dB */
183 /* 0101111 == mute (0x2f) */
184 if (vol_l == vol_r) {
185 ipod_i2c_send(0x1a, 0x4 | 0x1, vol_l);
186 } else {
187 ipod_i2c_send(0x1a, 0x4, vol_l);
188 ipod_i2c_send(0x1a, 0x6, vol_r);
189 }
190
191 return 0;
192}
193
194int wm8975_set_mixer_vol(int channel1, int channel2)
195{
196 (void)channel1;
197 (void)channel2;
198
199 return 0;
200}
201
202void wm8731l_set_bass(int value)
203{
204 (void)value;
205}
206
207void wm8731l_set_treble(int value)
208{
209 (void)value;
210}
211
212/* Nice shutdown of WM8975 codec */
213void wm8731l_close(void)
214{
215 /* set DACMU=1 DEEMPH=0 */
216 ipod_i2c_send(0x1a, 0xa, 0x8);
217
218 /* ACTIVE=0 */
219 codec_set_active(0x0);
220
221 /* line in mute left & right*/
222 ipod_i2c_send(0x1a, 0x0 | 0x1, 0x80);
223
224 /* set DACSEL=0, MUTEMIC=1 */
225 ipod_i2c_send(0x1a, 0x8, 0x2);
226
227 /* set POWEROFF=0 OUTPD=0 DACPD=1 */
228 ipod_i2c_send(0x1a, 0xc, 0x6f);
229
230 /* set POWEROFF=1 OUTPD=1 DACPD=1 */
231 ipod_i2c_send(0x1a, 0xc, 0xff);
232}
233
234/* Change the order of the noise shaper, 5th order is recommended above 32kHz */
235void wm8731l_set_nsorder(int order)
236{
237 (void)order;
238}
239
240/* */
241void wm8731l_set_sample_rate(int sampling_control)
242{
243 codec_set_active(0x0);
244 ipod_i2c_send(0x1a, 0x10, sampling_control);
245 codec_set_active(0x1);
246}
247
248void wm8731l_enable_recording(bool source_mic)
249{
250 (void)source_mic;
251}
252
253void wm8731l_disable_recording(void)
254{
255
256}
257
258void wm8731l_set_recvol(int left, int right, int type)
259{
260 (void)left;
261 (void)right;
262 (void)type;
263}
264
265void wm8731l_set_monitor(int enable)
266{
267 (void)enable;
268}