Kaynağa Gözat

asoc: bolero: enable VA macro island mode MUX select on Kona

VA macro is currently lacking capability to dynamically select
island mode on Kona. Add support in VA macro driver to read MUX
selection register from DT to enable dynamic island mode select.

Change-Id: I5462265fffcc6d6bbb3ff6eead5f44f0b8909141
Signed-off-by: Xiaoyu Ye <[email protected]>
Xiaoyu Ye 6 yıl önce
ebeveyn
işleme
2122732534
1 değiştirilmiş dosya ile 51 ekleme ve 15 silme
  1. 51 15
      asoc/codecs/bolero/va-macro.c

+ 51 - 15
asoc/codecs/bolero/va-macro.c

@@ -107,7 +107,9 @@ struct va_macro_priv {
 	s32 dmic_6_7_clk_cnt;
 	s32 dmic_6_7_clk_cnt;
 	u16 dmic_clk_div;
 	u16 dmic_clk_div;
 	u16 va_mclk_users;
 	u16 va_mclk_users;
+	u16 mclk_mux_sel;
 	char __iomem *va_io_base;
 	char __iomem *va_io_base;
+	char __iomem *va_island_mode_muxsel;
 	struct regulator *micb_supply;
 	struct regulator *micb_supply;
 	u32 micb_voltage;
 	u32 micb_voltage;
 	u32 micb_current;
 	u32 micb_current;
@@ -139,7 +141,6 @@ static int va_macro_mclk_enable(struct va_macro_priv *va_priv,
 {
 {
 	struct regmap *regmap = dev_get_regmap(va_priv->dev->parent, NULL);
 	struct regmap *regmap = dev_get_regmap(va_priv->dev->parent, NULL);
 	int ret = 0;
 	int ret = 0;
-	u16 mclk_mux_sel = MCLK_MUX0;
 
 
 	if (regmap == NULL) {
 	if (regmap == NULL) {
 		dev_err(va_priv->dev, "%s: regmap is NULL\n", __func__);
 		dev_err(va_priv->dev, "%s: regmap is NULL\n", __func__);
@@ -150,21 +151,11 @@ static int va_macro_mclk_enable(struct va_macro_priv *va_priv,
 		__func__, mclk_enable, dapm, va_priv->va_mclk_users);
 		__func__, mclk_enable, dapm, va_priv->va_mclk_users);
 
 
 	mutex_lock(&va_priv->mclk_lock);
 	mutex_lock(&va_priv->mclk_lock);
-	if (of_property_read_u16(va_priv->dev->of_node,
-				 "qcom,va-clk-mux-select", &mclk_mux_sel))
-		dev_dbg(va_priv->dev,
-			"%s: could not find %s entry in dt, use default\n",
-			__func__, "qcom,va-clk-mux-select");
-	if (mclk_mux_sel != MCLK_MUX0 && mclk_mux_sel != MCLK_MUX1) {
-		dev_err(va_priv->dev, "%s: mclk_mux_sel: %d is invalid\n",
-			__func__, mclk_mux_sel);
-		return -EINVAL;
-	}
-
 	if (mclk_enable) {
 	if (mclk_enable) {
 		if (va_priv->va_mclk_users == 0) {
 		if (va_priv->va_mclk_users == 0) {
 			ret = bolero_request_clock(va_priv->dev,
 			ret = bolero_request_clock(va_priv->dev,
-						VA_MACRO, mclk_mux_sel, true);
+						VA_MACRO,
+						va_priv->mclk_mux_sel, true);
 			if (ret < 0) {
 			if (ret < 0) {
 				dev_err(va_priv->dev,
 				dev_err(va_priv->dev,
 					"%s: va request clock en failed\n",
 					"%s: va request clock en failed\n",
@@ -205,7 +196,8 @@ static int va_macro_mclk_enable(struct va_macro_priv *va_priv,
 				BOLERO_CDC_VA_CLK_RST_CTRL_MCLK_CONTROL,
 				BOLERO_CDC_VA_CLK_RST_CTRL_MCLK_CONTROL,
 				0x01, 0x00);
 				0x01, 0x00);
 			bolero_request_clock(va_priv->dev,
 			bolero_request_clock(va_priv->dev,
-					VA_MACRO, mclk_mux_sel, false);
+					VA_MACRO,
+					va_priv->mclk_mux_sel, false);
 		}
 		}
 	}
 	}
 exit:
 exit:
@@ -289,7 +281,11 @@ static int va_macro_mclk_ctrl(struct device *dev, bool enable)
 			dev_err(dev, "%s:va mclk enable failed\n", __func__);
 			dev_err(dev, "%s:va mclk enable failed\n", __func__);
 			goto exit;
 			goto exit;
 		}
 		}
+		if (va_priv->mclk_mux_sel == MCLK_MUX1)
+			iowrite32(0x1, va_priv->va_island_mode_muxsel);
 	} else {
 	} else {
+		if (va_priv->mclk_mux_sel == MCLK_MUX1)
+			iowrite32(0x0, va_priv->va_island_mode_muxsel);
 		clk_disable_unprepare(va_priv->va_core_clk);
 		clk_disable_unprepare(va_priv->va_core_clk);
 	}
 	}
 
 
@@ -1611,8 +1607,9 @@ static int va_macro_probe(struct platform_device *pdev)
 {
 {
 	struct macro_ops ops;
 	struct macro_ops ops;
 	struct va_macro_priv *va_priv;
 	struct va_macro_priv *va_priv;
-	u32 va_base_addr, sample_rate = 0;
+	u32 va_base_addr, sample_rate = 0, island_sel = 0;
 	char __iomem *va_io_base;
 	char __iomem *va_io_base;
+	char __iomem *va_muxsel_io = NULL;
 	struct clk *va_core_clk;
 	struct clk *va_core_clk;
 	bool va_without_decimation = false;
 	bool va_without_decimation = false;
 	const char *micb_supply_str = "va-vdd-micb-supply";
 	const char *micb_supply_str = "va-vdd-micb-supply";
@@ -1621,6 +1618,7 @@ static int va_macro_probe(struct platform_device *pdev)
 	const char *micb_current_str = "qcom,va-vdd-micb-current";
 	const char *micb_current_str = "qcom,va-vdd-micb-current";
 	int ret = 0;
 	int ret = 0;
 	const char *dmic_sample_rate = "qcom,va-dmic-sample-rate";
 	const char *dmic_sample_rate = "qcom,va-dmic-sample-rate";
+	u16 mclk_mux_sel = MCLK_MUX0;
 
 
 	va_priv = devm_kzalloc(&pdev->dev, sizeof(struct va_macro_priv),
 	va_priv = devm_kzalloc(&pdev->dev, sizeof(struct va_macro_priv),
 			    GFP_KERNEL);
 			    GFP_KERNEL);
@@ -1658,6 +1656,44 @@ static int va_macro_probe(struct platform_device *pdev)
 		return -EINVAL;
 		return -EINVAL;
 	}
 	}
 	va_priv->va_io_base = va_io_base;
 	va_priv->va_io_base = va_io_base;
+
+	ret = of_property_read_u16(va_priv->dev->of_node,
+				   "qcom,va-clk-mux-select", &mclk_mux_sel);
+	if (ret) {
+		dev_dbg(&pdev->dev,
+			"%s: could not find %s entry in dt, use default\n",
+			__func__, "qcom,va-clk-mux-select");
+	} else {
+		if (mclk_mux_sel != MCLK_MUX0 && mclk_mux_sel != MCLK_MUX1) {
+			dev_err(&pdev->dev,
+				"%s: mclk_mux_sel: %d is invalid\n",
+				__func__, mclk_mux_sel);
+			return -EINVAL;
+		}
+	}
+	va_priv->mclk_mux_sel = mclk_mux_sel;
+
+	if (va_priv->mclk_mux_sel == MCLK_MUX1) {
+		ret = of_property_read_u32(pdev->dev.of_node,
+					   "qcom,va-island-mode-muxsel",
+					   &island_sel);
+		if (ret) {
+			dev_err(&pdev->dev,
+				"%s: could not find %s entry in dt\n",
+				__func__, "qcom,va-island-mode-muxsel");
+			return ret;
+		} else {
+			va_muxsel_io = devm_ioremap(&pdev->dev,
+						    island_sel, 0x4);
+			if (!va_muxsel_io) {
+				dev_err(&pdev->dev,
+					"%s: ioremap failed for island_sel\n",
+					__func__);
+				return -ENOMEM;
+			}
+		}
+		va_priv->va_island_mode_muxsel = va_muxsel_io;
+	}
 	/* Register MCLK for va macro */
 	/* Register MCLK for va macro */
 	va_core_clk = devm_clk_get(&pdev->dev, "va_core_clk");
 	va_core_clk = devm_clk_get(&pdev->dev, "va_core_clk");
 	if (IS_ERR(va_core_clk)) {
 	if (IS_ERR(va_core_clk)) {