mirror of
https://github.com/Rockbox/rockbox.git
synced 2025-10-14 02:27:39 -04:00
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
This commit is contained in:
parent
9c41252d77
commit
ae68278c8d
2 changed files with 75 additions and 51 deletions
|
@ -33,19 +33,16 @@
|
||||||
|
|
||||||
const struct sound_settings_info audiohw_settings[] = {
|
const struct sound_settings_info audiohw_settings[] = {
|
||||||
[SOUND_VOLUME] = {"dB", 0, 1, -74, 6, -25},
|
[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},
|
[SOUND_BASS] = {"dB", 1, 15, -60, 90, 0},
|
||||||
#endif
|
|
||||||
[SOUND_TREBLE] = {"dB", 1, 15, -60, 90, 0},
|
[SOUND_TREBLE] = {"dB", 1, 15, -60, 90, 0},
|
||||||
[SOUND_BALANCE] = {"%", 0, 1,-100, 100, 0},
|
[SOUND_BALANCE] = {"%", 0, 1,-100, 100, 0},
|
||||||
[SOUND_CHANNELS] = {"", 0, 1, 0, 5, 0},
|
[SOUND_CHANNELS] = {"", 0, 1, 0, 5, 0},
|
||||||
[SOUND_STEREO_WIDTH] = {"%", 0, 5, 0, 250, 100},
|
[SOUND_STEREO_WIDTH] = {"%", 0, 5, 0, 250, 100},
|
||||||
#ifdef HAVE_RECORDING
|
#ifdef HAVE_RECORDING
|
||||||
[SOUND_LEFT_GAIN] = {"dB", 1, 50,-970, 300, 0},
|
/* -97.0dB to 30.0dB in 0.5dB increments */
|
||||||
[SOUND_RIGHT_GAIN] = {"dB", 1, 50,-970, 300, 0},
|
[SOUND_LEFT_GAIN] = {"dB", 1, 1,-194, 60, 0},
|
||||||
[SOUND_MIC_GAIN] = {"dB", 1, 50,-970, 300, 0},
|
[SOUND_RIGHT_GAIN] = {"dB", 1, 1,-194, 60, 0},
|
||||||
|
[SOUND_MIC_GAIN] = {"dB", 1, 1,-194, 60, 60},
|
||||||
#endif
|
#endif
|
||||||
#ifdef AUDIOHW_HAVE_BASS_CUTOFF
|
#ifdef AUDIOHW_HAVE_BASS_CUTOFF
|
||||||
[SOUND_BASS_CUTOFF] = {"Hz", 0, 70, 130, 200, 200},
|
[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},
|
[SOUND_TREBLE_CUTOFF] = {"kHz",0, 4, 4, 8, 4},
|
||||||
#endif
|
#endif
|
||||||
#ifdef AUDIOHW_HAVE_DEPTH_3D
|
#ifdef AUDIOHW_HAVE_DEPTH_3D
|
||||||
[SOUND_DEPTH_3D] = {"", 0, 1, -1, 15, -1},
|
[SOUND_DEPTH_3D] = {"%", 0, 1, 0, 15, 0},
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
static int prescaler = 0;
|
|
||||||
|
|
||||||
static uint16_t wmcodec_regs[WM_NUM_REGS] =
|
static uint16_t wmcodec_regs[WM_NUM_REGS] =
|
||||||
{
|
{
|
||||||
[0 ... WM_NUM_REGS-1] = 0x200, /* set invalid data in gaps */
|
[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
|
[MONOOUT] = 0x079
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* global prescaler vars */
|
||||||
|
static int prescalertone = 0;
|
||||||
|
static int prescaler3d = 0;
|
||||||
|
|
||||||
static void wmcodec_set_reg(unsigned int reg, unsigned int val)
|
static void wmcodec_set_reg(unsigned int reg, unsigned int val)
|
||||||
{
|
{
|
||||||
if (reg >= WM_NUM_REGS || (wmcodec_regs[reg] & 0x200))
|
if (reg >= WM_NUM_REGS || (wmcodec_regs[reg] & 0x200))
|
||||||
|
@ -160,16 +159,6 @@ static int tone_tenthdb2hw(int value)
|
||||||
return 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
|
#ifdef AUDIOHW_HAVE_BASS_CUTOFF
|
||||||
void audiohw_set_bass_cutoff(int val)
|
void audiohw_set_bass_cutoff(int val)
|
||||||
{
|
{
|
||||||
|
@ -200,6 +189,30 @@ static int recvol2hw(int value)
|
||||||
}
|
}
|
||||||
#endif
|
#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)
|
static void audiohw_mute(bool mute)
|
||||||
{
|
{
|
||||||
/* Mute: Set DACMU = 1 to soft-mute the audio DACs. */
|
/* Mute: Set DACMU = 1 to soft-mute the audio DACs. */
|
||||||
|
@ -261,25 +274,21 @@ void audiohw_postinit(void)
|
||||||
/* From app notes: allow Vref to stabilize to reduce clicks */
|
/* From app notes: allow Vref to stabilize to reduce clicks */
|
||||||
sleep(HZ);
|
sleep(HZ);
|
||||||
|
|
||||||
|
|
||||||
#ifdef AUDIOHW_HAVE_DEPTH_3D
|
#ifdef AUDIOHW_HAVE_DEPTH_3D
|
||||||
wmcodec_set_bits(ENHANCE_3D, ENHANCE_3D_MODE3D_PLAYBACK);
|
wmcodec_set_bits(ENHANCE_3D, ENHANCE_3D_MODE3D_PLAYBACK);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_ADAPTIVE_BASS
|
|
||||||
wmcodec_set_bits(BASSCTRL, BASSCTRL_BB);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* 3. Enable DACs as required. */
|
/* 3. Enable DACs as required. */
|
||||||
wmcodec_set_bits(PWRMGMT2, PWRMGMT2_DACL | PWRMGMT2_DACR);
|
wmcodec_set_bits(PWRMGMT2, PWRMGMT2_DACL | PWRMGMT2_DACR);
|
||||||
|
|
||||||
/* 4. Enable line and / or headphone output buffers as required. */
|
/* 4. Enable line and / or headphone output buffers as required. */
|
||||||
#if defined(MROBE_100) || defined(MPIO_HD200)
|
#if defined(GIGABEATFX)
|
||||||
/* power-up output stage */
|
/* headphones + line-out */
|
||||||
wmcodec_set_bits(PWRMGMT2, PWRMGMT2_LOUT1 | PWRMGMT2_ROUT1);
|
|
||||||
#else
|
|
||||||
wmcodec_set_bits(PWRMGMT2, PWRMGMT2_LOUT1 | PWRMGMT2_ROUT1 |
|
wmcodec_set_bits(PWRMGMT2, PWRMGMT2_LOUT1 | PWRMGMT2_ROUT1 |
|
||||||
PWRMGMT2_LOUT2 | PWRMGMT2_ROUT2);
|
PWRMGMT2_LOUT2 | PWRMGMT2_ROUT2);
|
||||||
|
#else
|
||||||
|
/* headphones */
|
||||||
|
wmcodec_set_bits(PWRMGMT2, PWRMGMT2_LOUT1 | PWRMGMT2_ROUT1);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Full -0dB on the DACS */
|
/* 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)
|
void audiohw_set_bass(int value)
|
||||||
{
|
{
|
||||||
wmcodec_set_masked(BASSCTRL,
|
wmcodec_set_masked(BASSCTRL,
|
||||||
|
BASSCTRL_BASS(tone_tenthdb2hw(value)),
|
||||||
#ifdef USE_ADAPTIVE_BASS
|
BASSCTRL_BASS_MASK);
|
||||||
BASSCTRL_BASS(adaptivebass2hw(value)),BASSCTRL_BASS_MASK);
|
|
||||||
#else
|
|
||||||
BASSCTRL_BASS(tone_tenthdb2hw(value)),BASSCTRL_BASS_MASK);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void audiohw_set_treble(int value)
|
void audiohw_set_treble(int value)
|
||||||
|
@ -373,14 +378,23 @@ void audiohw_set_treble(int value)
|
||||||
TREBCTRL_TREB_MASK);
|
TREBCTRL_TREB_MASK);
|
||||||
}
|
}
|
||||||
|
|
||||||
void audiohw_set_prescaler(int value)
|
static void sync_prescaler(void)
|
||||||
{
|
{
|
||||||
prescaler = 3 * value / 15;
|
int prescaler;
|
||||||
|
prescaler = prescalertone + prescaler3d;
|
||||||
|
|
||||||
|
/* attenuate in 0.5dB steps (0dB - -127dB) */
|
||||||
wmcodec_set_reg(LEFTGAIN, 0xff - (prescaler & LEFTGAIN_LDACVOL));
|
wmcodec_set_reg(LEFTGAIN, 0xff - (prescaler & LEFTGAIN_LDACVOL));
|
||||||
wmcodec_set_reg(RIGHTGAIN, RIGHTGAIN_RDVU |
|
wmcodec_set_reg(RIGHTGAIN, RIGHTGAIN_RDVU |
|
||||||
(0xff - (prescaler & RIGHTGAIN_RDACVOL)));
|
(0xff - (prescaler & RIGHTGAIN_RDACVOL)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void audiohw_set_prescaler(int value)
|
||||||
|
{
|
||||||
|
prescalertone = 3 * value / 15; /* value in tdB */
|
||||||
|
sync_prescaler();
|
||||||
|
}
|
||||||
|
|
||||||
/* Nice shutdown of WM8751 codec */
|
/* Nice shutdown of WM8751 codec */
|
||||||
void audiohw_close(void)
|
void audiohw_close(void)
|
||||||
{
|
{
|
||||||
|
@ -424,11 +438,9 @@ void audiohw_set_frequency(int fsel)
|
||||||
/* Set the depth of the 3D effect */
|
/* Set the depth of the 3D effect */
|
||||||
void audiohw_set_depth_3d(int val)
|
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),
|
wmcodec_set_masked(ENHANCE_3D, ENHANCE_3D_DEPTH(val),
|
||||||
ENHANCE_3D_DEPTH_MASK);
|
ENHANCE_3D_DEPTH_MASK);
|
||||||
}
|
}
|
||||||
|
@ -436,10 +448,18 @@ void audiohw_set_depth_3d(int val)
|
||||||
{
|
{
|
||||||
wmcodec_clear_bits(ENHANCE_3D, ENHANCE_3D_3DEN);
|
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
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_RECORDING
|
#ifdef HAVE_RECORDING
|
||||||
|
#if 0
|
||||||
static void audiohw_set_ngat(int ngath, int type, bool enable)
|
static void audiohw_set_ngat(int ngath, int type, bool enable)
|
||||||
{
|
{
|
||||||
/* This function controls Noise gate function
|
/* 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);
|
wmcodec_set_masked(ALC1, ALC1_ALCSEL_DISABLED, ALC1_ALCSEL_MASK);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void audiohw_set_recsrc(int source, bool recording)
|
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);
|
wmcodec_set_masked(ADCR, ADCR_RINSEL_RINPUT1, ADCR_RINSEL_MASK);
|
||||||
|
|
||||||
/* turn off ALC and NGAT as OF do */
|
/* turn off ALC and NGAT as OF do */
|
||||||
|
/*
|
||||||
audiohw_set_alc(0x00, false, 0x00, 0x00, 0x00, false);
|
audiohw_set_alc(0x00, false, 0x00, 0x00, 0x00, false);
|
||||||
audiohw_set_ngat(0x00, 0x00, false);
|
audiohw_set_ngat(0x00, 0x00, false);
|
||||||
|
*/
|
||||||
|
|
||||||
/* setup output digital data
|
/* setup output digital data
|
||||||
* default is LADC -> LDATA, RADC -> RDATA
|
* 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 */
|
/* setup ALC and NGAT as OF do */
|
||||||
/* level, zc, hold, decay, attack, enable */
|
/* 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 */
|
/* ngath, type, enable */
|
||||||
audiohw_set_ngat(0x08, 0x02, true);
|
/* audiohw_set_ngat(0x08, 0x02, true); */
|
||||||
|
|
||||||
/* setup output digital data
|
/* setup output digital data
|
||||||
* default is LADC -> LDATA, RADC -> RDATA
|
* 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 */
|
/* setup ALC and NGAT as OF do */
|
||||||
/* level, zc, hold, decay, attack, enable */
|
/* 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 */
|
/* ngath, type, enable */
|
||||||
audiohw_set_ngat(0x1f, 0x00, true);
|
/* audiohw_set_ngat(0x1f, 0x00, true); */
|
||||||
|
|
||||||
/* setup output digital data
|
/* setup output digital data
|
||||||
* default is LADC -> LDATA, RADC -> RDATA
|
* default is LADC -> LDATA, RADC -> RDATA
|
||||||
|
|
|
@ -669,6 +669,7 @@ void sound_set(int setting, int value)
|
||||||
&& !defined(HAVE_WM8758) && !defined(HAVE_TSC2100) \
|
&& !defined(HAVE_WM8758) && !defined(HAVE_TSC2100) \
|
||||||
&& !defined (HAVE_WM8711) && !defined (HAVE_WM8721) \
|
&& !defined (HAVE_WM8711) && !defined (HAVE_WM8721) \
|
||||||
&& !defined (HAVE_WM8731) && !defined (HAVE_WM8978) \
|
&& !defined (HAVE_WM8731) && !defined (HAVE_WM8978) \
|
||||||
|
&& !defined (HAVE_WM8750) && !defined (HAVE_WM8751) \
|
||||||
&& !defined(HAVE_AK4537)) || (CONFIG_PLATFORM & PLATFORM_HOSTED)
|
&& !defined(HAVE_AK4537)) || (CONFIG_PLATFORM & PLATFORM_HOSTED)
|
||||||
int sound_val2phys(int setting, int value)
|
int sound_val2phys(int setting, int value)
|
||||||
{
|
{
|
||||||
|
@ -748,7 +749,7 @@ int sound_val2phys(int setting, int value)
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
#elif defined(HAVE_WM8978)
|
#elif defined(HAVE_WM8978) || defined(HAVE_WM8750) || defined(HAVE_WM8751)
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
switch (setting)
|
switch (setting)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue