summaryrefslogtreecommitdiff
path: root/firmware/drivers/wm8975.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/drivers/wm8975.c')
-rw-r--r--firmware/drivers/wm8975.c122
1 files changed, 29 insertions, 93 deletions
diff --git a/firmware/drivers/wm8975.c b/firmware/drivers/wm8975.c
index 64a123b883..a961356222 100644
--- a/firmware/drivers/wm8975.c
+++ b/firmware/drivers/wm8975.c
@@ -37,77 +37,13 @@
37#include "buffer.h" 37#include "buffer.h"
38#include "audio.h" 38#include "audio.h"
39 39
40#include "i2c-pp5020.h" 40#include "wmcodec.h"
41#include "wm8975.h" 41#include "wm8975.h"
42#include "pcf50605.h"
43 42
44void wmcodec_reset(void); 43void wmcodec_reset(void);
45 44
46#define IPOD_PCM_LEVEL 0x65 /* -6dB */ 45#define IPOD_PCM_LEVEL 0x65 /* -6dB */
47 46
48/*
49 * Reset the I2S BIT.FORMAT I2S, 16bit, FIFO.FORMAT 32bit
50 */
51static void i2s_reset(void)
52{
53 /* PP502x */
54
55 /* I2S soft reset */
56 outl(inl(0x70002800) | 0x80000000, 0x70002800);
57 outl(inl(0x70002800) & ~0x80000000, 0x70002800);
58
59 /* BIT.FORMAT [11:10] = I2S (default) */
60 outl(inl(0x70002800) & ~0xc00, 0x70002800);
61 /* BIT.SIZE [9:8] = 16bit (default) */
62 outl(inl(0x70002800) & ~0x300, 0x70002800);
63
64 /* FIFO.FORMAT [6:4] = 32 bit LSB */
65 /* since BIT.SIZ < FIFO.FORMAT low 16 bits will be 0 */
66 outl(inl(0x70002800) | 0x30, 0x70002800);
67
68 /* RX_ATN_LVL=1 == when 12 slots full */
69 /* TX_ATN_LVL=1 == when 12 slots empty */
70 outl(inl(0x7000280c) | 0x33, 0x7000280c);
71
72 /* Rx.CLR = 1, TX.CLR = 1 */
73 outl(inl(0x7000280c) | 0x1100, 0x7000280c);
74}
75
76void wm8975_write(int reg, int data)
77{
78 ipod_i2c_send(0x1a, (reg<<1) | ((data&0x100)>>8),data&0xff);
79}
80
81/*
82 * Initialise the WM8975 for playback via headphone and line out.
83 * Note, I'm using the WM8750 datasheet as its apparently close.
84 */
85int wmcodec_init(void) {
86 /* reset I2C */
87 i2c_init();
88
89 /* normal outputs for CDI and I2S pin groups */
90 outl(inl(0x70000020) & ~0x300, 0x70000020);
91
92 /*mini2?*/
93 outl(inl(0x70000010) & ~0x3000000, 0x70000010);
94 /*mini2?*/
95
96 /* device reset */
97 outl(inl(0x60006004) | 0x800, 0x60006004);
98 outl(inl(0x60006004) & ~0x800, 0x60006004);
99
100 /* device enable */
101 outl(inl(0x6000600C) | 0x807, 0x6000600C);
102
103 /* enable external dev clock clocks */
104 outl(inl(0x6000600c) | 0x2, 0x6000600c);
105
106 /* external dev clock to 24MHz */
107 outl(inl(0x70000018) & ~0xc, 0x70000018);
108
109 return 0;
110}
111 47
112/* Silently enable / disable audio output */ 48/* Silently enable / disable audio output */
113void wmcodec_enable_output(bool enable) 49void wmcodec_enable_output(bool enable)
@@ -124,39 +60,39 @@ void wmcodec_enable_output(bool enable)
124 * and Headphone outputs are all OFF (DACMU = 1 Power 60 * and Headphone outputs are all OFF (DACMU = 1 Power
125 * Management registers 1 and 2 are all zeros). 61 * Management registers 1 and 2 are all zeros).
126 */ 62 */
127 wm8975_write(RESET, 0x1ff); /*Reset*/ 63 wmcodec_write(RESET, 0x1ff); /*Reset*/
128 wm8975_write(RESET, 0x0); 64 wmcodec_write(RESET, 0x0);
129 65
130 /* 2. Enable Vmid and VREF. */ 66 /* 2. Enable Vmid and VREF. */
131 wm8975_write(PWRMGMT1, 0xc0); /*Pwr Mgmt(1)*/ 67 wmcodec_write(PWRMGMT1, 0xc0); /*Pwr Mgmt(1)*/
132 68
133 /* 3. Enable DACs as required. */ 69 /* 3. Enable DACs as required. */
134 wm8975_write(PWRMGMT2, 0x180); /*Pwr Mgmt(2)*/ 70 wmcodec_write(PWRMGMT2, 0x180); /*Pwr Mgmt(2)*/
135 71
136 /* 4. Enable line and / or headphone output buffers as required. */ 72 /* 4. Enable line and / or headphone output buffers as required. */
137 wm8975_write(PWRMGMT2, 0x1f8); /*Pwr Mgmt(2)*/ 73 wmcodec_write(PWRMGMT2, 0x1f8); /*Pwr Mgmt(2)*/
138 74
139 /* BCLKINV=0(Dont invert BCLK) MS=1(Enable Master) LRSWAP=0 LRP=0 */ 75 /* BCLKINV=0(Dont invert BCLK) MS=1(Enable Master) LRSWAP=0 LRP=0 */
140 /* IWL=00(16 bit) FORMAT=10(I2S format) */ 76 /* IWL=00(16 bit) FORMAT=10(I2S format) */
141 wm8975_write(AINTFCE, 0x42); 77 wmcodec_write(AINTFCE, 0x42);
142 78
143 /* The iPod can handle multiple frequencies, but fix at 44.1KHz for now */ 79 /* The iPod can handle multiple frequencies, but fix at 44.1KHz for now */
144 wmcodec_set_sample_rate(WM8975_44100HZ); 80 wmcodec_set_sample_rate(WM8975_44100HZ);
145 81
146 /* set the volume to -6dB */ 82 /* set the volume to -6dB */
147 wm8975_write(LOUT1VOL, IPOD_PCM_LEVEL); 83 wmcodec_write(LOUT1VOL, IPOD_PCM_LEVEL);
148 wm8975_write(ROUT1VOL,0x100 | IPOD_PCM_LEVEL); 84 wmcodec_write(ROUT1VOL,0x100 | IPOD_PCM_LEVEL);
149 wm8975_write(LOUT1VOL, IPOD_PCM_LEVEL); 85 wmcodec_write(LOUT1VOL, IPOD_PCM_LEVEL);
150 wm8975_write(ROUT1VOL,0x100 | IPOD_PCM_LEVEL); 86 wmcodec_write(ROUT1VOL,0x100 | IPOD_PCM_LEVEL);
151 87
152 wm8975_write(LOUTMIX1, 0x150); /* Left out Mix(def) */ 88 wmcodec_write(LOUTMIX1, 0x150); /* Left out Mix(def) */
153 wm8975_write(LOUTMIX2, 0x50); 89 wmcodec_write(LOUTMIX2, 0x50);
154 90
155 wm8975_write(ROUTMIX1, 0x50); /* Right out Mix(def) */ 91 wmcodec_write(ROUTMIX1, 0x50); /* Right out Mix(def) */
156 wm8975_write(ROUTMIX2, 0x150); 92 wmcodec_write(ROUTMIX2, 0x150);
157 93
158 wm8975_write(MOUTMIX1, 0x0); /* Mono out Mix */ 94 wmcodec_write(MOUTMIX1, 0x0); /* Mono out Mix */
159 wm8975_write(MOUTMIX2, 0x0); 95 wmcodec_write(MOUTMIX2, 0x0);
160 96
161 wmcodec_mute(0); 97 wmcodec_mute(0);
162 } else { 98 } else {
@@ -173,8 +109,8 @@ int wmcodec_set_master_vol(int vol_l, int vol_r)
173 /* 0101111 == mute (0x2f) */ 109 /* 0101111 == mute (0x2f) */
174 110
175 /* OUT1 */ 111 /* OUT1 */
176 wm8975_write(LOUT1VOL, vol_l); 112 wmcodec_write(LOUT1VOL, vol_l);
177 wm8975_write(ROUT1VOL, 0x100 | vol_r); 113 wmcodec_write(ROUT1VOL, 0x100 | vol_r);
178 114
179 return 0; 115 return 0;
180} 116}
@@ -182,8 +118,8 @@ int wmcodec_set_master_vol(int vol_l, int vol_r)
182int wmcodec_set_lineout_vol(int vol_l, int vol_r) 118int wmcodec_set_lineout_vol(int vol_l, int vol_r)
183{ 119{
184 /* OUT2 */ 120 /* OUT2 */
185 wm8975_write(LOUT2VOL, vol_l); 121 wmcodec_write(LOUT2VOL, vol_l);
186 wm8975_write(ROUT2VOL, 0x100 | vol_r); 122 wmcodec_write(ROUT2VOL, 0x100 | vol_r);
187 123
188 return 0; 124 return 0;
189} 125}
@@ -203,7 +139,7 @@ void wmcodec_set_bass(int value)
203 139
204 if ((value >= -6) && (value <= 9)) { 140 if ((value >= -6) && (value <= 9)) {
205 /* We use linear bass control with 130Hz cutoff */ 141 /* We use linear bass control with 130Hz cutoff */
206 wm8975_write(BASSCTRL, regvalues[value+6]); 142 wmcodec_write(BASSCTRL, regvalues[value+6]);
207 } 143 }
208} 144}
209 145
@@ -213,7 +149,7 @@ void wmcodec_set_treble(int value)
213 149
214 if ((value >= -6) && (value <= 9)) { 150 if ((value >= -6) && (value <= 9)) {
215 /* We use a 8Khz cutoff */ 151 /* We use a 8Khz cutoff */
216 wm8975_write(TREBCTRL, regvalues[value+6]); 152 wmcodec_write(TREBCTRL, regvalues[value+6]);
217 } 153 }
218} 154}
219 155
@@ -222,10 +158,10 @@ int wmcodec_mute(int mute)
222 if (mute) 158 if (mute)
223 { 159 {
224 /* Set DACMU = 1 to soft-mute the audio DACs. */ 160 /* Set DACMU = 1 to soft-mute the audio DACs. */
225 wm8975_write(DACCTRL, 0x8); 161 wmcodec_write(DACCTRL, 0x8);
226 } else { 162 } else {
227 /* Set DACMU = 0 to soft-un-mute the audio DACs. */ 163 /* Set DACMU = 0 to soft-un-mute the audio DACs. */
228 wm8975_write(DACCTRL, 0x0); 164 wmcodec_write(DACCTRL, 0x0);
229 } 165 }
230 166
231 return 0; 167 return 0;
@@ -235,13 +171,13 @@ int wmcodec_mute(int mute)
235void wmcodec_close(void) 171void wmcodec_close(void)
236{ 172{
237 /* 1. Set DACMU = 1 to soft-mute the audio DACs. */ 173 /* 1. Set DACMU = 1 to soft-mute the audio DACs. */
238 wm8975_write(DACCTRL, 0x8); 174 wmcodec_write(DACCTRL, 0x8);
239 175
240 /* 2. Disable all output buffers. */ 176 /* 2. Disable all output buffers. */
241 wm8975_write(PWRMGMT2, 0x0); /*Pwr Mgmt(2)*/ 177 wmcodec_write(PWRMGMT2, 0x0); /*Pwr Mgmt(2)*/
242 178
243 /* 3. Switch off the power supplies. */ 179 /* 3. Switch off the power supplies. */
244 wm8975_write(PWRMGMT1, 0x0); /*Pwr Mgmt(1)*/ 180 wmcodec_write(PWRMGMT1, 0x0); /*Pwr Mgmt(1)*/
245} 181}
246 182
247/* Change the order of the noise shaper, 5th order is recommended above 32kHz */ 183/* Change the order of the noise shaper, 5th order is recommended above 32kHz */
@@ -253,7 +189,7 @@ void wmcodec_set_nsorder(int order)
253/* Note: Disable output before calling this function */ 189/* Note: Disable output before calling this function */
254void wmcodec_set_sample_rate(int sampling_control) { 190void wmcodec_set_sample_rate(int sampling_control) {
255 191
256 wm8975_write(0x08, sampling_control); 192 wmcodec_write(0x08, sampling_control);
257 193
258} 194}
259 195