diff options
author | Michael Sevakis <jethead71@rockbox.org> | 2010-05-26 05:13:45 +0000 |
---|---|---|
committer | Michael Sevakis <jethead71@rockbox.org> | 2010-05-26 05:13:45 +0000 |
commit | 72ccb14ab1a2b38b89120330378ecec64fc8df7b (patch) | |
tree | 41b364e3a53772b6663fcf34a31c755a85c8c702 | |
parent | ab27aa1526983cf1992ce8974c61a3b10ac551dd (diff) | |
download | rockbox-72ccb14ab1a2b38b89120330378ecec64fc8df7b.tar.gz rockbox-72ccb14ab1a2b38b89120330378ecec64fc8df7b.zip |
Gigabeat S: Turn off hardware effects (tone and 3d) when doing digital loopback for FM recording otherwise the signal and levels are poorly represented in monitoring (can't just do ADC->DAC for general FM and get voice too). Some tweaking to input setup to improve gain a tiny bit. A little bit quieter startup too.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@26300 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r-- | firmware/drivers/audio/wm8978.c | 110 | ||||
-rw-r--r-- | firmware/target/arm/imx31/gigabeat-s/audio-gigabeat-s.c | 10 |
2 files changed, 87 insertions, 33 deletions
diff --git a/firmware/drivers/audio/wm8978.c b/firmware/drivers/audio/wm8978.c index 2d57ce3f10..2a19e22df3 100644 --- a/firmware/drivers/audio/wm8978.c +++ b/firmware/drivers/audio/wm8978.c | |||
@@ -129,13 +129,17 @@ static uint16_t wmc_regs[WMC_NUM_REGISTERS] = | |||
129 | 129 | ||
130 | struct | 130 | struct |
131 | { | 131 | { |
132 | int vol_l; | 132 | signed char vol_l; |
133 | int vol_r; | 133 | signed char vol_r; |
134 | int dac_l; | 134 | unsigned char dac_l; |
135 | int dac_r; | 135 | unsigned char dac_r; |
136 | bool ahw_mute; | 136 | unsigned char ahw_mute; |
137 | int prescaler; | 137 | unsigned char prescaler; /* Attenuation */ |
138 | int enhance_3d_prescaler; | 138 | unsigned char eq_on; /* Enabled */ |
139 | signed char band_gain[5]; /* Setting */ | ||
140 | unsigned char enh_3d_prescaler; /* Attenuation */ | ||
141 | unsigned char enh_3d_on; /* Enabled */ | ||
142 | unsigned char enh_3d; /* Setting */ | ||
139 | } wmc_vol = | 143 | } wmc_vol = |
140 | { | 144 | { |
141 | .vol_l = 0, | 145 | .vol_l = 0, |
@@ -144,7 +148,11 @@ struct | |||
144 | .dac_r = 0, | 148 | .dac_r = 0, |
145 | .ahw_mute = false, | 149 | .ahw_mute = false, |
146 | .prescaler = 0, | 150 | .prescaler = 0, |
147 | .enhance_3d_prescaler = 0, | 151 | .eq_on = true, |
152 | .band_gain = { 0, 0, 0, 0, 0 }, | ||
153 | .enh_3d_prescaler = 0, | ||
154 | .enh_3d_on = true, | ||
155 | .enh_3d = 0, | ||
148 | }; | 156 | }; |
149 | 157 | ||
150 | static void wmc_write(unsigned int reg, unsigned int val) | 158 | static void wmc_write(unsigned int reg, unsigned int val) |
@@ -252,14 +260,14 @@ void audiohw_preinit(void) | |||
252 | 260 | ||
253 | /* 5. Set BIASEN = 1 in register R1. */ | 261 | /* 5. Set BIASEN = 1 in register R1. */ |
254 | wmc_set(WMC_POWER_MANAGEMENT1, WMC_BIASEN); | 262 | wmc_set(WMC_POWER_MANAGEMENT1, WMC_BIASEN); |
263 | |||
264 | /* 6. Set L/ROUTEN = 1 in register R2. */ | ||
265 | wmc_write(WMC_POWER_MANAGEMENT2, WMC_LOUT1EN | WMC_ROUT1EN); | ||
255 | } | 266 | } |
256 | 267 | ||
257 | void audiohw_postinit(void) | 268 | void audiohw_postinit(void) |
258 | { | 269 | { |
259 | sleep(HZ); | 270 | sleep(5*HZ/4); |
260 | |||
261 | /* 6. Set L/ROUTEN = 1 in register R2. */ | ||
262 | wmc_write(WMC_POWER_MANAGEMENT2, WMC_LOUT1EN | WMC_ROUT1EN); | ||
263 | 271 | ||
264 | /* 7. Enable other mixers as required */ | 272 | /* 7. Enable other mixers as required */ |
265 | 273 | ||
@@ -316,6 +324,23 @@ static void get_headphone_levels(int val, int *dac_p, int *hp_p, | |||
316 | *boost_p = boost; | 324 | *boost_p = boost; |
317 | } | 325 | } |
318 | 326 | ||
327 | static void sync_prescaler(void) | ||
328 | { | ||
329 | int prescaler = 0; | ||
330 | |||
331 | /* Combine all prescaling into a single DAC attenuation */ | ||
332 | if (wmc_vol.eq_on) | ||
333 | prescaler = wmc_vol.prescaler * 2; | ||
334 | |||
335 | if (wmc_vol.enh_3d_on) | ||
336 | prescaler += wmc_vol.enh_3d_prescaler; | ||
337 | |||
338 | wmc_write_masked(WMC_LEFT_DAC_DIGITAL_VOL, wmc_vol.dac_l - prescaler, | ||
339 | WMC_DVOL); | ||
340 | wmc_write_masked(WMC_RIGHT_DAC_DIGITAL_VOL, wmc_vol.dac_r - prescaler, | ||
341 | WMC_DVOL); | ||
342 | } | ||
343 | |||
319 | void audiohw_set_headphone_vol(int vol_l, int vol_r) | 344 | void audiohw_set_headphone_vol(int vol_l, int vol_r) |
320 | { | 345 | { |
321 | int prev_l = wmc_vol.vol_l; | 346 | int prev_l = wmc_vol.vol_l; |
@@ -334,21 +359,18 @@ void audiohw_set_headphone_vol(int vol_l, int vol_r) | |||
334 | wmc_vol.dac_l = dac_l; | 359 | wmc_vol.dac_l = dac_l; |
335 | wmc_vol.dac_r = dac_r; | 360 | wmc_vol.dac_r = dac_r; |
336 | 361 | ||
337 | dac_l -= wmc_vol.prescaler + wmc_vol.enhance_3d_prescaler; | 362 | sync_prescaler(); |
338 | dac_r -= wmc_vol.prescaler + wmc_vol.enhance_3d_prescaler; | ||
339 | 363 | ||
340 | wmc_write_masked(WMC_LEFT_MIXER_CTRL, mix_l << WMC_BYPLMIXVOL_POS, | 364 | wmc_write_masked(WMC_LEFT_MIXER_CTRL, mix_l << WMC_BYPLMIXVOL_POS, |
341 | WMC_BYPLMIXVOL); | 365 | WMC_BYPLMIXVOL); |
342 | wmc_write_masked(WMC_LEFT_ADC_BOOST_CTRL, | 366 | wmc_write_masked(WMC_LEFT_ADC_BOOST_CTRL, |
343 | boost_l << WMC_L2_2BOOSTVOL_POS, WMC_L2_2BOOSTVOL); | 367 | boost_l << WMC_L2_2BOOSTVOL_POS, WMC_L2_2BOOSTVOL); |
344 | wmc_write_masked(WMC_LEFT_DAC_DIGITAL_VOL, dac_l, WMC_DVOL); | ||
345 | wmc_write_masked(WMC_LOUT1_HP_VOLUME_CTRL, hp_l, WMC_AVOL); | 368 | wmc_write_masked(WMC_LOUT1_HP_VOLUME_CTRL, hp_l, WMC_AVOL); |
346 | 369 | ||
347 | wmc_write_masked(WMC_RIGHT_MIXER_CTRL, mix_r << WMC_BYPRMIXVOL_POS, | 370 | wmc_write_masked(WMC_RIGHT_MIXER_CTRL, mix_r << WMC_BYPRMIXVOL_POS, |
348 | WMC_BYPRMIXVOL); | 371 | WMC_BYPRMIXVOL); |
349 | wmc_write_masked(WMC_RIGHT_ADC_BOOST_CTRL, | 372 | wmc_write_masked(WMC_RIGHT_ADC_BOOST_CTRL, |
350 | boost_r << WMC_R2_2BOOSTVOL_POS, WMC_R2_2BOOSTVOL); | 373 | boost_r << WMC_R2_2BOOSTVOL_POS, WMC_R2_2BOOSTVOL); |
351 | wmc_write_masked(WMC_RIGHT_DAC_DIGITAL_VOL, dac_r, WMC_DVOL); | ||
352 | wmc_write_masked(WMC_ROUT1_HP_VOLUME_CTRL, hp_r, WMC_AVOL); | 374 | wmc_write_masked(WMC_ROUT1_HP_VOLUME_CTRL, hp_r, WMC_AVOL); |
353 | 375 | ||
354 | if (vol_l > 0) | 376 | if (vol_l > 0) |
@@ -405,6 +427,11 @@ void audiohw_set_eq_band_gain(unsigned int band, int val) | |||
405 | if (band > 4) | 427 | if (band > 4) |
406 | return; | 428 | return; |
407 | 429 | ||
430 | wmc_vol.band_gain[band] = val; | ||
431 | |||
432 | if (!wmc_vol.eq_on) | ||
433 | val = 0; | ||
434 | |||
408 | wmc_write_masked(band + WMC_EQ1_LOW_SHELF, 12 - val, WMC_EQG); | 435 | wmc_write_masked(band + WMC_EQ1_LOW_SHELF, 12 - val, WMC_EQG); |
409 | } | 436 | } |
410 | 437 | ||
@@ -433,27 +460,20 @@ void audiohw_set_eq_band_width(unsigned int band, int val) | |||
433 | * gain to EQ bands. */ | 460 | * gain to EQ bands. */ |
434 | void audiohw_set_prescaler(int val) | 461 | void audiohw_set_prescaler(int val) |
435 | { | 462 | { |
436 | val *= 2; | ||
437 | wmc_vol.prescaler = val; | 463 | wmc_vol.prescaler = val; |
438 | val += wmc_vol.enhance_3d_prescaler; /* Combine with 3D attenuation */ | 464 | sync_prescaler(); |
439 | |||
440 | wmc_write_masked(WMC_LEFT_DAC_DIGITAL_VOL, wmc_vol.dac_l - val, | ||
441 | WMC_DVOL); | ||
442 | wmc_write_masked(WMC_RIGHT_DAC_DIGITAL_VOL, wmc_vol.dac_r - val, | ||
443 | WMC_DVOL); | ||
444 | } | 465 | } |
445 | 466 | ||
446 | /* Set the depth of the 3D effect */ | 467 | /* Set the depth of the 3D effect */ |
447 | void audiohw_set_depth_3d(int val) | 468 | void audiohw_set_depth_3d(int val) |
448 | { | 469 | { |
449 | int att = 10*val / 15; /* -5 dB @ full setting */ | 470 | wmc_vol.enh_3d_prescaler = 10*val / 15; /* -5 dB @ full setting */ |
450 | wmc_vol.enhance_3d_prescaler = att; | 471 | wmc_vol.enh_3d = val; |
451 | att += wmc_vol.prescaler; /* Combine with prescaler attenuation */ | ||
452 | 472 | ||
453 | wmc_write_masked(WMC_LEFT_DAC_DIGITAL_VOL, wmc_vol.dac_l - att, | 473 | if (!wmc_vol.enh_3d_on) |
454 | WMC_DVOL); | 474 | val = 0; |
455 | wmc_write_masked(WMC_RIGHT_DAC_DIGITAL_VOL, wmc_vol.dac_r - att, | 475 | |
456 | WMC_DVOL); | 476 | sync_prescaler(); |
457 | wmc_write_masked(WMC_3D_CONTROL, val, WMC_DEPTH3D); | 477 | wmc_write_masked(WMC_3D_CONTROL, val, WMC_DEPTH3D); |
458 | } | 478 | } |
459 | 479 | ||
@@ -599,6 +619,22 @@ void audiohw_set_frequency(int fsel) | |||
599 | } | 619 | } |
600 | } | 620 | } |
601 | 621 | ||
622 | void audiohw_enable_tone_controls(bool enable) | ||
623 | { | ||
624 | int i; | ||
625 | wmc_vol.eq_on = enable; | ||
626 | audiohw_set_prescaler(wmc_vol.prescaler); | ||
627 | |||
628 | for (i = 0; i < 5; i++) | ||
629 | audiohw_set_eq_band_gain(i, wmc_vol.band_gain[i]); | ||
630 | } | ||
631 | |||
632 | void audiohw_enable_depth_3d(bool enable) | ||
633 | { | ||
634 | wmc_vol.enh_3d_on = enable; | ||
635 | audiohw_set_depth_3d(wmc_vol.enh_3d); | ||
636 | } | ||
637 | |||
602 | #ifdef HAVE_RECORDING | 638 | #ifdef HAVE_RECORDING |
603 | void audiohw_set_recsrc(int source, bool recording) | 639 | void audiohw_set_recsrc(int source, bool recording) |
604 | { | 640 | { |
@@ -615,7 +651,9 @@ void audiohw_set_recsrc(int source, bool recording) | |||
615 | /* Disable IP BOOSTMIX and PGA */ | 651 | /* Disable IP BOOSTMIX and PGA */ |
616 | wmc_clear(WMC_POWER_MANAGEMENT2, WMC_INPPGAENL | WMC_INPPGAENR | | 652 | wmc_clear(WMC_POWER_MANAGEMENT2, WMC_INPPGAENL | WMC_INPPGAENR | |
617 | WMC_BOOSTENL | WMC_BOOSTENR); | 653 | WMC_BOOSTENL | WMC_BOOSTENR); |
618 | wmc_clear(WMC_INPUT_CTRL, WMC_L2_2INPPGA | WMC_R2_2INPPGA); | 654 | wmc_clear(WMC_INPUT_CTRL, WMC_L2_2INPPGA | WMC_R2_2INPPGA | |
655 | WMC_LIP2INPPGA | WMC_RIP2INPPGA | | ||
656 | WMC_LIN2INPPGA | WMC_RIN2INPPGA); | ||
619 | wmc_clear(WMC_LEFT_ADC_BOOST_CTRL, WMC_PGABOOSTL); | 657 | wmc_clear(WMC_LEFT_ADC_BOOST_CTRL, WMC_PGABOOSTL); |
620 | wmc_clear(WMC_RIGHT_ADC_BOOST_CTRL, WMC_PGABOOSTR); | 658 | wmc_clear(WMC_RIGHT_ADC_BOOST_CTRL, WMC_PGABOOSTR); |
621 | break; | 659 | break; |
@@ -637,7 +675,11 @@ void audiohw_set_recsrc(int source, bool recording) | |||
637 | wmc_set(WMC_LEFT_ADC_BOOST_CTRL, WMC_PGABOOSTL); | 675 | wmc_set(WMC_LEFT_ADC_BOOST_CTRL, WMC_PGABOOSTL); |
638 | wmc_set(WMC_RIGHT_ADC_BOOST_CTRL, WMC_PGABOOSTR); | 676 | wmc_set(WMC_RIGHT_ADC_BOOST_CTRL, WMC_PGABOOSTR); |
639 | /* Connect L/R2 inputs to PGA */ | 677 | /* Connect L/R2 inputs to PGA */ |
640 | wmc_set(WMC_INPUT_CTRL, WMC_L2_2INPPGA | WMC_R2_2INPPGA); | 678 | wmc_write_masked(WMC_INPUT_CTRL, WMC_L2_2INPPGA | WMC_R2_2INPPGA | |
679 | WMC_LIN2INPPGA | WMC_RIN2INPPGA, | ||
680 | WMC_L2_2INPPGA | WMC_R2_2INPPGA | | ||
681 | WMC_LIP2INPPGA | WMC_RIP2INPPGA | | ||
682 | WMC_LIN2INPPGA | WMC_RIN2INPPGA); | ||
641 | } | 683 | } |
642 | else | 684 | else |
643 | { | 685 | { |
@@ -647,7 +689,9 @@ void audiohw_set_recsrc(int source, bool recording) | |||
647 | wmc_write_masked(WMC_POWER_MANAGEMENT2, WMC_BOOSTENL | WMC_BOOSTENR, | 689 | wmc_write_masked(WMC_POWER_MANAGEMENT2, WMC_BOOSTENL | WMC_BOOSTENR, |
648 | WMC_BOOSTENL | WMC_BOOSTENR | WMC_INPPGAENL | | 690 | WMC_BOOSTENL | WMC_BOOSTENR | WMC_INPPGAENL | |
649 | WMC_INPPGAENR | WMC_ADCENL | WMC_ADCENR); | 691 | WMC_INPPGAENR | WMC_ADCENL | WMC_ADCENR); |
650 | wmc_clear(WMC_INPUT_CTRL, WMC_L2_2INPPGA | WMC_R2_2INPPGA); | 692 | wmc_clear(WMC_INPUT_CTRL, WMC_L2_2INPPGA | WMC_R2_2INPPGA | |
693 | WMC_LIP2INPPGA | WMC_RIP2INPPGA | | ||
694 | WMC_LIN2INPPGA | WMC_RIN2INPPGA); | ||
651 | wmc_clear(WMC_LEFT_ADC_BOOST_CTRL, WMC_PGABOOSTL); | 695 | wmc_clear(WMC_LEFT_ADC_BOOST_CTRL, WMC_PGABOOSTL); |
652 | wmc_clear(WMC_RIGHT_ADC_BOOST_CTRL, WMC_PGABOOSTR); | 696 | wmc_clear(WMC_RIGHT_ADC_BOOST_CTRL, WMC_PGABOOSTR); |
653 | /* Enable bypass to L/R mixers */ | 697 | /* Enable bypass to L/R mixers */ |
diff --git a/firmware/target/arm/imx31/gigabeat-s/audio-gigabeat-s.c b/firmware/target/arm/imx31/gigabeat-s/audio-gigabeat-s.c index f5e17a4039..9587b5683c 100644 --- a/firmware/target/arm/imx31/gigabeat-s/audio-gigabeat-s.c +++ b/firmware/target/arm/imx31/gigabeat-s/audio-gigabeat-s.c | |||
@@ -23,6 +23,9 @@ | |||
23 | #include "audiohw.h" | 23 | #include "audiohw.h" |
24 | #include "audio.h" | 24 | #include "audio.h" |
25 | 25 | ||
26 | void audiohw_enable_tone_controls(bool enable); | ||
27 | void audiohw_enable_depth_3d(bool enable); | ||
28 | |||
26 | /* Set the audio source for IIS TX */ | 29 | /* Set the audio source for IIS TX */ |
27 | void audio_set_output_source(int source) | 30 | void audio_set_output_source(int source) |
28 | { | 31 | { |
@@ -30,12 +33,19 @@ void audio_set_output_source(int source) | |||
30 | { | 33 | { |
31 | default: | 34 | default: |
32 | case AUDIO_SRC_PLAYBACK: | 35 | case AUDIO_SRC_PLAYBACK: |
36 | audiohw_enable_tone_controls(true); | ||
37 | audiohw_enable_depth_3d(true); | ||
33 | /* Receive data from PORT2 (SSI2) */ | 38 | /* Receive data from PORT2 (SSI2) */ |
34 | AUDMUX_PDCR4 = AUDMUX_PDCR_RXDSEL_PORT2; | 39 | AUDMUX_PDCR4 = AUDMUX_PDCR_RXDSEL_PORT2; |
35 | /* wmc_clear(WMC_COMPANDING_CTRL, WMC_LOOPBACK); */ | 40 | /* wmc_clear(WMC_COMPANDING_CTRL, WMC_LOOPBACK); */ |
36 | break; | 41 | break; |
37 | 42 | ||
38 | case AUDIO_SRC_FMRADIO: | 43 | case AUDIO_SRC_FMRADIO: |
44 | /* Analog path doesn't support these and digital radio playback | ||
45 | * cannot be done without mixing on the MCU if voice is to be | ||
46 | * heard. Any recording should match what is heard. */ | ||
47 | audiohw_enable_tone_controls(false); | ||
48 | audiohw_enable_depth_3d(false); | ||
39 | /* External source - receive data from self (loopback to TX) */ | 49 | /* External source - receive data from self (loopback to TX) */ |
40 | AUDMUX_PDCR4 = AUDMUX_PDCR_RXDSEL_PORT4; | 50 | AUDMUX_PDCR4 = AUDMUX_PDCR_RXDSEL_PORT4; |
41 | /* wmc_set(WMC_COMPANDING_CTRL, WMC_LOOPBACK); */ | 51 | /* wmc_set(WMC_COMPANDING_CTRL, WMC_LOOPBACK); */ |