The original manufacturer sample driver code uses direct DSP register
writes to control digital volume on this amplifier without further
context as to why it's not using the documented DIG_VOL_CTRL register.
A thread in the manufacturer's forums [1] suggests this might have been
done to work around volume ramping being used when controlling the volume
through the DIG_VOL_CTRL register. When volume is controlled through
this register, reading and/or writing any register is blocked until the
volume ramping has concluded and the setpoint is reached.
Additionally, the sample code uses a lookup table to map decibel values
to 9.23 formatted coefficients. For posterity, add references to where
this is documented and why a lookup table may be used.
Signed-off-by: Felix Kaechele <felix@xxxxxxxxxxx>
[1]: https://e2e.ti.com/support/audio-group/audio/f/audio-forum/1165952/tas5805m-linux-driver-for-tas58xx-family
---
sound/soc/codecs/tas5805m.c | 18 +++++++++++++++---
1 file changed, 15 insertions(+), 3 deletions(-)
diff --git a/sound/soc/codecs/tas5805m.c b/sound/soc/codecs/tas5805m.c
index 3b53eba38a0b..59536c8b8e38 100644
--- a/sound/soc/codecs/tas5805m.c
+++ b/sound/soc/codecs/tas5805m.c
@@ -67,6 +67,14 @@ static const uint8_t dsp_cfg_preboot[] = {
0x00, 0x00, 0x7f, 0x00, 0x03, 0x02,
};
+/*
+ * Lookup table for DSP volume coefficients.
+ * The formula uses floating point math, so a lookup table is used
+ * instead of computing values on the fly.
+ * Formula: round(10^(volume in dB/20)*2^23)
+ * The 9.23 format used here is documented in
+ * SLAA894 - "General Tuning Guide for TAS58xx Family"
+ */
static const uint32_t tas5805m_volume[] = {
0x0000001B, /* 0, -110dB */ 0x0000001E, /* 1, -109dB */
0x00000021, /* 2, -108dB */ 0x00000025, /* 3, -107dB */
@@ -196,9 +204,13 @@ static void tas5805m_refresh(struct tas5805m_priv *tas5805m)
regmap_write(rm, REG_BOOK, 0x8c);
regmap_write(rm, REG_PAGE, 0x2a);
- /* Refresh volume. The actual volume control documented in the
- * datasheet doesn't seem to work correctly. This is a pair of
- * DSP registers which are *not* documented in the datasheet.
+ /* Refresh volume. This writes the volume coefficients from
+ * the lookup table directly into the DSP registers.
+ * Digital volume control on this chip involves ramping which
+ * blocks register reads and writes until the desired setpoint
+ * is reached.
+ * The DSP memory maps are documented in
+ * SLOA263A - "TAS5805M, TAS5806M and TAS5806MD Process Flows"
*/
set_dsp_scale(rm, 0x24, tas5805m->vol[0]);
set_dsp_scale(rm, 0x28, tas5805m->vol[1]);
base-commit: 9fa5527b19b21848dfb09928ee66af1aac4a5700
--
2.45.2
[Index of Archives]
[Pulseaudio]
[Linux Audio Users]
[ALSA Devel]
[Fedora Desktop]
[Fedora SELinux]
[Big List of Linux Books]
[Yosemite News]
[KDE Users]