summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAidan MacDonald <amachronic@protonmail.com>2021-09-22 10:39:21 +0100
committerAidan MacDonald <amachronic@protonmail.com>2021-10-05 12:46:00 +0100
commitfd568d90a4eb5e635880ac8f050d521ab46c23b3 (patch)
tree926bcbcef25693d4009542d105c1aa5317a7ac1c
parent0a1d25d27a50fca95305c7d3ee3bdcfec8dbdae1 (diff)
downloadrockbox-fd568d90a4.tar.gz
rockbox-fd568d90a4.zip
m3k: don't use mixer controls for volume control
According to a forum user, there's an audible click when changing the volume between -32 and -32.5 dB with some headphones. Fix this by not (ab)using the DAC digital mixer for volume control. The mixer only provides an extra -6 dB of hardware volume range, so the only side effect is that software volume will now kick in at -32 dB instead of -38 dB. Change-Id: If24d9bc0058eff3c1a29aefb155a2e378522623c
-rw-r--r--firmware/drivers/audio/ak4376.c22
1 files changed, 8 insertions, 14 deletions
diff --git a/firmware/drivers/audio/ak4376.c b/firmware/drivers/audio/ak4376.c
index 11714b210d..8206bcf7e0 100644
--- a/firmware/drivers/audio/ak4376.c
+++ b/firmware/drivers/audio/ak4376.c
@@ -83,11 +83,11 @@ void ak4376_open(void)
ak4376_set_pdn_pin(1);
mdelay(1);
- static const int init_config[] = {
+ static const uint8_t init_config[] = {
/* Ensure HPRHZ, HPLHZ are 0 */
AK4376_REG_OUTPUT_MODE, 0x00,
/* Mute all volume controls */
- AK4376_REG_MIXER, 0x00,
+ AK4376_REG_MIXER, AK4376_MIX_LCH | (AK4376_MIX_RCH << 4),
AK4376_REG_LCH_VOLUME, 0x80,
AK4376_REG_RCH_VOLUME, 0x00,
AK4376_REG_AMP_VOLUME, 0x00,
@@ -150,14 +150,9 @@ static int round_step_up(int x, int step)
return x - rem;
}
-static void calc_volumes(int vol, int* mix, int* dig, int* sw)
+static void calc_volumes(int vol, int* dig, int* sw)
{
- /* Mixer can divide by 2, which gives an extra -6 dB adjustment */
- if(vol < AK4376_DIG_VOLUME_MIN) {
- *mix |= AK4376_MIX_HALF;
- vol += 60;
- }
-
+ /* Apply digital volume */
*dig = round_step_up(vol, AK4376_DIG_VOLUME_STEP);
*dig = MIN(*dig, AK4376_DIG_VOLUME_MAX);
*dig = MAX(*dig, AK4376_DIG_VOLUME_MIN);
@@ -186,8 +181,8 @@ static int amp_vol_to_hw(int vol)
void ak4376_set_volume(int vol_l, int vol_r)
{
int amp;
- int mix_l = AK4376_MIX_LCH, dig_l, sw_l;
- int mix_r = AK4376_MIX_RCH, dig_r, sw_r;
+ int dig_l, sw_l;
+ int dig_r, sw_r;
if(vol_l <= AK4376_MIN_VOLUME && vol_r <= AK4376_MIN_VOLUME) {
/* Special case for full mute */
@@ -202,11 +197,10 @@ void ak4376_set_volume(int vol_l, int vol_r)
amp = MAX(amp, AK4376_AMP_VOLUME_MIN);
/* Other controls are stereo */
- calc_volumes(vol_l - amp, &mix_l, &dig_l, &sw_l);
- calc_volumes(vol_r - amp, &mix_r, &dig_r, &sw_r);
+ calc_volumes(vol_l - amp, &dig_l, &sw_l);
+ calc_volumes(vol_r - amp, &dig_r, &sw_r);
}
- ak4376_write(AK4376_REG_MIXER, (mix_l & 0xf) | ((mix_r & 0xf) << 4));
ak4376_write(AK4376_REG_LCH_VOLUME, dig_vol_to_hw(dig_l) | (1 << 7));
ak4376_write(AK4376_REG_RCH_VOLUME, dig_vol_to_hw(dig_r));
ak4376_write(AK4376_REG_AMP_VOLUME, amp_vol_to_hw(amp));