Sfoglia il codice sorgente

NFC: driver: Add SW WAR to enable and disable NFC clock

Added SW WAR to enable NFC clock at NFC ON and disable
NFC clock at NFC OFF.

Change-Id: I74fd9fa58f9875e91807c4f06735b2c62867aaf7
Signed-off-by: Khageswararao Rao B <[email protected]>
Khageswararao Rao B 1 anno fa
parent
commit
1680e1885f
6 ha cambiato i file con 103 aggiunte e 29 eliminazioni
  1. 2 0
      BUILD.bazel
  2. 40 21
      nfc/common.c
  3. 11 1
      nfc/common.h
  4. 41 1
      nfc/common_qcom.c
  5. 7 4
      nfc/i2c_drv.c
  6. 2 2
      nfc_kernel_dlkm_vendor_board.mk

+ 2 - 0
BUILD.bazel

@@ -7,3 +7,5 @@ define_modules("pineapple", "gki")
 define_modules("blair", "consolidate")
 define_modules("blair", "gki")
 
+define_modules("pitti", "consolidate")
+define_modules("pitti", "gki")

+ 40 - 21
nfc/common.c

@@ -18,7 +18,7 @@
  *
  ******************************************************************************/
 /*
- * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
  *
  *****************************************************************************/
 #include <linux/gpio.h>
@@ -69,12 +69,16 @@ int nfc_parse_dt(struct device *dev, struct platform_configs *nfc_configs,
 		pr_warn("NxpDrv: %s: dwl_req gpio invalid %d\n", __func__,
 			nfc_gpio->dwl_req);
         }
-        /* Read clkreq GPIO pin number from DTSI */
-	nfc_gpio->clkreq = of_get_named_gpio(np, DTS_CLKREQ_GPIO_STR, 0);
-	if (!gpio_is_valid(nfc_gpio->clkreq)) {
-		   dev_err(dev, "NxpDrv: clkreq gpio invalid %d\n", nfc_gpio->clkreq);
-		   return -EINVAL;
-        }
+	/* Read clock request gpio configuration if MGPIO configurations are not preasent */
+	if (of_property_read_string(np, DTS_CLKSRC_GPIO_STR, &nfc_configs->clk_src_name)) {
+		nfc_configs->clk_pin_voting = false;
+		nfc_gpio->clkreq = of_get_named_gpio(np, DTS_CLKREQ_GPIO_STR, 0);
+		if (!gpio_is_valid(nfc_gpio->clkreq)) {
+			dev_err(dev, "NxpDrv: clkreq gpio invalid %d\n", nfc_gpio->clkreq);
+			return -EINVAL;
+		}
+	} else
+		nfc_configs->clk_pin_voting = true;
 
 #ifdef NFC_SECURE_PERIPHERAL_ENABLED
 	/* Read DTS_SZONE_STR to check secure zone support */
@@ -403,9 +407,21 @@ static int nfc_ioctl_power_states(struct nfc_dev *nfc_dev, unsigned long arg)
 		nfc_dev->nfc_state = NFC_STATE_NCI;
 
 	} else if (arg == NFC_ENABLE) {
+		if (nfc_dev->configs.clk_pin_voting) {
+			/* Enabling nfc clock */
+			ret = nfc_clock_select(nfc_dev);
+			if (ret)
+				pr_err("%s unable to select clock\n", __func__);
+		}
 		/* Setting flag true when NFC is enabled */
 		nfc_dev->cold_reset.is_nfc_enabled = true;
 	} else if (arg == NFC_DISABLE) {
+		if (nfc_dev->configs.clk_pin_voting) {
+			/* Disabling nfc clock */
+			ret = nfc_clock_deselect(nfc_dev);
+			if (ret)
+				pr_err("%s unable to disable clock\n", __func__);
+		}
 		/* Setting flag true when NFC is disabled */
 		nfc_dev->cold_reset.is_nfc_enabled = false;
 	} else {
@@ -478,20 +494,23 @@ int nfc_post_init(struct nfc_dev *nfc_dev)
 			__func__, nfc_gpio->dwl_req);
 	}
 
