Selaa lähdekoodia

Merge branch 'clo/driver/br_android_ncihalx_comm_14' into nfc-driver.lnx.14.0

* clo/driver/br_android_ncihalx_comm_14:
  Updated corresponding to - GITHUB_CODE_DROP
  Updated corresponding to - NFC_AR_00_1E800_14.02.00_OpnSrc
  Updated corresponding to - NFC_AR_00_1E800_13.0B.00_OpnSrc
  Updated corresponding to - NFC_AR_00_1E800_13.09.00_OpnSrc

Change-Id: Idd8d27502306f8ca55b290839f7e36292201ff24
Khageswararao Rao B 2 vuotta sitten
vanhempi
sitoutus
4e09540972
2 muutettua tiedostoa jossa 83 lisäystä ja 31 poistoa
  1. 72 27
      nfc/common.c
  2. 11 4
      nfc/common.h

+ 72 - 27
nfc/common.c

@@ -1,6 +1,6 @@
 /******************************************************************************
  * Copyright (C) 2015, The Linux Foundation. All rights reserved.
- * Copyright (C) 2019-2021 NXP
+ * Copyright (C) 2019-2022 NXP
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -50,22 +50,22 @@ int nfc_parse_dt(struct device *dev, struct platform_configs *nfc_configs,
 	if (interface == PLATFORM_IF_I2C) {
 		nfc_gpio->irq = of_get_named_gpio(np, DTS_IRQ_GPIO_STR, 0);
 		if ((!gpio_is_valid(nfc_gpio->irq))) {
-			pr_err("%s: nfc irq gpio invalid %d\n", __func__,
+			pr_err("%s: irq gpio invalid %d\n", __func__,
 			       nfc_gpio->irq);
-			return -EINVAL;
+			return nfc_gpio->irq;
 		}
 		pr_info("%s: irq %d\n", __func__, nfc_gpio->irq);
 	}
 	nfc_gpio->ven = of_get_named_gpio(np, DTS_VEN_GPIO_STR, 0);
 	if ((!gpio_is_valid(nfc_gpio->ven))) {
-		pr_err("%s: nfc ven gpio invalid %d\n", __func__, nfc_gpio->ven);
-		return -EINVAL;
+		pr_err("%s: ven gpio invalid %d\n", __func__, nfc_gpio->ven);
+		return nfc_gpio->ven;
 	}
 	/* some products like sn220 does not required fw dwl pin */
 	nfc_gpio->dwl_req = of_get_named_gpio(np, DTS_FWDN_GPIO_STR, 0);
-	/* not returning failure for dwl gpio as it is optional for sn220 */
-	if ((!gpio_is_valid(nfc_gpio->dwl_req))){
-		pr_warn("%s: nfc dwl_req gpio invalid %d\n", __func__,
+        /* not returning failure for dwl gpio as it is optional for sn220 */
+	if ((!gpio_is_valid(nfc_gpio->dwl_req))) {
+		pr_warn("%s: dwl_req gpio invalid %d\n", __func__,
 			nfc_gpio->dwl_req);
         }
         /* Read clkreq GPIO pin number from DTSI */
@@ -166,8 +166,7 @@ int configure_gpio(unsigned int gpio, int flag)
 		}
 
 		if (ret) {
-			pr_err("%s: unable to set direction for nfc gpio [%d]\n",
-			       __func__, gpio);
+			pr_err("%s: unable to set direction for nfc gpio [%d]\n", __func__, gpio);
 			gpio_free(gpio);
 			return ret;
 		}
@@ -279,6 +278,46 @@ int nfc_misc_register(struct nfc_dev *nfc_dev,
 	return 0;
 }
 
+/**
+ * nfc_gpio_info() - gets the status of nfc gpio pins and encodes into a byte.
+ * @nfc_dev:	nfc device data structure
+ * @arg:		userspace buffer
+ *
+ * Encoding can be done in following manner
+ * 1) map the gpio value into INVALID(-2), SET(1), RESET(0).
+ * 2) mask the first 2 bits of gpio.
+ * 3) left shift the 2 bits as multiple of 2.
+ * 4) multiply factor can be defined as position of gpio pin in struct platform_gpio
+ *
+ * Return: -EFAULT, if unable to copy the data from kernel space to userspace, 0
+ * if Success(or no issue)
+ */
+
+static int nfc_gpio_info(struct nfc_dev *nfc_dev, unsigned long arg)
+{
+	unsigned int gpios_status = 0;
+	int value = 0;
+	int gpio_no = 0;
+	int i;
+	int ret = 0;
+	struct platform_gpio *nfc_gpio = &nfc_dev->configs.gpio;
+
+	for (i = 0; i < sizeof(struct platform_gpio) / sizeof(unsigned int);
+	     i++) {
+		gpio_no = *((unsigned int *)nfc_gpio + i);
+		value = get_valid_gpio(gpio_no);
+		if (value < 0)
+			value = -2;
+		gpios_status |= (value & GPIO_STATUS_MASK_BITS)<<(GPIO_POS_SHIFT_VAL*i);
+	}
+	ret = copy_to_user((uint32_t *) arg, &gpios_status, sizeof(value));
+	if (ret < 0) {
+		pr_err("%s : Unable to copy data from kernel space to user space", __func__);
+		return -EFAULT;
+	}
+	return 0;
+}
+
 /**
  * nfc_ioctl_power_states() - power control
  * @nfc_dev:    nfc device data structure
@@ -305,12 +344,14 @@ static int nfc_ioctl_power_states(struct nfc_dev *nfc_dev, unsigned long arg)
 		set_valid_gpio(nfc_gpio->dwl_req, 0);
 		gpio_set_ven(nfc_dev, 0);
 		nfc_dev->nfc_ven_enabled = false;
+		nfc_dev->nfc_state = NFC_STATE_NCI;
 	} else if (arg == NFC_POWER_ON) {
 		nfc_dev->nfc_enable_intr(nfc_dev);
 		set_valid_gpio(nfc_gpio->dwl_req, 0);
 
 		gpio_set_ven(nfc_dev, 1);
 		nfc_dev->nfc_ven_enabled = true;
+		nfc_dev->nfc_state = NFC_STATE_NCI;
 	} else if (arg == NFC_FW_DWL_VEN_TOGGLE) {
 		/*
 		 * We are switching to download Mode, toggle the enable pin
@@ -353,8 +394,8 @@ static int nfc_ioctl_power_states(struct nfc_dev *nfc_dev, unsigned long arg)
 	} else if (arg == NFC_DISABLE) {
 		/* Setting flag true when NFC is disabled */
 		nfc_dev->cold_reset.is_nfc_enabled = false;
-	}  else {
-		pr_err("%s bad arg %lu\n", __func__, arg);
+	} else {
+		pr_err("%s: bad arg %lu\n", __func__, arg);
 		ret = -ENOIOCTLCMD;
 	}
 	return ret;
