Browse Source

asoc: codecs: Add wakeup register update for chip register

Update cdc-pinctrl driver to handle wakeup control
provided in any spare chip register.

Change-Id: Iaa413d4b78e0c9841e40d01d0b891da34ff79de2
Signed-off-by: Laxminath Kasam <[email protected]>
Laxminath Kasam 5 years ago
parent
commit
3d89d5356b
1 changed files with 40 additions and 1 deletions
  1. 40 1
      asoc/codecs/msm-cdc-pinctrl.c

+ 40 - 1
asoc/codecs/msm-cdc-pinctrl.c

@@ -4,6 +4,7 @@
 
 #include <linux/kernel.h>
 #include <linux/init.h>
+#include <linux/io.h>
 #include <linux/err.h>
 #include <linux/module.h>
 #include <linux/of.h>
@@ -23,8 +24,12 @@ struct msm_cdc_pinctrl_info {
 	int gpio;
 	bool state;
 	u32 tlmm_gpio[MAX_GPIOS];
+	char __iomem *chip_wakeup_register[MAX_GPIOS];
+	u32 chip_wakeup_maskbit[MAX_GPIOS];
 	u32 count;
+	u32 wakeup_reg_count;
 	bool wakeup_capable;
+	bool chip_wakeup_reg;
 };
 
 static struct msm_cdc_pinctrl_info *msm_cdc_pinctrl_get_gpiodata(
@@ -154,7 +159,7 @@ int msm_cdc_pinctrl_set_wakeup_capable(struct device_node *np, bool enable)
 {
 	struct msm_cdc_pinctrl_info *gpio_data;
 	int ret = 0;
-	u32 i = 0;
+	u32 i = 0, temp = 0;
 
 	gpio_data = msm_cdc_pinctrl_get_gpiodata(np);
 	if (!gpio_data)
@@ -168,6 +173,18 @@ int msm_cdc_pinctrl_set_wakeup_capable(struct device_node *np, bool enable)
 				goto exit;
 		}
 	}
+	if (gpio_data->chip_wakeup_reg) {
+		for (i = 0; i < gpio_data->wakeup_reg_count; i++) {
+			temp = ioread32(gpio_data->chip_wakeup_register[i]);
+			if (enable)
+				temp |= (1 <<
+					 gpio_data->chip_wakeup_maskbit[i]);
+			else
+				temp &= ~(1 <<
+					  gpio_data->chip_wakeup_maskbit[i]);
+			iowrite32(temp, gpio_data->chip_wakeup_register[i]);
+		}
+	}
 exit:
 	return ret;
 }
@@ -178,6 +195,7 @@ static int msm_cdc_pinctrl_probe(struct platform_device *pdev)
 	int ret = 0;
 	struct msm_cdc_pinctrl_info *gpio_data;
 	u32 tlmm_gpio[MAX_GPIOS] = {0};
+	u32 chip_wakeup_reg[MAX_GPIOS] = {0};
 	u32 i = 0;
 	int count = 0;
 
@@ -223,6 +241,27 @@ static int msm_cdc_pinctrl_probe(struct platform_device *pdev)
 	}
 
 
+	count = of_property_count_u32_elems(pdev->dev.of_node, "qcom,chip-wakeup-reg");
+	if (count <= 0)
+		goto cdc_tlmm_gpio;
+	if (!of_property_read_u32_array(pdev->dev.of_node, "qcom,chip-wakeup-reg",
+				chip_wakeup_reg, count)) {
+		if (of_property_read_u32_array(pdev->dev.of_node,
+					   "qcom,chip-wakeup-maskbit",
+					   gpio_data->chip_wakeup_maskbit, count)) {
+			dev_err(&pdev->dev,
+				"chip-wakeup-maskbit needed if chip-wakeup-reg is defined!\n");
+			goto cdc_tlmm_gpio;
+		}
+		gpio_data->chip_wakeup_reg = true;
+		for (i = 0; i < count; i++) {
+			gpio_data->chip_wakeup_register[i] =
+				devm_ioremap(&pdev->dev, chip_wakeup_reg[i], 0x4);
+		}
+		gpio_data->wakeup_reg_count = count;
+	}
+
+cdc_tlmm_gpio:
 	count = of_property_count_u32_elems(pdev->dev.of_node, "qcom,tlmm-gpio");
 	if (count <= 0)
 		goto cdc_rst;