Hello,
I'm trying to limit the maximum volume level allowed for the tlv320aic3110. In our initial tests, when the volume is at its maximum default volume, it ends up damaging the speaker. For now, we are lowering the default volume using ALSA controls, but we would like to have a limit that couldn't be surpassed even with ALSA controls. My idea is to use some values read from the device tree that would be written to the appropriate registers.
I have successfully modified the driver to read these values and I'm writing to a series of registers, but that doesn't seem to be having any effect. When I load the OS in our terminal and modify the volume level to the maximum value, I seem to be getting the same volume I was getting without my modifications.
These are the registers I'm writing to:
if (strncmp(name, "SP Analog Playback Volume", 25) == 0) { aic31xx->SP_Analog_Playback_Volume = 127 - limit; } if (strncmp(name, "SP Driver Playback Volume", 25) == 0) { aic31xx->SP_Driver_Playback_Volume = limit; } ret = snd_soc_component_write(component, AIC31XX_DACMIXERROUTE, 0x44); /* Page 1 / Register 35 (0x23): DAC_L and DAC_R Output Mixer Routing */ ret = snd_soc_component_write(component, AIC31XX_LANALOGHPL, 0xC0); /* Page 1 / Register 36 (0x24): Left Analog Volume to HPL */ ret = snd_soc_component_write(component, AIC31XX_RANALOGHPR, 0xC0); /* Page 1 / Register 37 (0x25): Right Analog Volume to HPR */ ret = snd_soc_component_write(component, AIC31XX_LANALOGSPL, (aic31xx->SP_Analog_Playback_Volume & 0x7F) | 0x80); /* Page 1 / Register 38 (0x26): Left Analog Volume to SPL */ ret = snd_soc_component_write(component, AIC31XX_RANALOGSPR, (aic31xx->SP_Analog_Playback_Volume & 0x7F) | 0x80); /* Page 1 / Register 39 (0x27): Right Analog Volume to SPR */ ret = snd_soc_component_write(component, AIC31XX_HPDRIVER, 0xc4); /* Page 1 / Register 31 (0x1F): Headphone Drivers */ ret = snd_soc_component_write(component, AIC31XX_HPLGAIN, 0x4d); /* Page 1 / Register 40 (0x28): HPL Driver */ ret = snd_soc_component_write(component, AIC31XX_HPRGAIN, 0x4d); /* Page 1 / Register 41 (0x29): HPR Driver */ ret = snd_soc_component_write(component, AIC31XX_SPLGAIN, ((aic31xx->SP_Driver_Playback_Volume & 0x03) << 3) | 0x5); /* Page 1 / Register 42 (0x2A): SPL Driver */ ret = snd_soc_component_write(component, AIC31XX_SPRGAIN, ((aic31xx->SP_Driver_Playback_Volume & 0x03) << 3) | 0x5); /* Page 1 / Register 43 (0x2B): SPR Driver */ ret = snd_soc_component_write(component, AIC31XX_SPKAMP, 0xc6); /* Page 1 / Register 32 (0x20): Class-D Speaker Amplifier */ ret = snd_soc_component_write(component, AIC31XX_LANALOGSPL, 0x74); /* Page 1 / Register 38 (0x26): Left Analog Volume to SPL */ ret = snd_soc_component_write(component, AIC31XX_RANALOGSPR, 0x74); /* Page 1 / Register 39 (0x27): Right Analog Volume to SPR */
I'm writing to them in the probe function, at the end, right after reading the values from the device tree I mentioned earlier. According to the value returned by the write function, it is being successful, and the read function returns the same value I'm trying to write.
Should I write to these registers in a different place or with a certain frequency (every minute, for example)? Could it be a completely different thing?
To modify the volume once my change is installed, I'm using alsamixer, and I'm using speaker-test to produce sound.