summaryrefslogtreecommitdiff
path: root/firmware/drivers/wm8731l.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/drivers/wm8731l.c')
-rw-r--r--firmware/drivers/wm8731l.c153
1 files changed, 21 insertions, 132 deletions
diff --git a/firmware/drivers/wm8731l.c b/firmware/drivers/wm8731l.c
index 71ccfdb4f6..be9bf14099 100644
--- a/firmware/drivers/wm8731l.c
+++ b/firmware/drivers/wm8731l.c
@@ -37,34 +37,21 @@
37#include "buffer.h" 37#include "buffer.h"
38#include "audio.h" 38#include "audio.h"
39 39
40#include "i2c-pp5002.h" 40#include "wmcodec.h"
41#include "wm8731l.h" 41#include "wm8731l.h"
42#include "pcf50605.h"
43 42
44#define IPOD_PCM_LEVEL 0x65 /* -6dB */ 43#define IPOD_PCM_LEVEL 0x65 /* -6dB */
45 44
46void wm8731_write(int reg, int data)
47{
48/* Todo: Since the ipod_i2c_* functions also work on H10 and possibly other PP
49 targets, these functions should probably be renamed */
50#if defined(IRIVER_H10) || defined(IRIVER_H10_5GB)
51 /* The H10's audio codec uses an I2C address of 0x1b */
52 ipod_i2c_send(0x1b, (reg<<1) | ((data&0x100)>>8),data&0xff);
53#else
54 /* The iPod's audio codecs use an I2C address of 0x1a */
55 ipod_i2c_send(0x1a, (reg<<1) | ((data&0x100)>>8),data&0xff);
56#endif
57}
58 45
59int wmcodec_mute(int mute) 46int wmcodec_mute(int mute)
60{ 47{
61 if (mute) 48 if (mute)
62 { 49 {
63 /* Set DACMU = 1 to soft-mute the audio DACs. */ 50 /* Set DACMU = 1 to soft-mute the audio DACs. */
64 wm8731_write(DACCTRL, 0x8); 51 wmcodec_write(DACCTRL, 0x8);
65 } else { 52 } else {
66 /* Set DACMU = 0 to soft-un-mute the audio DACs. */ 53 /* Set DACMU = 0 to soft-un-mute the audio DACs. */
67 wm8731_write(DACCTRL, 0x0); 54 wmcodec_write(DACCTRL, 0x0);
68 } 55 }
69 56
70 return 0; 57 return 0;
@@ -75,110 +62,12 @@ static void codec_set_active(int active)
75{ 62{
76 /* set active to 0x0 or 0x1 */ 63 /* set active to 0x0 or 0x1 */
77 if (active) { 64 if (active) {
78 wm8731_write(ACTIVECTRL, 0x01); 65 wmcodec_write(ACTIVECTRL, 0x01);
79 } else { 66 } else {
80 wm8731_write(ACTIVECTRL, 0x00); 67 wmcodec_write(ACTIVECTRL, 0x00);
81 } 68 }
82} 69}
83 70
84/*
85 * Reset the I2S BIT.FORMAT I2S, 16bit, FIFO.FORMAT 32bit
86 */
87static void i2s_reset(void)
88{
89#if CONFIG_CPU == PP5020
90 /* I2S soft reset */
91 outl(inl(0x70002800) | 0x80000000, 0x70002800);
92 outl(inl(0x70002800) & ~0x80000000, 0x70002800);
93
94 /* BIT.FORMAT [11:10] = I2S (default) */
95 outl(inl(0x70002800) & ~0xc00, 0x70002800);
96 /* BIT.SIZE [9:8] = 16bit (default) */
97 outl(inl(0x70002800) & ~0x300, 0x70002800);
98
99 /* FIFO.FORMAT [6:4] = 32 bit LSB */
100 /* since BIT.SIZ < FIFO.FORMAT low 16 bits will be 0 */
101 outl(inl(0x70002800) | 0x30, 0x70002800);
102
103 /* RX_ATN_LVL=1 == when 12 slots full */
104 /* TX_ATN_LVL=1 == when 12 slots empty */
105 outl(inl(0x7000280c) | 0x33, 0x7000280c);
106
107 /* Rx.CLR = 1, TX.CLR = 1 */
108 outl(inl(0x7000280c) | 0x1100, 0x7000280c);
109#elif CONFIG_CPU == PP5002
110 /* I2S device reset */
111 outl(inl(0xcf005030) | 0x80, 0xcf005030);
112 outl(inl(0xcf005030) & ~0x80, 0xcf005030);
113
114 /* I2S controller enable */
115 outl(inl(0xc0002500) | 0x1, 0xc0002500);
116
117 /* BIT.FORMAT [11:10] = I2S (default) */
118 /* BIT.SIZE [9:8] = 24bit */
119 /* FIFO.FORMAT = 24 bit LSB */
120
121 /* reset DAC and ADC fifo */
122 outl(inl(0xc000251c) | 0x30000, 0xc000251c);
123#endif
124}
125
126/*
127 * Initialise the WM8975 for playback via headphone and line out.
128 * Note, I'm using the WM8750 datasheet as its apparently close.
129 */
130int wmcodec_init(void) {
131 /* reset I2C */
132 i2c_init();
133
134#if CONFIG_CPU == PP5020
135 /* normal outputs for CDI and I2S pin groups */
136 outl(inl(0x70000020) & ~0x300, 0x70000020);
137
138 /*mini2?*/
139 outl(inl(0x70000010) & ~0x3000000, 0x70000010);
140 /*mini2?*/
141
142 /* device reset */
143 outl(inl(0x60006004) | 0x800, 0x60006004);
144 outl(inl(0x60006004) & ~0x800, 0x60006004);
145
146 /* device enable */
147 outl(inl(0x6000600C) | 0x807, 0x6000600C);
148
149 /* enable external dev clock clocks */
150 outl(inl(0x6000600c) | 0x2, 0x6000600c);
151
152 /* external dev clock to 24MHz */
153 outl(inl(0x70000018) & ~0xc, 0x70000018);
154#else
155 /* device reset */
156 outl(inl(0xcf005030) | 0x80, 0xcf005030);
157 outl(inl(0xcf005030) & ~0x80, 0xcf005030);
158
159 /* device enable */
160 outl(inl(0xcf005000) | 0x80, 0xcf005000);
161
162 /* GPIO D06 enable for output */
163 outl(inl(0xcf00000c) | 0x40, 0xcf00000c);
164 outl(inl(0xcf00001c) & ~0x40, 0xcf00001c);
165 /* bits 11,10 == 01 */
166 outl(inl(0xcf004040) | 0x400, 0xcf004040);
167 outl(inl(0xcf004040) & ~0x800, 0xcf004040);
168
169 outl(inl(0xcf004048) & ~0x1, 0xcf004048);
170
171 outl(inl(0xcf000004) & ~0xf, 0xcf000004);
172 outl(inl(0xcf004044) & ~0xf, 0xcf004044);
173
174 /* C03 = 0 */
175 outl(inl(0xcf000008) | 0x8, 0xcf000008);
176 outl(inl(0xcf000018) | 0x8, 0xcf000018);
177 outl(inl(0xcf000028) & ~0x8, 0xcf000028);
178#endif
179
180 return 0;
181}
182 71
183/* Silently enable / disable audio output */ 72/* Silently enable / disable audio output */
184void wmcodec_enable_output(bool enable) 73void wmcodec_enable_output(bool enable)
@@ -188,36 +77,36 @@ void wmcodec_enable_output(bool enable)
188 /* reset the I2S controller into known state */ 77 /* reset the I2S controller into known state */
189 i2s_reset(); 78 i2s_reset();
190 79
191 wm8731_write(RESET, 0x0); /*Reset*/ 80 wmcodec_write(RESET, 0x0); /*Reset*/
192 81
193 codec_set_active(0x0); 82 codec_set_active(0x0);
194 83
195#ifdef HAVE_WM8721 84#ifdef HAVE_WM8721
196 /* DACSEL=1 */ 85 /* DACSEL=1 */
197 wm8731_write(0x4, 0x10); 86 wmcodec_write(0x4, 0x10);
198#elif defined HAVE_WM8731 87#elif defined HAVE_WM8731
199 /* DACSEL=1, BYPASS=1 */ 88 /* DACSEL=1, BYPASS=1 */
200 wm8731_write(0x4, 0x18); 89 wmcodec_write(0x4, 0x18);
201#endif 90#endif
202 91
203 /* set power register to POWEROFF=0 on OUTPD=0, DACPD=0 */ 92 /* set power register to POWEROFF=0 on OUTPD=0, DACPD=0 */
204 wm8731_write(PWRMGMT, 0x67); 93 wmcodec_write(PWRMGMT, 0x67);
205 94
206 /* BCLKINV=0(Dont invert BCLK) MS=1(Enable Master) LRSWAP=0 LRP=0 */ 95 /* BCLKINV=0(Dont invert BCLK) MS=1(Enable Master) LRSWAP=0 LRP=0 */
207 /* IWL=00(16 bit) FORMAT=10(I2S format) */ 96 /* IWL=00(16 bit) FORMAT=10(I2S format) */
208 wm8731_write(AINTFCE, 0x42); 97 wmcodec_write(AINTFCE, 0x42);
209 98
210 wmcodec_set_sample_rate(WM8731L_44100HZ); 99 wmcodec_set_sample_rate(WM8731L_44100HZ);
211 100
212 /* set the volume to -6dB */ 101 /* set the volume to -6dB */
213 wm8731_write(LOUTVOL, IPOD_PCM_LEVEL); 102 wmcodec_write(LOUTVOL, IPOD_PCM_LEVEL);
214 wm8731_write(ROUTVOL, 0x100 | IPOD_PCM_LEVEL); 103 wmcodec_write(ROUTVOL, 0x100 | IPOD_PCM_LEVEL);
215 104
216 /* ACTIVE=1 */ 105 /* ACTIVE=1 */
217 codec_set_active(1); 106 codec_set_active(1);
218 107
219 /* 5. Set DACMU = 0 to soft-un-mute the audio DACs. */ 108 /* 5. Set DACMU = 0 to soft-un-mute the audio DACs. */
220 wm8731_write(DACCTRL, 0x0); 109 wmcodec_write(DACCTRL, 0x0);
221 110
222#if defined(IRIVER_H10) || defined(IRIVER_H10_5GB) 111#if defined(IRIVER_H10) || defined(IRIVER_H10_5GB)
223 /* We need to enable bit 4 of GPIOL for output for sound on H10 */ 112 /* We need to enable bit 4 of GPIOL for output for sound on H10 */
@@ -241,8 +130,8 @@ int wmcodec_set_master_vol(int vol_l, int vol_r)
241 /* 0110000 == -73dB */ 130 /* 0110000 == -73dB */
242 /* 0101111 == mute (0x2f) */ 131 /* 0101111 == mute (0x2f) */
243 132
244 wm8731_write(LOUTVOL, vol_l); 133 wmcodec_write(LOUTVOL, vol_l);
245 wm8731_write(ROUTVOL, vol_r); 134 wmcodec_write(ROUTVOL, vol_r);
246 135
247 return 0; 136 return 0;
248} 137}
@@ -269,22 +158,22 @@ void wmcodec_set_treble(int value)
269void wmcodec_close(void) 158void wmcodec_close(void)
270{ 159{
271 /* set DACMU=1 DEEMPH=0 */ 160 /* set DACMU=1 DEEMPH=0 */
272 wm8731_write(DACCTRL, 0x8); 161 wmcodec_write(DACCTRL, 0x8);
273 162
274 /* ACTIVE=0 */ 163 /* ACTIVE=0 */
275 codec_set_active(0x0); 164 codec_set_active(0x0);
276 165
277 /* line in mute left & right*/ 166 /* line in mute left & right*/
278 wm8731_write(LINVOL, 0x100 | 0x80); 167 wmcodec_write(LINVOL, 0x100 | 0x80);
279 168
280 /* set DACSEL=0, MUTEMIC=1 */ 169 /* set DACSEL=0, MUTEMIC=1 */
281 wm8731_write(0x4, 0x2); 170 wmcodec_write(0x4, 0x2);
282 171
283 /* set POWEROFF=0 OUTPD=0 DACPD=1 */ 172 /* set POWEROFF=0 OUTPD=0 DACPD=1 */
284 wm8731_write(PWRMGMT, 0x6f); 173 wmcodec_write(PWRMGMT, 0x6f);
285 174
286 /* set POWEROFF=1 OUTPD=1 DACPD=1 */ 175 /* set POWEROFF=1 OUTPD=1 DACPD=1 */
287 wm8731_write(PWRMGMT, 0xff); 176 wmcodec_write(PWRMGMT, 0xff);
288} 177}
289 178
290/* Change the order of the noise shaper, 5th order is recommended above 32kHz */ 179/* Change the order of the noise shaper, 5th order is recommended above 32kHz */
@@ -296,7 +185,7 @@ void wmcodec_set_nsorder(int order)
296void wmcodec_set_sample_rate(int sampling_control) 185void wmcodec_set_sample_rate(int sampling_control)
297{ 186{
298 codec_set_active(0x0); 187 codec_set_active(0x0);
299 wm8731_write(SAMPCTRL, sampling_control); 188 wmcodec_write(SAMPCTRL, sampling_control);
300 codec_set_active(0x1); 189 codec_set_active(0x1);
301} 190}
302 191