From ae68278c8d3c253b2417439b0176f97476f8caa4 Mon Sep 17 00:00:00 2001 From: Marcin Bukat Date: Mon, 14 Mar 2011 23:06:33 +0000 Subject: [PATCH] WM8750/51 driver: 1) Set prescaler correctly when 3d enhancement in use. 2) Implement sound_val2phys so gains in recording screen are correct. 3) Minor cleanups. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@29588 a1c6a512-1295-4272-9138-f99709370657 --- firmware/drivers/audio/wm8751.c | 123 +++++++++++++++++++------------- firmware/sound.c | 3 +- 2 files changed, 75 insertions(+), 51 deletions(-) diff --git a/firmware/drivers/audio/wm8751.c b/firmware/drivers/audio/wm8751.c index b9d41c7b32..02a04a3802 100644 --- a/firmware/drivers/audio/wm8751.c +++ b/firmware/drivers/audio/wm8751.c @@ -33,19 +33,16 @@ const struct sound_settings_info audiohw_settings[] = { [SOUND_VOLUME] = {"dB", 0, 1, -74, 6, -25}, -#ifdef USE_ADAPTIVE_BASS - [SOUND_BASS] = {"", 0, 1, 0, 15, 0}, -#else [SOUND_BASS] = {"dB", 1, 15, -60, 90, 0}, -#endif [SOUND_TREBLE] = {"dB", 1, 15, -60, 90, 0}, [SOUND_BALANCE] = {"%", 0, 1,-100, 100, 0}, [SOUND_CHANNELS] = {"", 0, 1, 0, 5, 0}, [SOUND_STEREO_WIDTH] = {"%", 0, 5, 0, 250, 100}, #ifdef HAVE_RECORDING - [SOUND_LEFT_GAIN] = {"dB", 1, 50,-970, 300, 0}, - [SOUND_RIGHT_GAIN] = {"dB", 1, 50,-970, 300, 0}, - [SOUND_MIC_GAIN] = {"dB", 1, 50,-970, 300, 0}, + /* -97.0dB to 30.0dB in 0.5dB increments */ + [SOUND_LEFT_GAIN] = {"dB", 1, 1,-194, 60, 0}, + [SOUND_RIGHT_GAIN] = {"dB", 1, 1,-194, 60, 0}, + [SOUND_MIC_GAIN] = {"dB", 1, 1,-194, 60, 60}, #endif #ifdef AUDIOHW_HAVE_BASS_CUTOFF [SOUND_BASS_CUTOFF] = {"Hz", 0, 70, 130, 200, 200}, @@ -54,12 +51,10 @@ const struct sound_settings_info audiohw_settings[] = { [SOUND_TREBLE_CUTOFF] = {"kHz",0, 4, 4, 8, 4}, #endif #ifdef AUDIOHW_HAVE_DEPTH_3D - [SOUND_DEPTH_3D] = {"", 0, 1, -1, 15, -1}, + [SOUND_DEPTH_3D] = {"%", 0, 1, 0, 15, 0}, #endif }; -static int prescaler = 0; - static uint16_t wmcodec_regs[WM_NUM_REGS] = { [0 ... WM_NUM_REGS-1] = 0x200, /* set invalid data in gaps */ @@ -107,6 +102,10 @@ static uint16_t wmcodec_regs[WM_NUM_REGS] = [MONOOUT] = 0x079 }; +/* global prescaler vars */ +static int prescalertone = 0; +static int prescaler3d = 0; + static void wmcodec_set_reg(unsigned int reg, unsigned int val) { if (reg >= WM_NUM_REGS || (wmcodec_regs[reg] & 0x200)) @@ -160,16 +159,6 @@ static int tone_tenthdb2hw(int value) return value; } -#ifdef USE_ADAPTIVE_BASS -static int adaptivebass2hw(int value) -{ - /* 0 to 15 step 1 - step -1 0 = off is a 15 in the register */ - value = 15 - value; - - return value; -} -#endif - #ifdef AUDIOHW_HAVE_BASS_CUTOFF void audiohw_set_bass_cutoff(int val) { @@ -200,14 +189,38 @@ static int recvol2hw(int value) } #endif +int sound_val2phys(int setting, int value) +{ + int result; + + switch (setting) + { +#ifdef HAVE_RECORDING + case SOUND_LEFT_GAIN: + case SOUND_RIGHT_GAIN: + case SOUND_MIC_GAIN: + result = value * 5; + break; +#endif + case SOUND_DEPTH_3D: + result = (100 * value + 8) / 15; + break; + + default: + result = value; + } + + return result; +} + static void audiohw_mute(bool mute) { /* Mute: Set DACMU = 1 to soft-mute the audio DACs. */ /* Unmute: Set DACMU = 0 to soft-un-mute the audio DACs. */ if (mute) - wmcodec_set_bits(DACCTRL,DACCTRL_DACMU); + wmcodec_set_bits(DACCTRL, DACCTRL_DACMU); else - wmcodec_clear_bits(DACCTRL,DACCTRL_DACMU); + wmcodec_clear_bits(DACCTRL, DACCTRL_DACMU); } /* Reset and power up the WM8751 */ @@ -243,7 +256,7 @@ void audiohw_preinit(void) wmcodec_set_bits(PWRMGMT1, PWRMGMT1_VREF | PWRMGMT1_VMIDSEL_5K); #ifdef CODEC_SLAVE - wmcodec_set_bits(AINTFCE,AINTFCE_WL_16|AINTFCE_FORMAT_I2S); + wmcodec_set_bits(AINTFCE,AINTFCE_WL_16 | AINTFCE_FORMAT_I2S); #else /* BCLKINV=0(Dont invert BCLK) MS=1(Enable Master) LRSWAP=0 LRP=0 */ /* IWL=00(16 bit) FORMAT=10(I2S format) */ @@ -261,25 +274,21 @@ void audiohw_postinit(void) /* From app notes: allow Vref to stabilize to reduce clicks */ sleep(HZ); - #ifdef AUDIOHW_HAVE_DEPTH_3D wmcodec_set_bits(ENHANCE_3D, ENHANCE_3D_MODE3D_PLAYBACK); #endif -#ifdef USE_ADAPTIVE_BASS - wmcodec_set_bits(BASSCTRL, BASSCTRL_BB); -#endif - /* 3. Enable DACs as required. */ wmcodec_set_bits(PWRMGMT2, PWRMGMT2_DACL | PWRMGMT2_DACR); /* 4. Enable line and / or headphone output buffers as required. */ -#if defined(MROBE_100) || defined(MPIO_HD200) - /* power-up output stage */ - wmcodec_set_bits(PWRMGMT2, PWRMGMT2_LOUT1 | PWRMGMT2_ROUT1); -#else +#if defined(GIGABEATFX) + /* headphones + line-out */ wmcodec_set_bits(PWRMGMT2, PWRMGMT2_LOUT1 | PWRMGMT2_ROUT1 | PWRMGMT2_LOUT2 | PWRMGMT2_ROUT2); +#else + /* headphones */ + wmcodec_set_bits(PWRMGMT2, PWRMGMT2_LOUT1 | PWRMGMT2_ROUT1); #endif /* Full -0dB on the DACS */ @@ -359,12 +368,8 @@ void audiohw_set_lineout_vol(int vol_l, int vol_r) void audiohw_set_bass(int value) { wmcodec_set_masked(BASSCTRL, - -#ifdef USE_ADAPTIVE_BASS - BASSCTRL_BASS(adaptivebass2hw(value)),BASSCTRL_BASS_MASK); -#else - BASSCTRL_BASS(tone_tenthdb2hw(value)),BASSCTRL_BASS_MASK); -#endif + BASSCTRL_BASS(tone_tenthdb2hw(value)), + BASSCTRL_BASS_MASK); } void audiohw_set_treble(int value) @@ -373,12 +378,21 @@ void audiohw_set_treble(int value) TREBCTRL_TREB_MASK); } +static void sync_prescaler(void) +{ + int prescaler; + prescaler = prescalertone + prescaler3d; + + /* attenuate in 0.5dB steps (0dB - -127dB) */ + wmcodec_set_reg(LEFTGAIN, 0xff - (prescaler & LEFTGAIN_LDACVOL)); + wmcodec_set_reg(RIGHTGAIN, RIGHTGAIN_RDVU | + (0xff - (prescaler & RIGHTGAIN_RDACVOL))); +} + void audiohw_set_prescaler(int value) { - prescaler = 3 * value / 15; - wmcodec_set_reg(LEFTGAIN, 0xff - (prescaler & LEFTGAIN_LDACVOL)); - wmcodec_set_reg(RIGHTGAIN, RIGHTGAIN_RDVU | - (0xff - (prescaler & RIGHTGAIN_RDACVOL))); + prescalertone = 3 * value / 15; /* value in tdB */ + sync_prescaler(); } /* Nice shutdown of WM8751 codec */ @@ -424,11 +438,9 @@ void audiohw_set_frequency(int fsel) /* Set the depth of the 3D effect */ void audiohw_set_depth_3d(int val) { - if (val >= 0) + if (val > 0) { - if ( !(wmcodec_regs[ENHANCE_3D] & ENHANCE_3D_3DEN) ) - wmcodec_set_bits(ENHANCE_3D, ENHANCE_3D_3DEN); - + wmcodec_set_bits(ENHANCE_3D, ENHANCE_3D_3DEN); wmcodec_set_masked(ENHANCE_3D, ENHANCE_3D_DEPTH(val), ENHANCE_3D_DEPTH_MASK); } @@ -436,10 +448,18 @@ void audiohw_set_depth_3d(int val) { wmcodec_clear_bits(ENHANCE_3D, ENHANCE_3D_3DEN); } + + /* -4 dB @ full setting + * this gives approximately constant volume on setting change + * and prevents clipping (at least on my HD300) + */ + prescaler3d = 8*val / 15; + sync_prescaler(); } #endif #ifdef HAVE_RECORDING +#if 0 static void audiohw_set_ngat(int ngath, int type, bool enable) { /* This function controls Noise gate function @@ -474,6 +494,7 @@ static void audiohw_set_alc(unsigned char level, /* signal level at ADC */ wmcodec_set_masked(ALC1, ALC1_ALCSEL_DISABLED, ALC1_ALCSEL_MASK); } } +#endif void audiohw_set_recsrc(int source, bool recording) { @@ -529,8 +550,10 @@ void audiohw_set_recsrc(int source, bool recording) wmcodec_set_masked(ADCR, ADCR_RINSEL_RINPUT1, ADCR_RINSEL_MASK); /* turn off ALC and NGAT as OF do */ + /* audiohw_set_alc(0x00, false, 0x00, 0x00, 0x00, false); audiohw_set_ngat(0x00, 0x00, false); + */ /* setup output digital data * default is LADC -> LDATA, RADC -> RDATA @@ -596,9 +619,9 @@ void audiohw_set_recsrc(int source, bool recording) /* setup ALC and NGAT as OF do */ /* level, zc, hold, decay, attack, enable */ - audiohw_set_alc(0x0b, true, 0x00, 0x03, 0x02, true); + /* audiohw_set_alc(0x0b, true, 0x00, 0x03, 0x02, true); */ /* ngath, type, enable */ - audiohw_set_ngat(0x08, 0x02, true); + /* audiohw_set_ngat(0x08, 0x02, true); */ /* setup output digital data * default is LADC -> LDATA, RADC -> RDATA @@ -634,9 +657,9 @@ void audiohw_set_recsrc(int source, bool recording) /* setup ALC and NGAT as OF do */ /* level, zc, hold, decay, attack, enable */ - audiohw_set_alc(0x0f, false, 0x00, 0x05, 0x02, true); + /* audiohw_set_alc(0x0f, false, 0x00, 0x05, 0x02, true); */ /* ngath, type, enable */ - audiohw_set_ngat(0x1f, 0x00, true); + /* audiohw_set_ngat(0x1f, 0x00, true); */ /* setup output digital data * default is LADC -> LDATA, RADC -> RDATA diff --git a/firmware/sound.c b/firmware/sound.c index efdcb19987..658a732a15 100644 --- a/firmware/sound.c +++ b/firmware/sound.c @@ -669,6 +669,7 @@ void sound_set(int setting, int value) && !defined(HAVE_WM8758) && !defined(HAVE_TSC2100) \ && !defined (HAVE_WM8711) && !defined (HAVE_WM8721) \ && !defined (HAVE_WM8731) && !defined (HAVE_WM8978) \ + && !defined (HAVE_WM8750) && !defined (HAVE_WM8751) \ && !defined(HAVE_AK4537)) || (CONFIG_PLATFORM & PLATFORM_HOSTED) int sound_val2phys(int setting, int value) { @@ -748,7 +749,7 @@ int sound_val2phys(int setting, int value) } return result; -#elif defined(HAVE_WM8978) +#elif defined(HAVE_WM8978) || defined(HAVE_WM8750) || defined(HAVE_WM8751) int result; switch (setting)