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