tlv320aic3x audio driver -- possible bug

Frederick Gotham cauldwell.thomas at gmail.com
Fri Jul 23 15:29:51 CEST 2021


In the C source file "tlv320aic3x" in the function "aic3x_set_power",
when the argument for power is 0, the hardware registers are saved to
the Linux computer as follows:

    regcache_cache_only(aic3x->regmap, true);

And then later when "aic3x_set_power" is called with power set to 1,
the previous values are then restored back to their hardware
registers:

     regcache_cache_only(aic3x->regmap, false);
     regcache_sync(aic3x->regmap);

When the device is powered back on, the previous setting for
microphone bias (MICBIAS) is lost. If it was previously set to 2 volts
or 2.5 volts, then when it's powered back on it becomes Off.

I'm not very familiar with audio codec chips and how they work, but I
think maybe the order of function calls in the "else" branch might be
incorrect. Right now the code looks like this:

		/*
		 * Do soft reset to this codec instance in order to clear
		 * possible VDD leakage currents in case the supply regulators
		 * remain on
		 */
		snd_soc_component_write(component, AIC3X_RESET, SOFT_RESET);
		regcache_mark_dirty(aic3x->regmap);
		aic3x->power = 0;
		/* HW writes are needless when bias is off */
		regcache_cache_only(aic3x->regmap, true);
		ret = regulator_bulk_disable(ARRAY_SIZE(aic3x->supplies),
					     aic3x->supplies);

However I think that the call to "regcache_cache_only" should come
before the soft reset takeS place. The setting for MICBIAS is lost at
this line:

    snd_soc_component_write(component, AIC3X_RESET, SOFT_RESET);

And so I think that the call to "regcache_cache_only" should be moved
up above "snd_soc_component_write", as follows:


		/*
		 * Do soft reset to this codec instance in order to clear
		 * possible VDD leakage currents in case the supply regulators
		 * remain on
		 */
		regcache_cache_only(aic3x->regmap, true);
		snd_soc_component_write(component, AIC3X_RESET, SOFT_RESET);
		regcache_mark_dirty(aic3x->regmap);
		aic3x->power = 0;
		ret = regulator_bulk_disable(ARRAY_SIZE(aic3x->supplies),
					     aic3x->supplies);


More information about the Alsa-devel mailing list