[03/11] soc: codecs: tlv320aic31xx: Add support for external optional clock mclk

Message ID 20211111152258.26131-3-michael@amarulasolutions.com
State New
Headers show
Series
  • [01/11] arm: dts: imx8ulz-smm-m2: Add BSH SMM-M2 IMX6ULZ System on Module
Related show

Commit Message

Michael Nazzareno Trimarchi Nov. 11, 2021, 3:22 p.m. UTC
Need to be sure that clock connected to the codec is enable during
the codec probe.

Signed-off-by: Michael Trimarchi <michael@amarulasolutions.com>
---
 sound/soc/codecs/tlv320aic31xx.c | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

Patch

diff --git a/sound/soc/codecs/tlv320aic31xx.c b/sound/soc/codecs/tlv320aic31xx.c
index 6b54811be1ca..f1a758fe07ce 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>
@@ -162,6 +163,7 @@  struct aic31xx_priv {
 	u8 i2c_regs_status;
 	struct device *dev;
 	struct regmap *regmap;
+	struct clk *clk;
 	enum aic31xx_type codec_type;
 	struct gpio_desc *gpio_reset;
 	int micbias_vg;
@@ -1346,6 +1348,21 @@  static int aic31xx_codec_probe(struct snd_soc_component *component)
 
 	aic31xx->component = component;
 
+	aic31xx->clk = devm_clk_get_optional(component->dev, "mclk");
+	if (IS_ERR(aic31xx->clk)) {
+		dev_err(component->dev, "failed to get the clock: %ld\n",
+				PTR_ERR(aic31xx->clk));
+		return -EINVAL;
+	}
+
+	aic31xx->sysclk = clk_get_rate(aic31xx->clk);
+
+	ret = clk_prepare_enable(aic31xx->clk);
+	if (ret) {
+		dev_err(component->dev, "unable to enable mclk\n");
+		return ret;
+	}
+
 	for (i = 0; i < ARRAY_SIZE(aic31xx->supplies); i++) {
 		aic31xx->disable_nb[i].nb.notifier_call =
 			aic31xx_regulator_event;
@@ -1380,8 +1397,16 @@  static int aic31xx_codec_probe(struct snd_soc_component *component)
 	return 0;
 }
 
+static void aic31xx_codec_remove(struct snd_soc_component *component)
+{
+	struct aic31xx_priv *aic31xx = snd_soc_component_get_drvdata(component);
+
+	clk_disable_unprepare(aic31xx->clk);
+}
+
 static const struct snd_soc_component_driver soc_codec_driver_aic31xx = {
 	.probe			= aic31xx_codec_probe,
+	.remove			= aic31xx_codec_remove,
 	.set_jack		= aic31xx_set_jack,
 	.set_bias_level		= aic31xx_set_bias_level,
 	.controls		= common31xx_snd_controls,