1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Driver for WM8751 audio codec
12 * Based on code from the ipodlinux project - http://ipodlinux.org/
13 * Adapted for Rockbox in December 2005
15 * Original file: linux/arch/armnommu/mach-ipod/audio.c
17 * Copyright (c) 2003-2005 Bernard Leach (leachbj@bouncycastle.org)
19 * This program is free software; you can redistribute it and/or
20 * modify it under the terms of the GNU General Public License
21 * as published by the Free Software Foundation; either version 2
22 * of the License, or (at your option) any later version.
24 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
25 * KIND, either express or implied.
27 ****************************************************************************/
35 const struct sound_settings_info audiohw_settings
[] = {
36 [SOUND_VOLUME
] = {"dB", 0, 1, -74, 6, -25},
37 [SOUND_BASS
] = {"dB", 1, 15, -60, 90, 0},
38 [SOUND_TREBLE
] = {"dB", 1, 15, -60, 90, 0},
39 [SOUND_BALANCE
] = {"%", 0, 1,-100, 100, 0},
40 [SOUND_CHANNELS
] = {"", 0, 1, 0, 5, 0},
41 [SOUND_STEREO_WIDTH
] = {"%", 0, 5, 0, 250, 100},
43 /* -17.25dB to 30.0dB in 0.75dB increments 64 steps*/
44 [SOUND_LEFT_GAIN
] = {"dB", 2, 75, -1725, 3000, 0},
45 [SOUND_RIGHT_GAIN
] = {"dB", 2, 75, -1725, 3000, 0},
46 [SOUND_MIC_GAIN
] = {"dB", 2, 75, -1725, 3000, 3000},
48 #ifdef AUDIOHW_HAVE_BASS_CUTOFF
49 [SOUND_BASS_CUTOFF
] = {"Hz", 0, 70, 130, 200, 200},
51 #ifdef AUDIOHW_HAVE_TREBLE_CUTOFF
52 [SOUND_TREBLE_CUTOFF
] = {"kHz", 0, 4, 4, 8, 4},
54 #ifdef AUDIOHW_HAVE_DEPTH_3D
55 [SOUND_DEPTH_3D
] = {"%", 0, 1, 0, 15, 0},
59 static uint16_t wmcodec_regs
[WM_NUM_REGS
] =
61 [0 ... WM_NUM_REGS
-1] = 0x200, /* set invalid data in gaps */
85 [ADDITIONAL1
] = 0x0c0,
86 [ADDITIONAL2
] = 0x000,
89 [ADDITIONAL3
] = 0x000,
106 /* global prescaler vars */
107 static int prescalertone
= 0;
108 static int prescaler3d
= 0;
110 static void wmcodec_set_reg(unsigned int reg
, unsigned int val
)
112 if (reg
>= WM_NUM_REGS
|| (wmcodec_regs
[reg
] & 0x200))
113 /* invalid register */
116 wmcodec_regs
[reg
] = val
& 0x1ff;
117 wmcodec_write(reg
, wmcodec_regs
[reg
]);
120 static void wmcodec_set_bits(unsigned int reg
, unsigned int bits
)
122 wmcodec_set_reg(reg
, wmcodec_regs
[reg
] | bits
);
125 static void wmcodec_clear_bits(unsigned int reg
, unsigned int bits
)
127 wmcodec_set_reg(reg
, wmcodec_regs
[reg
] & ~bits
);
130 static void wmcodec_set_masked(unsigned int reg
, unsigned int val
,
133 wmcodec_set_reg(reg
, (wmcodec_regs
[reg
] & ~mask
) | val
);
136 /* convert tenth of dB volume (-730..60) to master volume register value */
137 int tenthdb2master(int db
)
139 /* +6 to -73dB 1dB steps (plus mute == 80levels) 7bits */
140 /* 1111111 == +6dB (0x7f) */
141 /* 1111001 == 0dB (0x79) */
142 /* 0110000 == -73dB (0x30) */
143 /* 0101111..0000000 == mute (<= 0x2f) */
147 return (db
/ 10) + 73 + 0x30;
150 static int tone_tenthdb2hw(int value
)
152 /* -6.0db..+0db..+9.0db step 1.5db - translate -60..+0..+90 step 15
155 value
= 10 - (value
+ 60) / 15;
158 value
= 0xf; /* 0db -> off */
163 #ifdef AUDIOHW_HAVE_BASS_CUTOFF
164 void audiohw_set_bass_cutoff(int val
)
167 wmcodec_clear_bits(BASSCTRL
, BASSCTRL_BC
);
169 wmcodec_set_bits(BASSCTRL
, BASSCTRL_BC
);
174 #ifdef AUDIOHW_HAVE_TREBLE_CUTOFF
175 void audiohw_set_treble_cutoff(int val
)
178 wmcodec_clear_bits(TREBCTRL
, TREBCTRL_TC
);
180 wmcodec_set_bits(TREBCTRL
, TREBCTRL_TC
);
184 #ifdef HAVE_RECORDING
185 static int recvol2hw(int value
)
187 /* -1725 to 3000 => 0 ... 23 ... 63 */
188 return ((4 * value
) / 300) + 23;
192 int sound_val2phys(int setting
, int value
)
198 #ifdef AUDIOHW_HAVE_DEPTH_3D
200 result
= (100 * value
+ 8) / 15;
210 static void audiohw_mute(bool mute
)
212 /* Mute: Set DACMU = 1 to soft-mute the audio DACs. */
213 /* Unmute: Set DACMU = 0 to soft-un-mute the audio DACs. */
215 wmcodec_set_bits(DACCTRL
, DACCTRL_DACMU
);
217 wmcodec_clear_bits(DACCTRL
, DACCTRL_DACMU
);
220 /* Reset and power up the WM8751 */
221 void audiohw_preinit(void)
223 #if defined(MROBE_100)
224 /* controls headphone ouput */
225 GPIOL_ENABLE
|= 0x10;
226 GPIOL_OUTPUT_EN
|= 0x10;
227 GPIOL_OUTPUT_VAL
|= 0x10; /* disable */
228 #elif defined(MPIO_HD200)
229 /* control headphone output
230 * disabled on startup
232 and_l(~(1<<25), &GPIO1_OUT
);
233 or_l((1<<25), &GPIO1_ENABLE
);
234 or_l((1<<25), &GPIO1_FUNCTION
);
235 #elif defined(MPIO_HD300)
236 and_l(~(1<<5), &GPIO1_OUT
);
237 or_l((1<<5), &GPIO1_ENABLE
);
238 or_l((1<<5), &GPIO1_FUNCTION
);
242 * 1. Switch on power supplies.
243 * By default the WM8751 is in Standby Mode, the DAC is
244 * digitally muted and the Audio Interface, Line outputs
245 * and Headphone outputs are all OFF (DACMU = 1 Power
246 * Management registers 1 and 2 are all zeros).
249 wmcodec_write(RESET
, RESET_RESET
); /*Reset*/
251 /* 2. Enable Vmid and VREF. */
252 wmcodec_set_bits(PWRMGMT1
, PWRMGMT1_VREF
| PWRMGMT1_VMIDSEL_5K
);
255 wmcodec_set_bits(AINTFCE
,AINTFCE_WL_16
| AINTFCE_FORMAT_I2S
);
257 /* BCLKINV=0(Dont invert BCLK) MS=1(Enable Master) LRSWAP=0 LRP=0 */
258 /* IWL=00(16 bit) FORMAT=10(I2S format) */
259 wmcodec_set_bits(AINTFCE
, AINTFCE_MS
| AINTFCE_WL_16
|
262 /* Set default samplerate */
264 audiohw_set_frequency(HW_FREQ_DEFAULT
);
267 /* Enable DACs and audio output after a short delay */
268 void audiohw_postinit(void)
270 /* From app notes: allow Vref to stabilize to reduce clicks */
273 #ifdef AUDIOHW_HAVE_DEPTH_3D
274 wmcodec_set_bits(ENHANCE_3D
, ENHANCE_3D_MODE3D_PLAYBACK
);
277 /* 3. Enable DACs as required. */
278 wmcodec_set_bits(PWRMGMT2
, PWRMGMT2_DACL
| PWRMGMT2_DACR
);
280 /* 4. Enable line and / or headphone output buffers as required. */
281 #if defined(GIGABEAT_F)
282 /* headphones + line-out */
283 wmcodec_set_bits(PWRMGMT2
, PWRMGMT2_LOUT1
| PWRMGMT2_ROUT1
|
284 PWRMGMT2_LOUT2
| PWRMGMT2_ROUT2
);
287 wmcodec_set_bits(PWRMGMT2
, PWRMGMT2_LOUT1
| PWRMGMT2_ROUT1
);
290 /* Full -0dB on the DACS */
291 wmcodec_set_bits(LEFTGAIN
, 0xff);
292 wmcodec_set_bits(RIGHTGAIN
, RIGHTGAIN_RDVU
| 0xff);
294 /* Enable Thermal shutdown, Timeout when zero-crossing in use,
295 * set analog bias for 3.3V, monomix to DACR
297 wmcodec_set_reg(ADDITIONAL1
, ADDITIONAL1_TSDEN
| ADDITIONAL1_TOEN
|
298 ADDITIONAL1_DMONOMIX_LLRR
| ADDITIONAL1_VSEL_DEFAULT
);
301 /* Enable zero-crossing in out stage */
302 wmcodec_set_bits(LOUT1
, LOUT1_LO1ZC
);
303 wmcodec_set_bits(ROUT1
, ROUT1_RO1ZC
);
304 wmcodec_set_bits(LOUT2
, LOUT2_LO2ZC
);
305 wmcodec_set_bits(ROUT2
, ROUT2_RO2ZC
);
307 /* route signal from DAC to mixers */
308 wmcodec_set_bits(LEFTMIX1
, LEFTMIX1_LD2LO
);
309 wmcodec_set_bits(RIGHTMIX2
, RIGHTMIX2_RD2RO
);
311 #ifdef TOSHIBA_GIGABEAT_F
312 #ifdef HAVE_HARDWARE_BEEP
313 /* Single-ended mono input */
314 wmcodec_set_reg(MONOMIX1
, 0x00);
316 /* Route mono input to both outputs at 0dB */
317 wmcodec_set_reg(LEFTMIX2
, LEFTMIX2_MI2LO
| LEFTMIX2_MI2LOVOL(2));
318 wmcodec_set_reg(RIGHTMIX1
, RIGHTMIX1_MI2RO
| RIGHTMIX1_MI2ROVOL(2));
322 /* lower power consumption */
323 wmcodec_set_masked(PWRMGMT1
, PWRMGMT1_VMIDSEL_50K
,
324 PWRMGMT1_VMIDSEL_MASK
);
328 #if defined(MROBE_100)
329 /* enable headphone output */
330 GPIOL_OUTPUT_VAL
&= ~0x10;
331 GPIOL_OUTPUT_EN
|= 0x10;
332 #elif defined(MPIO_HD200)
333 /* enable headphone output */
334 or_l((1<<25), &GPIO1_OUT
);
335 #elif defined(MPIO_HD300)
336 or_l((1<<5), &GPIO1_OUT
);
340 void audiohw_set_master_vol(int vol_l
, int vol_r
)
342 /* +6 to -73dB 1dB steps (plus mute == 80levels) 7bits */
343 /* 1111111 == +6dB */
345 /* 0110000 == -73dB */
346 /* 0101111 == mute (0x2f) */
348 wmcodec_set_masked(LOUT1
, LOUT1_LOUT1VOL(vol_l
),
349 LOUT1_LOUT1VOL_MASK
);
350 wmcodec_set_masked(ROUT1
, ROUT1_RO1VU
| ROUT1_ROUT1VOL(vol_r
),
351 ROUT1_ROUT1VOL_MASK
);
354 #ifdef TOSHIBA_GIGABEAT_F
355 void audiohw_set_lineout_vol(int vol_l
, int vol_r
)
357 wmcodec_set_masked(LOUT2
, LOUT2_LOUT2VOL(vol_l
),
358 LOUT2_LOUT2VOL_MASK
);
359 wmcodec_set_masked(ROUT2
, ROUT2_RO2VU
| ROUT2_ROUT2VOL(vol_r
),
360 ROUT2_ROUT2VOL_MASK
);
364 void audiohw_set_bass(int value
)
366 wmcodec_set_masked(BASSCTRL
,
367 BASSCTRL_BASS(tone_tenthdb2hw(value
)),
371 void audiohw_set_treble(int value
)
373 wmcodec_set_masked(TREBCTRL
, TREBCTRL_TREB(tone_tenthdb2hw(value
)),
377 static void sync_prescaler(void)
380 prescaler
= prescalertone
+ prescaler3d
;
382 /* attenuate in 0.5dB steps (0dB - -127dB) */
383 wmcodec_set_reg(LEFTGAIN
, 0xff - (prescaler
& LEFTGAIN_LDACVOL
));
384 wmcodec_set_reg(RIGHTGAIN
, RIGHTGAIN_RDVU
|
385 (0xff - (prescaler
& RIGHTGAIN_RDACVOL
)));
388 void audiohw_set_prescaler(int value
)
390 prescalertone
= 3 * value
/ 15; /* value in tdB */
394 /* Nice shutdown of WM8751 codec */
395 void audiohw_close(void)
397 /* 1. Set DACMU = 1 to soft-mute the audio DACs. */
400 #if defined(MPIO_HD200)
401 /* disable headphone out */
402 and_l(~(1<<25), &GPIO1_OUT
);
403 #elif defined(MPIO_HD300)
404 and_l(~(1<<5), &GPIO1_OUT
);
407 /* 2. Disable all output buffers. */
408 wmcodec_set_reg(PWRMGMT2
, 0x0);
410 /* 3. Switch off the power supplies. */
411 wmcodec_set_reg(PWRMGMT1
, 0x0);
414 /* According to datasheet of WM8750
415 * clocking setup is needed in both slave and master mode
417 void audiohw_set_frequency(int fsel
)
420 static const unsigned char srctrl_table
[HW_NUM_FREQ
] =
422 HW_HAVE_11_([HW_FREQ_11
] = CODEC_SRCTRL_11025HZ
,)
423 HW_HAVE_22_([HW_FREQ_22
] = CODEC_SRCTRL_22050HZ
,)
424 HW_HAVE_44_([HW_FREQ_44
] = CODEC_SRCTRL_44100HZ
,)
425 HW_HAVE_88_([HW_FREQ_88
] = CODEC_SRCTRL_88200HZ
,)
428 if ((unsigned)fsel
>= HW_NUM_FREQ
)
429 fsel
= HW_FREQ_DEFAULT
;
431 wmcodec_set_reg(CLOCKING
, srctrl_table
[fsel
]);
435 #ifdef AUDIOHW_HAVE_DEPTH_3D
436 /* Set the depth of the 3D effect */
437 void audiohw_set_depth_3d(int val
)
441 wmcodec_set_bits(ENHANCE_3D
, ENHANCE_3D_3DEN
);
442 wmcodec_set_masked(ENHANCE_3D
, ENHANCE_3D_DEPTH(val
),
443 ENHANCE_3D_DEPTH_MASK
);
447 wmcodec_clear_bits(ENHANCE_3D
, ENHANCE_3D_3DEN
);
450 /* -4 dB @ full setting
451 * this gives approximately constant volume on setting change
452 * and prevents clipping (at least on my HD300)
454 prescaler3d
= 8*val
/ 15;
459 #ifdef HAVE_RECORDING
461 static void audiohw_set_ngat(int ngath
, int type
, bool enable
)
463 /* This function controls Noise gate function
464 * of the codec. This can only run in conjunction
469 wmcodec_set_reg(NGAT
, NGAT_NGG(type
) |
470 NGAT_NGTH(ngath
) | NGAT_NGAT
);
472 wmcodec_clear_bits(NGAT
, NGAT_NGAT
);
476 static void audiohw_set_alc(unsigned char level
, /* signal level at ADC */
477 bool zc
, /* zero cross detection */
478 unsigned char hold
, /* hold time */
479 unsigned char decay
, /* decay time */
480 unsigned char attack
, /* attack time */
481 bool enable
) /* hw function on/off */
485 wmcodec_set_reg(ALC1
, ALC1_ALCSEL_STEREO
| ALC1_MAXGAIN(0x07) |
487 wmcodec_set_reg(ALC2
, zc
?ALC2_ALCZC
:0 | ALC2_HLD(hold
));
488 wmcodec_set_reg(ALC3
, ALC3_DCY(decay
) | ALC3_ATK(attack
));
492 wmcodec_set_masked(ALC1
, ALC1_ALCSEL_DISABLED
, ALC1_ALCSEL_MASK
);
497 void audiohw_set_recsrc(int source
, bool recording
)
503 * if recording == false we use analog bypass from input
504 * turn off ADC, PGA to save power
505 * turn on output buffer(s)
507 * if recording == true we route input signal to PGA
508 * and monitoring picks up signal after PGA and ADC
509 * turn on ADC, PGA, DAC, output buffer(s)
514 case AUDIO_SRC_PLAYBACK
:
517 /* mute PGA, disable all audio paths but DAC and output stage*/
518 wmcodec_set_bits(LINVOL
, LINVOL_LINMUTE
); /* Mute */
519 wmcodec_set_bits(RINVOL
, RINVOL_RINMUTE
); /* Mute */
521 wmcodec_clear_bits(PWRMGMT2
, PWRMGMT2_OUT3
| PWRMGMT2_MOUT
|
522 PWRMGMT2_ROUT2
| PWRMGMT2_LOUT2
);
524 /* route DAC signal to output mixer, disable INPUT routing */
525 wmcodec_clear_bits(LEFTMIX1
, LEFTMIX1_LI2LO
);
526 wmcodec_set_bits(LEFTMIX1
, LEFTMIX1_LD2LO
);
527 wmcodec_clear_bits(RIGHTMIX2
, RIGHTMIX2_RI2RO
);
528 wmcodec_set_bits(RIGHTMIX2
, RIGHTMIX2_RD2RO
);
534 case AUDIO_SRC_FMRADIO
:
538 /* Turn on PGA and ADC */
539 wmcodec_set_bits(PWRMGMT1
, PWRMGMT1_AINL
| PWRMGMT1_AINR
|
540 PWRMGMT1_ADCL
| PWRMGMT1_ADCR
);
542 /* Setup input source for PGA as INPUT1 */
543 wmcodec_set_masked(ADCL
, ADCL_LINSEL_LINPUT1
, ADCL_LINSEL_MASK
);
544 wmcodec_set_masked(ADCR
, ADCR_RINSEL_RINPUT1
, ADCR_RINSEL_MASK
);
546 /* turn off ALC and NGAT as OF do */
548 audiohw_set_alc(0x00, false, 0x00, 0x00, 0x00, false);
549 audiohw_set_ngat(0x00, 0x00, false);
552 /* setup output digital data
553 * default is LADC -> LDATA, RADC -> RDATA
554 * so we don't touch this
557 /* skip: power up DAC and output stage as its never powered down
558 wmcodec_set_bits(PWRMGMT2, PWRMGMT2_DACL | PWRMGMT2_DACR |
559 PWRMGMT2_LOUT1 | PWRMGMT2_ROUT1);
562 /* route DAC signal to output mixer, disable INPUT routing */
563 wmcodec_clear_bits(LEFTMIX1
, LEFTMIX1_LI2LO
);
564 wmcodec_set_bits(LEFTMIX1
, LEFTMIX1_LD2LO
);
565 wmcodec_clear_bits(RIGHTMIX2
, RIGHTMIX2_RI2RO
);
566 wmcodec_set_bits(RIGHTMIX2
, RIGHTMIX2_RD2RO
);
574 /* turn off ADC, PGA */
575 wmcodec_clear_bits(PWRMGMT1
, PWRMGMT1_AINL
| PWRMGMT1_AINR
|
576 PWRMGMT1_ADCL
| PWRMGMT1_ADCR
);
578 /* setup monitor mode by routing input signal to outmix
581 wmcodec_set_masked(LEFTMIX1
, LEFTMIX1_LI2LOVOL(0x20),
582 LEFTMIX1_LI2LOVOL_MASK
);
583 wmcodec_set_bits(LEFTMIX1
, LEFTMIX1_LI2LO
|
584 LEFTMIX1_LMIXSEL_LINPUT1
|
586 wmcodec_set_masked(RIGHTMIX2
, RIGHTMIX2_RI2ROVOL(0x20),
587 RIGHTMIX2_RI2ROVOL_MASK
);
588 wmcodec_set_bits(RIGHTMIX1
, RIGHTMIX1_RMIXSEL_RINPUT1
);
589 wmcodec_set_bits(RIGHTMIX2
, RIGHTMIX2_RI2RO
|
596 #if (INPUT_SRC_CAPS & SRC_CAP_LINEIN)
597 case AUDIO_SRC_LINEIN
:
600 /* Turn on PGA, ADC */
601 wmcodec_set_bits(PWRMGMT1
, PWRMGMT1_AINL
| PWRMGMT1_AINR
|
602 PWRMGMT1_ADCL
| PWRMGMT1_ADCR
);
604 /* Setup input source for PGA as INPUT2
607 wmcodec_set_masked(ADCL
, ADCL_LINSEL_LINPUT2
, ADCL_LINSEL_MASK
);
608 wmcodec_set_masked(ADCR
, ADCR_RINSEL_RINPUT2
, ADCR_RINSEL_MASK
);
610 /* setup ALC and NGAT as OF do */
611 /* level, zc, hold, decay, attack, enable */
612 /* audiohw_set_alc(0x0b, true, 0x00, 0x03, 0x02, true); */
613 /* ngath, type, enable */
614 /* audiohw_set_ngat(0x08, 0x02, true); */
616 /* setup output digital data
617 * default is LADC -> LDATA, RADC -> RDATA
618 * so we don't touch this
621 /* route DAC signal to output mixer, disable INPUT routing */
622 wmcodec_clear_bits(LEFTMIX1
, LEFTMIX1_LI2LO
);
623 wmcodec_set_bits(LEFTMIX1
, LEFTMIX1_LD2LO
);
624 wmcodec_clear_bits(RIGHTMIX2
, RIGHTMIX2_RI2RO
);
625 wmcodec_set_bits(RIGHTMIX2
, RIGHTMIX2_RD2RO
);
627 #if !defined(MPIO_HD300)
628 /* HD300 uses the same socket for headphones and line-in */
633 #if (INPUT_SRC_CAPS & SRC_CAP_MIC)
637 /* Turn on PGA and ADC */
638 wmcodec_set_bits(PWRMGMT1
, PWRMGMT1_AINL
| PWRMGMT1_AINR
|
639 PWRMGMT1_ADCL
| PWRMGMT1_ADCR
);
641 /* Setup input source for PGA as INPUT3
644 wmcodec_set_masked(ADCL
, ADCL_LINSEL_LINPUT3
, ADCL_LINSEL_MASK
);
645 wmcodec_set_masked(ADCR
, ADCR_RINSEL_RINPUT3
, ADCR_RINSEL_MASK
);
647 /* setup ALC and NGAT as OF do */
648 /* level, zc, hold, decay, attack, enable */
649 /* audiohw_set_alc(0x0f, false, 0x00, 0x05, 0x02, true); */
650 /* ngath, type, enable */
651 /* audiohw_set_ngat(0x1f, 0x00, true); */
653 /* setup output digital data
654 * default is LADC -> LDATA, RADC -> RDATA
655 * so we don't touch this
658 /* route DAC signal to output mixer, disable INPUT routing */
659 wmcodec_clear_bits(LEFTMIX1
, LEFTMIX1_LI2LO
);
660 wmcodec_set_bits(LEFTMIX1
, LEFTMIX1_LD2LO
);
661 wmcodec_clear_bits(RIGHTMIX2
, RIGHTMIX2_RI2RO
);
662 wmcodec_set_bits(RIGHTMIX2
, RIGHTMIX2_RD2RO
);
667 } /* switch(source) */
671 void audiohw_set_recvol(int vol_l
, int vol_r
, int type
)
673 wmcodec_set_reg(LINVOL
, LINVOL_LIZC
| LINVOL_LINVOL(recvol2hw(vol_l
)));
675 if (type
== AUDIO_GAIN_MIC
)
676 wmcodec_set_reg(RINVOL
, RINVOL_RIVU
| RINVOL_RIZC
|
677 RINVOL_RINVOL(recvol2hw(vol_l
)));
679 wmcodec_set_reg(RINVOL
, RINVOL_RIVU
| RINVOL_RIZC
|
680 RINVOL_RINVOL(recvol2hw(vol_r
)));
682 #endif /* HAVE_RECORDING */
683 #endif /* HAVE_WM8750 */