mirror of
git://nv-tegra.nvidia.com/linux-nv-oot.git
synced 2025-12-22 17:25:35 +03:00
ASoC: tegra-alt: Fix MVC gain issues
The Applied gain in dB never reflected in the output data with the current driver code. There was few issues related to the way we program the sequences. As a first step cleaning up the driver to make sure the applied gain is proper in the output and bitmatch works with multiple runs. - Do MVC soft reset to clear the state in the hw_params before processing the input data. - Assign the init volume and target volume to the same value at start of processing. - Trigger the switch only after programming all the registers related to Volume, duration and polynomial coefficients. Bug 200532059 Change-Id: I2c77bd225284f31892ed8c2ff7c228dd19f8c63e Signed-off-by: Mohan Kumar <mkumard@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/2170333 (cherry picked from commit 6f56c3df3f2f6a55e33d9071cb5d05d0992a6b28) Reviewed-on: https://git-master.nvidia.com/r/2173817 Reviewed-by: Automatic_Commit_Validation_User GVS: Gerrit_Virtual_Submit Reviewed-by: Ravindra Lokhande <rlokhande@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
This commit is contained in:
committed by
Sameer Pujar
parent
a4c55519f8
commit
919e8b00bd
@@ -75,6 +75,24 @@ static int tegra210_mvc_runtime_resume(struct device *dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tegra210_mvc_soft_reset(struct tegra210_mvc *mvc)
|
||||
{
|
||||
int value;
|
||||
int dcnt = 10;
|
||||
/* issue soft reset */
|
||||
regmap_write(mvc->regmap, TEGRA210_MVC_SOFT_RESET, 1);
|
||||
/* wait for soft reset bit to clear */
|
||||
do {
|
||||
udelay(10);
|
||||
regmap_read(mvc->regmap, TEGRA210_MVC_SOFT_RESET, &value);
|
||||
dcnt--;
|
||||
if (dcnt < 0)
|
||||
return -EINVAL;
|
||||
} while (value);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tegra210_mvc_write_ram(struct tegra210_mvc *mvc,
|
||||
unsigned int addr,
|
||||
unsigned int val)
|
||||
@@ -209,9 +227,7 @@ static int tegra210_mvc_put_curve_type(struct snd_kcontrol *kcontrol,
|
||||
struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
|
||||
struct tegra210_mvc *mvc = snd_soc_codec_get_drvdata(codec);
|
||||
unsigned int reg = TEGRA210_MVC_CTRL;
|
||||
int dcnt = 10;
|
||||
int ret = 0;
|
||||
u32 value;
|
||||
|
||||
/* if no change in curve type, do nothing */
|
||||
if (mvc->curve_type == ucontrol->value.integer.value[0])
|
||||
@@ -226,18 +242,11 @@ static int tegra210_mvc_put_curve_type(struct snd_kcontrol *kcontrol,
|
||||
TEGRA210_MVC_CURVE_TYPE_SHIFT);
|
||||
mvc->curve_type = ucontrol->value.integer.value[0];
|
||||
|
||||
/* issue soft reset */
|
||||
regmap_write(mvc->regmap, TEGRA210_MVC_SOFT_RESET, 1);
|
||||
/* wait for soft reset bit to clear */
|
||||
do {
|
||||
udelay(10);
|
||||
ret = regmap_read(mvc->regmap, TEGRA210_MVC_SOFT_RESET, &value);
|
||||
dcnt--;
|
||||
if (dcnt < 0) {
|
||||
ret = -EINVAL;
|
||||
goto end;
|
||||
ret = tegra210_mvc_soft_reset(mvc);
|
||||
if (ret < 0) {
|
||||
dev_err(codec->dev, "SOFT_RESET error: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
} while (value);
|
||||
|
||||
/* change volume to default init for new curve type */
|
||||
if (ucontrol->value.integer.value[0] == CURVE_POLY)
|
||||
@@ -250,7 +259,6 @@ static int tegra210_mvc_put_curve_type(struct snd_kcontrol *kcontrol,
|
||||
TEGRA210_MVC_VOLUME_SWITCH_MASK,
|
||||
TEGRA210_MVC_VOLUME_SWITCH_TRIGGER);
|
||||
|
||||
end:
|
||||
pm_runtime_put(codec->dev);
|
||||
|
||||
return ret;
|
||||
@@ -376,6 +384,12 @@ static int tegra210_mvc_hw_params(struct snd_pcm_substream *substream,
|
||||
struct tegra210_mvc *mvc = snd_soc_dai_get_drvdata(dai);
|
||||
int i, ret;
|
||||
|
||||
ret = tegra210_mvc_soft_reset(mvc);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "SOFT_RESET error: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* set RX cif and TX cif */
|
||||
ret = tegra210_mvc_set_audio_cif(mvc, params,
|
||||
TEGRA210_MVC_AXBAR_RX_CIF_CTRL);
|
||||
@@ -396,23 +410,14 @@ static int tegra210_mvc_hw_params(struct snd_pcm_substream *substream,
|
||||
~(TEGRA210_MVC_PER_CHAN_CTRL_EN_MASK));
|
||||
|
||||
/* init the default volume=1 for MVC */
|
||||
regmap_write(mvc->regmap, TEGRA210_MVC_INIT_VOL,
|
||||
(mvc->curve_type == CURVE_POLY) ?
|
||||
TEGRA210_MVC_INIT_VOL_DEFAULT_POLY :
|
||||
TEGRA210_MVC_INIT_VOL_DEFAULT_LINEAR);
|
||||
regmap_write(mvc->regmap, TEGRA210_MVC_INIT_VOL, mvc->volume);
|
||||
|
||||
regmap_write(mvc->regmap, TEGRA210_MVC_TARGET_VOL, mvc->volume);
|
||||
/* trigger volume switch */
|
||||
ret |= regmap_update_bits(mvc->regmap, TEGRA210_MVC_SWITCH,
|
||||
TEGRA210_MVC_VOLUME_SWITCH_MASK,
|
||||
TEGRA210_MVC_VOLUME_SWITCH_TRIGGER);
|
||||
|
||||
|
||||
/* program the poly coefficients */
|
||||
for (i = 0; i < 9; i++)
|
||||
tegra210_mvc_write_ram(mvc, i, mvc->poly_coeff[i]);
|
||||
|
||||
|
||||
/* program poly_n1, poly_n2, duration */
|
||||
regmap_write(mvc->regmap, TEGRA210_MVC_POLY_N1, mvc->poly_n1);
|
||||
regmap_write(mvc->regmap, TEGRA210_MVC_POLY_N2, mvc->poly_n2);
|
||||
@@ -421,6 +426,10 @@ static int tegra210_mvc_hw_params(struct snd_pcm_substream *substream,
|
||||
/* program duration_inv */
|
||||
regmap_write(mvc->regmap, TEGRA210_MVC_DURATION_INV, mvc->duration_inv);
|
||||
|
||||
/* trigger volume switch */
|
||||
ret |= regmap_update_bits(mvc->regmap, TEGRA210_MVC_SWITCH,
|
||||
TEGRA210_MVC_VOLUME_SWITCH_MASK,
|
||||
TEGRA210_MVC_VOLUME_SWITCH_TRIGGER);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user