-        /* Read clkreq GPIO number from device tree*/
-        ret = of_property_read_u32_index(nfc_dev->i2c_dev.client->dev.of_node, DTS_CLKREQ_GPIO_STR, 1, &clkreq_gpio);
-        if (ret < 0) {
-            pr_err("NxpDrv: %s Failed to read clkreq gipo number, ret: %d\n", __func__, ret);
-            return ret;
-        }
-        /* configure clkreq GPIO as wakeup capable */
-        ret = msm_gpio_mpm_wake_set(clkreq_gpio, true);
-        if (ret < 0) {
-            pr_err("NxpDrv: %s Failed to setup clkreq gpio %d as wakeup capable, ret: %d\n", __func__, clkreq_gpio , ret);
-            return ret;
-        } else {
-                pr_info("NxpDrv: %s clkreq gpio %d successfully setup for wakeup capable\n", __func__, clkreq_gpio);
-        }
+	if (!(nfc_configs.clk_pin_voting)) {
+		/* Read clkreq GPIO number from device tree*/
+		ret = of_property_read_u32_index(nfc_dev->i2c_dev.client->dev.of_node,
+						DTS_CLKREQ_GPIO_STR, 1, &clkreq_gpio);
+		if (ret < 0) {
+			pr_err("NxpDrv: %s Failed to read clkreq gipo number, ret: %d\n",
+				 __func__, ret);
+			return ret;
+		}
+		/* configure clkreq GPIO as wakeup capable */
+		ret = msm_gpio_mpm_wake_set(clkreq_gpio, true);
+		if (ret < 0) {
+			pr_err("NxpDrv: %s clkreq gpio %d as wakeup capable failed, ret: %d\n",
+				 __func__, clkreq_gpio, ret);
+			return ret;
+		}
+	}
 
 	ret = nfcc_hw_check(nfc_dev);
 	if (ret || nfc_dev->nfc_state == NFC_STATE_UNKNOWN) {

+ 11 - 1
nfc/common.h

@@ -18,7 +18,7 @@
  *
  ******************************************************************************/
 /*
- * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
  *****************************************************************************/
 #ifndef _COMMON_H_
 #define _COMMON_H_
@@ -102,6 +102,7 @@
 #define DTS_VEN_GPIO_STR	"qcom,sn-ven"
 #define DTS_FWDN_GPIO_STR	"qcom,sn-firm"
 #define DTS_CLKREQ_GPIO_STR     "qcom,sn-clkreq"
+#define DTS_CLKSRC_GPIO_STR	"qcom,clk-src"
 #define DTS_SZONE_STR	        "qcom,sn-szone"
 #define NFC_LDO_SUPPLY_DT_NAME		"qcom,sn-vdd-1p8"
 #define NFC_LDO_SUPPLY_NAME		"qcom,sn-vdd-1p8-supply"
@@ -237,6 +238,9 @@ struct platform_ldo {
 struct platform_configs {
 	struct platform_gpio gpio;
 	struct platform_ldo ldo;
+	const char *clk_src_name;
+	/* NFC_CLK pin voting state */
+	bool clk_pin_voting;
 	const char *szone;
 #ifdef NFC_SECURE_PERIPHERAL_ENABLED
 	bool CNSS_NFC_HW_SECURE_ENABLE;
@@ -283,6 +287,10 @@ struct nfc_dev {
 	/*secure zone state*/
 	bool secure_zone;
 
+	/* CLK control */
+	bool clk_run;
+	struct clk *s_clk;
+
 	void *ipcl;
 
 	/* function pointers for the common i2c functionality */
@@ -318,6 +326,8 @@ int nfc_ese_pwr(struct nfc_dev *nfc_dev, unsigned long arg);
 int nfc_ldo_unvote(struct nfc_dev *nfc_dev);
 int is_nfc_data_available_for_read(struct nfc_dev *nfc_dev);
 int validate_nfc_state_nci(struct nfc_dev *nfc_dev);
+int nfc_clock_select(struct nfc_dev *nfc_dev);
+int nfc_clock_deselect(struct nfc_dev *nfc_dev);
 int nfc_post_init(struct nfc_dev *nfc_dev);
 int nfc_dynamic_protection_ioctl(struct nfc_dev *nfc_dev, unsigned long sec_zone_trans);
 bool nfc_hw_secure_check(void);

+ 41 - 1
nfc/common_qcom.c

@@ -4,7 +4,7 @@
  *
  ***************************************************************************/
 /*
- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
  *
  ***************************************************************************/
 
@@ -162,3 +162,43 @@ int nfc_ldo_unvote(struct nfc_dev *nfc_dev)
 	return ret;
 }
 
+/*
+ * Routine to enable clock.
+ * this routine can be extended to select from multiple
+ * sources based on clk name.
+ */
+int nfc_clock_select(struct nfc_dev *nfc_dev)
+{
+	int r = 0;
+
+	nfc_dev->s_clk = clk_get(&nfc_dev->i2c_dev.client->dev, "nfc_ref_clk");
+
+	if (IS_ERR(nfc_dev->s_clk))
+		return PTR_ERR(nfc_dev->s_clk);
+
+	if (!nfc_dev->clk_run)
+		r = clk_prepare_enable(nfc_dev->s_clk);
+
+	if (r)
+		return r;
+
+	nfc_dev->clk_run = true;
+	return r;
+}
+
+/*
+ * Routine to disable clocks
+ */
+int nfc_clock_deselect(struct nfc_dev *nfc_dev)
+{
+	int r = -EINVAL;
+
+	if (nfc_dev->s_clk != NULL) {
+		if (nfc_dev->clk_run) {
+			clk_disable_unprepare(nfc_dev->s_clk);
+			nfc_dev->clk_run = false;
+		}
+		return 0;
+	}
+	return r;
+}

+ 7 - 4
nfc/i2c_drv.c

@@ -30,12 +30,9 @@
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  ****************************************************************************/
 /*
- * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
  *
  ****************************************************************************/
 
@@ -435,6 +432,12 @@ int nfc_i2c_dev_probe(struct i2c_client *client, const struct i2c_device_id *id)
 	nfc_dev->secure_zone = false;
 	nfc_post_init(nfc_dev);
 #endif
+
+	if (nfc_dev->configs.clk_pin_voting)
+		nfc_dev->clk_run = false;
+	else
+		nfc_dev->clk_run = true;
+
 	device_init_wakeup(&client->dev, true);
 	i2c_set_clientdata(client, nfc_dev);
 	i2c_dev->irq_wake_up = false;

+ 2 - 2
nfc_kernel_dlkm_vendor_board.mk

@@ -12,11 +12,11 @@ endif
 
 ########## Build kernel module based on local DLKM flag status ##########
 ifeq ($(NFC_DLKM_ENABLED), true)
-ifeq ($(call is-board-platform-in-list, pineapple blair),true)
+ifeq ($(call is-board-platform-in-list, pineapple blair pitti),true)
   BOARD_VENDOR_KERNEL_MODULES += $(KERNEL_MODULES_OUT)/nxp-nci.ko
 endif
 endif
 
-ifeq ($(call is-board-platform-in-list, blair),true)
+ifeq ($(call is-board-platform-in-list, blair pitti),true)
 TARGET_ENABLE_PERIPHERAL_CONTROL := false
 endif