[1/2] iio: adc: mt6577_auxadc: add optional 32k clock

Message ID f98ed7f3fc15a0614443a57427d46ce17ec2e0cc.1666190235.git.daniel@makrotopia.org
State New
Headers
Series [1/2] iio: adc: mt6577_auxadc: add optional 32k clock |

Commit Message

Daniel Golle Oct. 19, 2022, 2:37 p.m. UTC
  MediaTek MT7986 and MT7981 require an additional clock to be brought up
for AUXADC. Add support for that in the driver, similar to how it's
done in MediaTek's SDK[1].

[1]: https://git01.mediatek.com/plugins/gitiles/openwrt/feeds/mtk-openwrt-feeds/+/refs/heads/master/target/linux/mediatek/patches-5.4/500-auxadc-add-auxadc-32k-clk.patch
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
---
 drivers/iio/adc/mt6577_auxadc.c | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)
  

Patch

diff --git a/drivers/iio/adc/mt6577_auxadc.c b/drivers/iio/adc/mt6577_auxadc.c
index 0e134777bdd248..e28e9691cae22a 100644
--- a/drivers/iio/adc/mt6577_auxadc.c
+++ b/drivers/iio/adc/mt6577_auxadc.c
@@ -42,6 +42,7 @@  struct mtk_auxadc_compatible {
 struct mt6577_auxadc_device {
 	void __iomem *reg_base;
 	struct clk *adc_clk;
+	struct clk *adc_32k_clk;
 	struct mutex lock;
 	const struct mtk_auxadc_compatible *dev_comp;
 };
@@ -227,6 +228,12 @@  static int mt6577_auxadc_resume(struct device *dev)
 		return ret;
 	}
 
+	ret = clk_prepare_enable(adc_dev->adc_32k_clk);
+	if (ret) {
+		pr_err("failed to enable auxadc clock\n");
+		return ret;
+	}
+
 	mt6577_auxadc_mod_reg(adc_dev->reg_base + MT6577_AUXADC_MISC,
 			      MT6577_AUXADC_PDN_EN, 0);
 	mdelay(MT6577_AUXADC_POWER_READY_MS);
@@ -241,6 +248,8 @@  static int mt6577_auxadc_suspend(struct device *dev)
 
 	mt6577_auxadc_mod_reg(adc_dev->reg_base + MT6577_AUXADC_MISC,
 			      0, MT6577_AUXADC_PDN_EN);
+
+	clk_disable_unprepare(adc_dev->adc_32k_clk);
 	clk_disable_unprepare(adc_dev->adc_clk);
 
 	return 0;
@@ -282,6 +291,17 @@  static int mt6577_auxadc_probe(struct platform_device *pdev)
 		return ret;
 	}
 
+	adc_dev->adc_32k_clk = devm_clk_get_optional(&pdev->dev, "32k");
+	if (IS_ERR(adc_dev->adc_32k_clk)) {
+		dev_err(&pdev->dev, "failed to get auxadc 32k clock\n");
+		return PTR_ERR(adc_dev->adc_32k_clk);
+	}
+	ret = clk_prepare_enable(adc_dev->adc_32k_clk);
+	if (ret) {
+		dev_err(&pdev->dev, "failed to enable auxadc 32k clock\n");
+		return ret;
+	}
+
 	adc_clk_rate = clk_get_rate(adc_dev->adc_clk);
 	if (!adc_clk_rate) {
 		ret = -EINVAL;
@@ -311,6 +331,7 @@  static int mt6577_auxadc_probe(struct platform_device *pdev)
 	mt6577_auxadc_mod_reg(adc_dev->reg_base + MT6577_AUXADC_MISC,
 			      0, MT6577_AUXADC_PDN_EN);
 err_disable_clk:
+	clk_disable_unprepare(adc_dev->adc_32k_clk);
 	clk_disable_unprepare(adc_dev->adc_clk);
 	return ret;
 }
@@ -325,6 +346,7 @@  static int mt6577_auxadc_remove(struct platform_device *pdev)
 	mt6577_auxadc_mod_reg(adc_dev->reg_base + MT6577_AUXADC_MISC,
 			      0, MT6577_AUXADC_PDN_EN);
 
+	clk_disable_unprepare(adc_dev->adc_32k_clk);
 	clk_disable_unprepare(adc_dev->adc_clk);
 
 	return 0;