@@ -375,10 +416,11 @@ static int nfc_ioctl_power_states(struct nfc_dev *nfc_dev, unsigned long arg)
  * and error ret code otherwise
  */
 long nfc_dev_compat_ioctl(struct file *pfile, unsigned int cmd,
-		      unsigned long arg)
+			  unsigned long arg)
 {
 	int ret = 0;
-	arg = (compat_u64)arg;
+
+	arg = (compat_u64) arg;
 	pr_debug("%s: cmd = %x arg = %zx\n", __func__, cmd, arg);
 	ret = nfc_dev_ioctl(pfile, cmd, arg);
 	return ret;
@@ -622,25 +664,26 @@ long nfc_dev_ioctl(struct file *pfile, unsigned int cmd, unsigned long arg)
 	case NFC_SET_PWR:
 		ret = nfc_ioctl_power_states(nfc_dev, arg);
 		break;
-        case NFC_SET_RESET_READ_PENDING:
-               if (arg == NFC_SET_READ_PENDING) {
-                       nfc_dev->cold_reset.is_nfc_read_pending = true;
-                        /* Set default NFC state as NCI for Nfc read pending request */
-                       nfc_dev->nfc_state = NFC_STATE_NCI;
-               }
-               else if (arg == NFC_RESET_READ_PENDING){
-                       nfc_dev->cold_reset.is_nfc_read_pending = false;
-               }
-               else {
-                       ret = -EINVAL;
-               }
-               break;
+	case NFC_SET_RESET_READ_PENDING:
+		if (arg == NFC_SET_READ_PENDING) {
+			nfc_dev->cold_reset.is_nfc_read_pending = true;
+			/* Set default NFC state as NCI for Nfc read pending request */
+			nfc_dev->nfc_state = NFC_STATE_NCI;
+		} else if (arg == NFC_RESET_READ_PENDING) {
+			nfc_dev->cold_reset.is_nfc_read_pending = false;
+		} else {
+			ret = -EINVAL;
+		}
+		break;
 	case ESE_SET_PWR:
 		ret = nfc_ese_pwr(nfc_dev, arg);
 		break;
 	case ESE_GET_PWR:
 		ret = nfc_ese_pwr(nfc_dev, ESE_POWER_STATE);
 		break;
+	case NFC_GET_GPIO_STATUS:
+		ret = nfc_gpio_info(nfc_dev, arg);
+		break;
 	case NFCC_GET_INFO:
 		ret = nfc_ioctl_nfcc_info(pfile, arg);
 		break;
@@ -663,6 +706,7 @@ long nfc_dev_ioctl(struct file *pfile, unsigned int cmd, unsigned long arg)
 int nfc_dev_open(struct inode *inode, struct file *filp)
 {
 	struct nfc_dev *nfc_dev = NULL;
+
 	nfc_dev = container_of(inode->i_cdev, struct nfc_dev, c_dev);
 
 	if (!nfc_dev)
@@ -719,6 +763,7 @@ int nfc_dev_flush(struct file *pfile, fl_owner_t id)
 int nfc_dev_close(struct inode *inode, struct file *filp)
 {
 	struct nfc_dev *nfc_dev = NULL;
+
 	nfc_dev = container_of(inode->i_cdev, struct nfc_dev, c_dev);
 
 	if (!nfc_dev)

+ 11 - 4
nfc/common.h

@@ -79,13 +79,14 @@
 #define MAX_DL_BUFFER_SIZE		(DL_HDR_LEN + DL_CRC_LEN + \
 					MAX_DL_PAYLOAD_LEN)
 
+
 /* Retry count for normal write */
 #define NO_RETRY			(1)
 /* Maximum retry count for standby writes */
 #define MAX_RETRY_COUNT			(3)
 #define MAX_WRITE_IRQ_COUNT		(5)
 #define MAX_IRQ_WAIT_TIME		(90)
-#define WAKEUP_SRC_TIMEOUT		(2000)
+#define WAKEUP_SRC_TIMEOUT		(100)
 
 /* command response timeout */
 #define NCI_CMD_RSP_TIMEOUT_MS		(2000)
@@ -104,6 +105,7 @@
 #define ESE_SET_PWR                   _IOW(NFC_MAGIC, 0x02, uint32_t)
 #define ESE_GET_PWR                   _IOR(NFC_MAGIC, 0x03, uint32_t)
 #define NFC_SET_RESET_READ_PENDING    _IOW(NFC_MAGIC, 0x04, uint32_t)
+#define NFC_GET_GPIO_STATUS	      _IOR(NFC_MAGIC, 0x05, uint32_t)
 #define NFC_SECURE_ZONE               _IOW(NFC_MAGIC, 0x0A, uint32_t)
 
 #define DTS_IRQ_GPIO_STR	"qcom,sn-irq"
@@ -121,6 +123,11 @@
 #define NFC_VDDIO_MAX		1950000 //in uV
 #define NFC_CURRENT_MAX		157000 //in uA
 
+/* Each GPIO occupies consecutive two bits */
+#define GPIO_POS_SHIFT_VAL 2
+/* Two bits to indicate GPIO status (Invalid(-2), Set(1) or Reset(0)) */
+#define GPIO_STATUS_MASK_BITS 3
+
 //NFC ID for registration with secure libraries
 #define HW_STATE_UID		0x108
 #define HW_OP_GET_STATE		1
@@ -178,8 +185,8 @@ enum nfcc_ioctl_request {
 };
 
 enum nfc_read_pending {
-       NFC_RESET_READ_PENDING,
-       NFC_SET_READ_PENDING,
+	NFC_RESET_READ_PENDING,
+	NFC_SET_READ_PENDING,
 };
 
 /* nfc platform interface type */
@@ -295,7 +302,7 @@ int nfc_dev_open(struct inode *inode, struct file *filp);
 int nfc_dev_flush(struct file *pfile, fl_owner_t id);
 int nfc_dev_close(struct inode *inode, struct file *filp);
 long nfc_dev_compat_ioctl(struct file *pfile, unsigned int cmd,
-		      unsigned long arg);
+			  unsigned long arg);
 long nfc_dev_ioctl(struct file *pfile, unsigned int cmd, unsigned long arg);
 int nfc_parse_dt(struct device *dev, struct platform_configs *nfc_configs,
 		 uint8_t interface);