diff options
Diffstat (limited to 'firmware/drivers/wm8731l.c')
-rw-r--r-- | firmware/drivers/wm8731l.c | 153 |
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 | ||
46 | void 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 | ||
59 | int wmcodec_mute(int mute) | 46 | int 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 | */ | ||
87 | static 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 | */ | ||
130 | int 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 */ |
184 | void wmcodec_enable_output(bool enable) | 73 | void 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) | |||
269 | void wmcodec_close(void) | 158 | void 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) | |||
296 | void wmcodec_set_sample_rate(int sampling_control) | 185 | void 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 | ||