diff mbox series

ASoC: tas5805m: demystify DSP volume control coefficients

Message ID 20240702024709.626009-1-felix@kaechele.ca (mailing list archive)
State New, archived
Headers show
Series ASoC: tas5805m: demystify DSP volume control coefficients | expand

Commit Message

Felix Kaechele July 2, 2024, 2:46 a.m. UTC
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@kaechele.ca>

[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(-)


base-commit: 9fa5527b19b21848dfb09928ee66af1aac4a5700
diff mbox series

Patch

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]);