summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndree Buschmann <AndreeBuschmann@t-online.de>2011-03-03 20:53:30 +0000
committerAndree Buschmann <AndreeBuschmann@t-online.de>2011-03-03 20:53:30 +0000
commit57bf8058e53af79f5d7f57f912df25d6b167e83a (patch)
treeda8dce1b02ddecc987f7a1c8d3b29c04f942bbd7
parent9946def79da50037c78f5068a4f38c22f4848c73 (diff)
downloadrockbox-57bf8058e53af79f5d7f57f912df25d6b167e83a.tar.gz
rockbox-57bf8058e53af79f5d7f57f912df25d6b167e83a.zip
Fix FS#11973. iPod nano1G needed reboot after entering record mode to have audio again.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@29513 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--firmware/drivers/audio/wm8975.c100
-rw-r--r--firmware/export/wm8975.h4
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
51static unsigned short wm8975_regs[] = 51static 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
69static void wm8975_write(int reg, unsigned val) 69static 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
75static void wm8975_write_and(int reg, unsigned bits) 77static 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
142void audiohw_preinit(void) 144void 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 */
168void audiohw_preinit(void) 166void 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
208void audiohw_postinit(void) 202void 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
227void audiohw_set_lineout_vol(int vol_l, int vol_r) 221void 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
234void audiohw_enable_lineout(bool enable) 228void 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