diff options
Diffstat (limited to 'firmware')
-rw-r--r-- | firmware/drivers/audio/wm8975.c | 100 | ||||
-rw-r--r-- | firmware/export/wm8975.h | 4 |
2 files changed, 51 insertions, 53 deletions
diff --git a/firmware/drivers/audio/wm8975.c b/firmware/drivers/audio/wm8975.c index 77d567d6da..c46dab79de 100644 --- a/firmware/drivers/audio/wm8975.c +++ b/firmware/drivers/audio/wm8975.c | |||
@@ -48,7 +48,7 @@ const struct sound_settings_info audiohw_settings[] = { | |||
48 | #endif | 48 | #endif |
49 | }; | 49 | }; |
50 | 50 | ||
51 | static unsigned short wm8975_regs[] = | 51 | static unsigned short wm8975_regs[WM8975_NUM_REGISTERS] = |
52 | { | 52 | { |
53 | [LINVOL] = LINVOL_LZCEN | 23, /* 0dB */ | 53 | [LINVOL] = LINVOL_LZCEN | 23, /* 0dB */ |
54 | [RINVOL] = RINVOL_RIVU | RINVOL_RZCEN | 23, /* 0dB */ | 54 | [RINVOL] = RINVOL_RIVU | RINVOL_RZCEN | 23, /* 0dB */ |
@@ -68,8 +68,10 @@ static unsigned short wm8975_regs[] = | |||
68 | 68 | ||
69 | static void wm8975_write(int reg, unsigned val) | 69 | static void wm8975_write(int reg, unsigned val) |
70 | { | 70 | { |
71 | wm8975_regs[reg] = val; | 71 | if (WM8975_NUM_REGISTERS > reg) { |
72 | wmcodec_write(reg, val); | 72 | wm8975_regs[reg] = val; |
73 | wmcodec_write(reg, val); | ||
74 | } | ||
73 | } | 75 | } |
74 | 76 | ||
75 | static void wm8975_write_and(int reg, unsigned bits) | 77 | static void wm8975_write_and(int reg, unsigned bits) |
@@ -141,17 +143,13 @@ static void audiohw_mute(bool mute) | |||
141 | #ifdef IPOD_NANO2G | 143 | #ifdef IPOD_NANO2G |
142 | void audiohw_preinit(void) | 144 | void audiohw_preinit(void) |
143 | { | 145 | { |
144 | wmcodec_write(RESET, RESET_RESET); | 146 | wm8975_write(RESET, RESET_RESET); |
145 | |||
146 | wmcodec_write(AINTFCE, AINTFCE_MS | AINTFCE_LRP_I2S_RLO | ||
147 | | AINTFCE_IWL_16BIT | AINTFCE_FORMAT_I2S); | ||
148 | 147 | ||
149 | #ifndef IPOD_NANO2G | 148 | wm8975_write(AINTFCE, AINTFCE_MS | AINTFCE_LRP_I2S_RLO |
150 | wmcodec_write(SAMPCTRL, WM8975_44100HZ); | 149 | | AINTFCE_IWL_16BIT | AINTFCE_FORMAT_I2S); |
151 | #endif | ||
152 | 150 | ||
153 | wmcodec_write(LOUTMIX1, LOUTMIX1_LD2LO | LOUTMIX1_LI2LOVOL(5)); | 151 | wm8975_write(LOUTMIX1, LOUTMIX1_LD2LO | LOUTMIX1_LI2LOVOL(5)); |
154 | wmcodec_write(ROUTMIX2, ROUTMIX2_RD2RO | ROUTMIX2_RI2ROVOL(5)); | 152 | wm8975_write(ROUTMIX2, ROUTMIX2_RD2RO | ROUTMIX2_RI2ROVOL(5)); |
155 | 153 | ||
156 | wm8975_write(PWRMGMT1, wm8975_regs[PWRMGMT1]); | 154 | wm8975_write(PWRMGMT1, wm8975_regs[PWRMGMT1]); |
157 | wm8975_write(PWRMGMT2, wm8975_regs[PWRMGMT2]); | 155 | wm8975_write(PWRMGMT2, wm8975_regs[PWRMGMT2]); |
@@ -164,11 +162,11 @@ void audiohw_postinit(void) | |||
164 | wm8975_write(PWRMGMT1, wm8975_regs[PWRMGMT1]); | 162 | wm8975_write(PWRMGMT1, wm8975_regs[PWRMGMT1]); |
165 | audiohw_mute(false); | 163 | audiohw_mute(false); |
166 | } | 164 | } |
167 | #else | 165 | #else /* !IPOD_NANO2G */ |
168 | void audiohw_preinit(void) | 166 | void audiohw_preinit(void) |
169 | { | 167 | { |
170 | /* POWER UP SEQUENCE */ | 168 | /* POWER UP SEQUENCE */ |
171 | wmcodec_write(RESET, RESET_RESET); | 169 | wm8975_write(RESET, RESET_RESET); |
172 | 170 | ||
173 | /* 2. Enable Vmid and VREF, quick startup. */ | 171 | /* 2. Enable Vmid and VREF, quick startup. */ |
174 | wm8975_write(PWRMGMT1, wm8975_regs[PWRMGMT1]); | 172 | wm8975_write(PWRMGMT1, wm8975_regs[PWRMGMT1]); |
@@ -179,30 +177,26 @@ void audiohw_preinit(void) | |||
179 | /* 4. Enable DACs, line and headphone output buffers as required. */ | 177 | /* 4. Enable DACs, line and headphone output buffers as required. */ |
180 | wm8975_write(PWRMGMT2, wm8975_regs[PWRMGMT2]); | 178 | wm8975_write(PWRMGMT2, wm8975_regs[PWRMGMT2]); |
181 | 179 | ||
182 | wmcodec_write(AINTFCE, AINTFCE_MS | AINTFCE_LRP_I2S_RLO | 180 | wm8975_write(AINTFCE, AINTFCE_MS | AINTFCE_LRP_I2S_RLO |
183 | | AINTFCE_IWL_16BIT | AINTFCE_FORMAT_I2S); | 181 | | AINTFCE_IWL_16BIT | AINTFCE_FORMAT_I2S); |
184 | 182 | ||
185 | wm8975_write(DAPCTRL, wm8975_regs[DAPCTRL] ); | 183 | wm8975_write(DAPCTRL, wm8975_regs[DAPCTRL] ); |
186 | 184 | ||
187 | /* Still need to find out why this is neccessary */ | 185 | /* Set sample rate. */ |
188 | #ifdef IPOD_NANO2G | 186 | wm8975_write(SAMPCTRL, WM8975_44100HZ); |
189 | wmcodec_write(SAMPCTRL, 0); | ||
190 | #else | ||
191 | wmcodec_write(SAMPCTRL, WM8975_44100HZ); | ||
192 | #endif | ||
193 | 187 | ||
194 | /* set the volume to -6dB */ | 188 | /* set the volume to -6dB */ |
195 | wmcodec_write(LOUT1VOL, LOUT1VOL_LO1ZC | IPOD_PCM_LEVEL); | 189 | wm8975_write(LOUT1VOL, LOUT1VOL_LO1ZC | IPOD_PCM_LEVEL); |
196 | wmcodec_write(ROUT1VOL, ROUT1VOL_RO1VU | ROUT1VOL_RO1ZC | IPOD_PCM_LEVEL); | 190 | wm8975_write(ROUT1VOL, ROUT1VOL_RO1VU | ROUT1VOL_RO1ZC | IPOD_PCM_LEVEL); |
197 | 191 | ||
198 | wmcodec_write(LOUTMIX1, LOUTMIX1_LD2LO| LOUTMIX1_LI2LOVOL(5)); | 192 | wm8975_write(LOUTMIX1, LOUTMIX1_LD2LO| LOUTMIX1_LI2LOVOL(5)); |
199 | wmcodec_write(LOUTMIX2, LOUTMIX2_RI2LOVOL(5)); | 193 | wm8975_write(LOUTMIX2, LOUTMIX2_RI2LOVOL(5)); |
200 | 194 | ||
201 | wmcodec_write(ROUTMIX1, ROUTMIX1_LI2ROVOL(5)); | 195 | wm8975_write(ROUTMIX1, ROUTMIX1_LI2ROVOL(5)); |
202 | wmcodec_write(ROUTMIX2, ROUTMIX2_RD2RO| ROUTMIX2_RI2ROVOL(5)); | 196 | wm8975_write(ROUTMIX2, ROUTMIX2_RD2RO| ROUTMIX2_RI2ROVOL(5)); |
203 | 197 | ||
204 | wmcodec_write(MOUTMIX1, 0); | 198 | wm8975_write(MOUTMIX1, 0); |
205 | wmcodec_write(MOUTMIX2, 0); | 199 | wm8975_write(MOUTMIX2, 0); |
206 | } | 200 | } |
207 | 201 | ||
208 | void audiohw_postinit(void) | 202 | void audiohw_postinit(void) |
@@ -220,15 +214,15 @@ void audiohw_set_master_vol(int vol_l, int vol_r) | |||
220 | /* 0101111 == mute (0x2f) */ | 214 | /* 0101111 == mute (0x2f) */ |
221 | 215 | ||
222 | /* OUT1 */ | 216 | /* OUT1 */ |
223 | wmcodec_write(LOUT1VOL, LOUT1VOL_LO1ZC | vol_l); | 217 | wm8975_write(LOUT1VOL, LOUT1VOL_LO1ZC | vol_l); |
224 | wmcodec_write(ROUT1VOL, ROUT1VOL_RO1VU | ROUT1VOL_RO1ZC | vol_r); | 218 | wm8975_write(ROUT1VOL, ROUT1VOL_RO1VU | ROUT1VOL_RO1ZC | vol_r); |
225 | } | 219 | } |
226 | 220 | ||
227 | void audiohw_set_lineout_vol(int vol_l, int vol_r) | 221 | void audiohw_set_lineout_vol(int vol_l, int vol_r) |
228 | { | 222 | { |
229 | /* OUT2 */ | 223 | /* OUT2 */ |
230 | wmcodec_write(LOUT2VOL, LOUT2VOL_LO2ZC | vol_l); | 224 | wm8975_write(LOUT2VOL, LOUT2VOL_LO2ZC | vol_l); |
231 | wmcodec_write(ROUT2VOL, ROUT2VOL_RO2VU | ROUT2VOL_RO2ZC | vol_r); | 225 | wm8975_write(ROUT2VOL, ROUT2VOL_RO2VU | ROUT2VOL_RO2ZC | vol_r); |
232 | } | 226 | } |
233 | 227 | ||
234 | void audiohw_enable_lineout(bool enable) | 228 | void audiohw_enable_lineout(bool enable) |
@@ -251,7 +245,7 @@ void audiohw_set_bass(int value) | |||
251 | 245 | ||
252 | if ((value >= -6) && (value <= 9)) { | 246 | if ((value >= -6) && (value <= 9)) { |
253 | /* We use linear bass control with 200 Hz cutoff */ | 247 | /* We use linear bass control with 200 Hz cutoff */ |
254 | wmcodec_write(BASSCTRL, regvalues[value + 6] | BASSCTRL_BC); | 248 | wm8975_write(BASSCTRL, regvalues[value + 6] | BASSCTRL_BC); |
255 | } | 249 | } |
256 | } | 250 | } |
257 | 251 | ||
@@ -263,7 +257,7 @@ void audiohw_set_treble(int value) | |||
263 | 257 | ||
264 | if ((value >= -6) && (value <= 9)) { | 258 | if ((value >= -6) && (value <= 9)) { |
265 | /* We use linear treble control with 4 kHz cutoff */ | 259 | /* We use linear treble control with 4 kHz cutoff */ |
266 | wmcodec_write(TREBCTRL, regvalues[value + 6] | TREBCTRL_TC); | 260 | wm8975_write(TREBCTRL, regvalues[value + 6] | TREBCTRL_TC); |
267 | } | 261 | } |
268 | } | 262 | } |
269 | 263 | ||
@@ -273,10 +267,10 @@ void audiohw_close(void) | |||
273 | audiohw_mute(true); | 267 | audiohw_mute(true); |
274 | 268 | ||
275 | /* 2. Disable all output buffers. */ | 269 | /* 2. Disable all output buffers. */ |
276 | wmcodec_write(PWRMGMT2, 0x0); | 270 | wm8975_write(PWRMGMT2, 0x0); |
277 | 271 | ||
278 | /* 3. Switch off the power supplies. */ | 272 | /* 3. Switch off the power supplies. */ |
279 | wmcodec_write(PWRMGMT1, 0x0); | 273 | wm8975_write(PWRMGMT1, 0x0); |
280 | } | 274 | } |
281 | 275 | ||
282 | /* Note: Disable output before calling this function */ | 276 | /* Note: Disable output before calling this function */ |
@@ -296,24 +290,24 @@ void audiohw_enable_recording(bool source_mic) | |||
296 | * the DACs disabled. Also the outputs shouldn't be disabled | 290 | * the DACs disabled. Also the outputs shouldn't be disabled |
297 | * when recording from line in (dock connector) - needs testing. */ | 291 | * when recording from line in (dock connector) - needs testing. */ |
298 | wm8975_regs[PWRMGMT2] &= ~(PWRMGMT2_LOUT1 | PWRMGMT2_ROUT1 | 292 | wm8975_regs[PWRMGMT2] &= ~(PWRMGMT2_LOUT1 | PWRMGMT2_ROUT1 |
299 | | PWRMGMT2_LOUT2 | PWRMGMT2_ROUT2); | 293 | | PWRMGMT2_LOUT2 | PWRMGMT2_ROUT2); |
300 | wm8975_write(PWRMGMT2, wm8975_regs[PWRMGMT2]); | 294 | wm8975_write(PWRMGMT2, wm8975_regs[PWRMGMT2]); |
301 | 295 | ||
302 | wm8975_write_or(LINVOL, LINVOL_LINMUTE); | 296 | wm8975_write_or(LINVOL, LINVOL_LINMUTE); |
303 | wm8975_write_or(RINVOL, RINVOL_RINMUTE); | 297 | wm8975_write_or(RINVOL, RINVOL_RINMUTE); |
304 | 298 | ||
305 | wmcodec_write(ADDCTRL3, ADDCTRL3_VROI); | 299 | wm8975_write(ADDCTRL3, ADDCTRL3_VROI); |
306 | 300 | ||
307 | if (source_mic) { | 301 | if (source_mic) { |
308 | wmcodec_write(ADDCTRL1, ADDCTRL1_VSEL_LOWBIAS | ADDCTRL1_DATSEL_RADC | 302 | wm8975_write(ADDCTRL1, ADDCTRL1_VSEL_LOWBIAS | ADDCTRL1_DATSEL_RADC |
309 | | ADDCTRL1_TOEN); | 303 | | ADDCTRL1_TOEN); |
310 | wmcodec_write(ADCLPATH, 0); | 304 | wm8975_write(ADCLPATH, 0); |
311 | wmcodec_write(ADCRPATH, ADCRPATH_RINSEL_RIN2 | ADCRPATH_RMICBOOST_20dB); | 305 | wm8975_write(ADCRPATH, ADCRPATH_RINSEL_RIN2 | ADCRPATH_RMICBOOST_20dB); |
312 | } else { | 306 | } else { |
313 | wmcodec_write(ADDCTRL1, ADDCTRL1_VSEL_LOWBIAS | ADDCTRL1_DATSEL_NORMAL | 307 | wm8975_write(ADDCTRL1, ADDCTRL1_VSEL_LOWBIAS | ADDCTRL1_DATSEL_NORMAL |
314 | | ADDCTRL1_TOEN); | 308 | | ADDCTRL1_TOEN); |
315 | wmcodec_write(ADCLPATH, ADCLPATH_LINSEL_LIN1 | ADCLPATH_LMICBOOST_OFF); | 309 | wm8975_write(ADCLPATH, ADCLPATH_LINSEL_LIN1 | ADCLPATH_LMICBOOST_OFF); |
316 | wmcodec_write(ADCRPATH, ADCRPATH_RINSEL_RIN1 | ADCRPATH_RMICBOOST_OFF); | 310 | wm8975_write(ADCRPATH, ADCRPATH_RINSEL_RIN1 | ADCRPATH_RMICBOOST_OFF); |
317 | } | 311 | } |
318 | wm8975_write_and(LINVOL, ~LINVOL_LINMUTE); | 312 | wm8975_write_and(LINVOL, ~LINVOL_LINMUTE); |
319 | wm8975_write_and(RINVOL, ~RINVOL_RINMUTE); | 313 | wm8975_write_and(RINVOL, ~RINVOL_RINMUTE); |
@@ -325,7 +319,7 @@ void audiohw_disable_recording(void) | |||
325 | wm8975_write_or(LINVOL, LINVOL_LINMUTE); | 319 | wm8975_write_or(LINVOL, LINVOL_LINMUTE); |
326 | wm8975_write_or(RINVOL, RINVOL_RINMUTE); | 320 | wm8975_write_or(RINVOL, RINVOL_RINMUTE); |
327 | 321 | ||
328 | wmcodec_write(ADDCTRL3, 0); | 322 | wm8975_write(ADDCTRL3, 0); |
329 | 323 | ||
330 | wm8975_regs[PWRMGMT2] |= PWRMGMT2_DACL | PWRMGMT2_DACR | 324 | wm8975_regs[PWRMGMT2] |= PWRMGMT2_DACL | PWRMGMT2_DACR |
331 | | PWRMGMT2_LOUT1 | PWRMGMT2_ROUT1 | 325 | | PWRMGMT2_LOUT1 | PWRMGMT2_ROUT1 |
@@ -361,12 +355,12 @@ void audiohw_set_monitor(bool enable) | |||
361 | if (enable) { | 355 | if (enable) { |
362 | /* set volume to 0 dB */ | 356 | /* set volume to 0 dB */ |
363 | wm8975_regs[LOUTMIX1] &= ~LOUTMIX1_LI2LOVOL_MASK; | 357 | wm8975_regs[LOUTMIX1] &= ~LOUTMIX1_LI2LOVOL_MASK; |
364 | wm8975_regs[LOUTMIX1] |= LOUTMIX1_LI2LOVOL(2); | 358 | wm8975_regs[LOUTMIX1] |= LOUTMIX1_LI2LOVOL(2); |
365 | wm8975_regs[ROUTMIX2] &= ~ROUTMIX2_RI2ROVOL_MASK; | 359 | wm8975_regs[ROUTMIX2] &= ~ROUTMIX2_RI2ROVOL_MASK; |
366 | wm8975_regs[ROUTMIX2] |= ROUTMIX2_RI2ROVOL(2); | 360 | wm8975_regs[ROUTMIX2] |= ROUTMIX2_RI2ROVOL(2); |
367 | /* set mux to line input */ | 361 | /* set mux to line input */ |
368 | wm8975_write_and(LOUTMIX1, ~7); | 362 | wm8975_write_and(LOUTMIX1, ~LOUTMIX1_LMIXSEL_MASK); |
369 | wm8975_write_and(ROUTMIX1, ~7); | 363 | wm8975_write_and(ROUTMIX1, ~ROUTMIX1_RMIXSEL_MASK); |
370 | /* enable bypass */ | 364 | /* enable bypass */ |
371 | wm8975_write_or(LOUTMIX1, LOUTMIX1_LI2LO); | 365 | wm8975_write_or(LOUTMIX1, LOUTMIX1_LI2LO); |
372 | wm8975_write_or(ROUTMIX2, ROUTMIX2_RI2RO); | 366 | wm8975_write_or(ROUTMIX2, ROUTMIX2_RI2RO); |
diff --git a/firmware/export/wm8975.h b/firmware/export/wm8975.h index 8c3cf473d6..c9d0bd1bbe 100644 --- a/firmware/export/wm8975.h +++ b/firmware/export/wm8975.h | |||
@@ -236,6 +236,7 @@ extern void audiohw_enable_lineout(bool enable); | |||
236 | #define LOUTMIX1_LMIXSEL_LIN3 (2 << 0) | 236 | #define LOUTMIX1_LMIXSEL_LIN3 (2 << 0) |
237 | #define LOUTMIX1_LMIXSEL_LADCIN (3 << 0) | 237 | #define LOUTMIX1_LMIXSEL_LADCIN (3 << 0) |
238 | #define LOUTMIX1_LMIXSEL_DIFF (4 << 0) | 238 | #define LOUTMIX1_LMIXSEL_DIFF (4 << 0) |
239 | #define LOUTMIX1_LMIXSEL_MASK (7 << 0) | ||
239 | #define LOUTMIX1_LI2LOVOL(x) ((x & 7) << 4) | 240 | #define LOUTMIX1_LI2LOVOL(x) ((x & 7) << 4) |
240 | #define LOUTMIX1_LI2LOVOL_MASK (7 << 4) | 241 | #define LOUTMIX1_LI2LOVOL_MASK (7 << 4) |
241 | #define LOUTMIX1_LI2LO (1 << 7) | 242 | #define LOUTMIX1_LI2LO (1 << 7) |
@@ -253,6 +254,7 @@ extern void audiohw_enable_lineout(bool enable); | |||
253 | #define ROUTMIX1_RMIXSEL_RIN3 (2 << 0) | 254 | #define ROUTMIX1_RMIXSEL_RIN3 (2 << 0) |
254 | #define ROUTMIX1_RMIXSEL_RADCIN (3 << 0) | 255 | #define ROUTMIX1_RMIXSEL_RADCIN (3 << 0) |
255 | #define ROUTMIX1_RMIXSEL_DIFF (4 << 0) | 256 | #define ROUTMIX1_RMIXSEL_DIFF (4 << 0) |
257 | #define ROUTMIX1_RMIXSEL_MASK (7 << 0) | ||
256 | #define ROUTMIX1_LI2ROVOL(x) ((x & 7) << 4) | 258 | #define ROUTMIX1_LI2ROVOL(x) ((x & 7) << 4) |
257 | #define ROUTMIX1_LI2ROVOL_MASK (7 << 4) | 259 | #define ROUTMIX1_LI2ROVOL_MASK (7 << 4) |
258 | #define ROUTMIX1_LI2RO (1 << 7) | 260 | #define ROUTMIX1_LI2RO (1 << 7) |
@@ -290,6 +292,8 @@ extern void audiohw_enable_lineout(bool enable); | |||
290 | #define MOUTVOL_MASK 0x7f | 292 | #define MOUTVOL_MASK 0x7f |
291 | #define MOUTVOL_MOZC (1 << 7) | 293 | #define MOUTVOL_MOZC (1 << 7) |
292 | 294 | ||
295 | #define WM8975_NUM_REGISTERS 0x2b | ||
296 | |||
293 | 297 | ||
294 | /* SAMPCTRL values for the supported samplerates: */ | 298 | /* SAMPCTRL values for the supported samplerates: */ |
295 | #define WM8975_8000HZ 0x4d | 299 | #define WM8975_8000HZ 0x4d |