summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAriel D'Alessandro <ariel.dalessandro@collabora.com>2021-11-19 18:32:47 +0300
committerMark Brown <broonie@kernel.org>2021-11-22 18:43:02 +0300
commitc5d22d5e12e776fee4e346dc098fe51d00c2f983 (patch)
treea37901008edb5b6269da8476527a3b26146dfc3a
parent6e6752a9c78738e27bde6da5cefa393b589276bb (diff)
downloadlinux-c5d22d5e12e776fee4e346dc098fe51d00c2f983.tar.xz
ASoC: tlv320aic31xx: Handle BCLK set as PLL input configuration
If BCLK is used as PLL input, the sysclk is determined by the hw params. So it must be updated here to match the input frequency, based on sample rate, format and channels. Signed-off-by: Ariel D'Alessandro <ariel.dalessandro@collabora.com> Signed-off-by: Michael Trimarchi <michael@amarulasolutions.com> Link: https://lore.kernel.org/r/20211119153248.419802-5-ariel.dalessandro@collabora.com Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r--sound/soc/codecs/tlv320aic31xx.c14
1 files changed, 14 insertions, 0 deletions
diff --git a/sound/soc/codecs/tlv320aic31xx.c b/sound/soc/codecs/tlv320aic31xx.c
index e8307f0737f2..4224b4b3cae6 100644
--- a/sound/soc/codecs/tlv320aic31xx.c
+++ b/sound/soc/codecs/tlv320aic31xx.c
@@ -15,6 +15,7 @@
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/init.h>
+#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/pm.h>
#include <linux/i2c.h>
@@ -169,6 +170,7 @@ struct aic31xx_priv {
struct regulator_bulk_data supplies[AIC31XX_NUM_SUPPLIES];
struct aic31xx_disable_nb disable_nb[AIC31XX_NUM_SUPPLIES];
struct snd_soc_jack *jack;
+ u32 sysclk_id;
unsigned int sysclk;
u8 p_div;
int rate_div_line;
@@ -962,6 +964,7 @@ static int aic31xx_hw_params(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
struct snd_soc_component *component = dai->component;
+ struct aic31xx_priv *aic31xx = snd_soc_component_get_drvdata(component);
u8 data = 0;
dev_dbg(component->dev, "## %s: width %d rate %d\n",
@@ -993,6 +996,16 @@ static int aic31xx_hw_params(struct snd_pcm_substream *substream,
AIC31XX_IFACE1_DATALEN_MASK,
data);
+ /*
+ * If BCLK is used as PLL input, the sysclk is determined by the hw
+ * params. So it must be updated here to match the input frequency.
+ */
+ if (aic31xx->sysclk_id == AIC31XX_PLL_CLKIN_BCLK) {
+ aic31xx->sysclk = params_rate(params) * params_width(params) *
+ params_channels(params);
+ aic31xx->p_div = 1;
+ }
+
return aic31xx_setup_pll(component, params);
}
@@ -1177,6 +1190,7 @@ static int aic31xx_set_dai_sysclk(struct snd_soc_dai *codec_dai,
snd_soc_component_update_bits(component, AIC31XX_CLKMUX, AIC31XX_PLL_CLKIN_MASK,
clk_id << AIC31XX_PLL_CLKIN_SHIFT);
+ aic31xx->sysclk_id = clk_id;
aic31xx->sysclk = freq;
return 0;