Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 92d40d99 authored by Karthik Poosa's avatar Karthik Poosa Committed by Gerrit - the friendly Code Review server
Browse files

NFC: Add driver to configure NFC-I3C controller GPIOs



Add driver to toggle NFC GPIOs for I3C enumeration to
pass for NFC controller.

Change-Id: I3eef5b8a327c2c70355c03574b06bf67e26b4419
Signed-off-by: default avatarKarthik Poosa <kpoosa2@codeaurora.org>
parent 535241a5
Loading
Loading
Loading
Loading
+10 −1
Original line number Diff line number Diff line
@@ -71,9 +71,18 @@ config NFC_QTI_I2C

	  If unsure, say N.

config NFC_QTI_I3C_GPIO
	tristate "QTI Driver to configure NFC GPIOs for SNxxx I3C modules"
	help
	  This enables the QTI driver for SNxxx I3C based devices.
	  NFC Enable GPIO(NFC_EN) should toggle before I3C enumeration so that NFC
	  controller gets recognized.

	  If unsure, say N.

config NFC_QTI_I3C
	tristate "QTI NCI based NFC I3C Slave Driver for SNxxx"
	depends on I3C
	depends on I3C && NFC_QTI_I3C_GPIO
	help
	  This enables the NFC driver for SNxxx based devices.
	  This is for I3C connected version. NCI protocol logic
+2 −0
Original line number Diff line number Diff line
@@ -8,3 +8,5 @@ nfc_i2c-objs:= nfc_common.o nfc_i2c_drv.o

obj-$(CONFIG_NFC_QTI_I3C)	+= nfc_i3c.o
nfc_i3c-objs:= nfc_common.o nfc_i3c_drv.o

obj-$(CONFIG_NFC_QTI_I3C_GPIO)	+= nfc_i3c_gpio_cfg.o
+102 −0
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2020, The Linux Foundation. All rights reserved.
 */

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of_gpio.h>
#include <linux/of_device.h>
#include <linux/delay.h>

/* NFC I3C DT node name */
#define NFC_I3C_DT_NODE_STR	"sn"

/* NFC GPIO names in the I3C slave node */
#define DTS_VEN_GPIO_STR	"qcom,sn-ven"
#define DTS_FWDN_GPIO_STR	"qcom,sn-firm"

static int __init nfc_i3c_gpio_cfg_init(void)
{
	int ret = 0;
	int ven_gpio = 0, firm_gpio = 0;
	struct device_node *np = NULL;

	pr_debug("%s\n", __func__);

	np = of_find_node_by_name(NULL, NFC_I3C_DT_NODE_STR);
	if (!np) {
		pr_err("finding NFC I3C slave node failed\n");
		return -ENODEV;
	}

	ven_gpio = of_get_named_gpio(np, DTS_VEN_GPIO_STR, 0);
	pr_debug("NFC VEN %d\n", ven_gpio);

	if ((!gpio_is_valid(ven_gpio))) {
		pr_err("invalid ven gpio %d from dt\n", ven_gpio);
		return -EINVAL;
	}

	firm_gpio = of_get_named_gpio(np, DTS_FWDN_GPIO_STR, 0);
	pr_debug("NFC FIRM GPIO %d\n", firm_gpio);

	if ((!gpio_is_valid(firm_gpio))) {
		pr_err("invalid firm gpio %d from dt\n", firm_gpio);
		return -EINVAL;
	}

	ret = gpio_request(firm_gpio, "nfc_fw_gpio");
	if (ret) {
		pr_err("NFC firm gpio request failed ret %d\n", ret);
		return -EIO;
	}

	ret = gpio_direction_output(firm_gpio, 0);
	if (ret) {
		pr_err("NFC firm gpio direction set failed ret %d\n", ret);
		gpio_free(firm_gpio);
		return -EIO;
	}

	usleep_range(10000, 10100);
	pr_debug("NFC firm gpio %d\n", gpio_get_value(firm_gpio));

	ret = gpio_request(ven_gpio, "nfc_reset_gpio");
	if (ret) {
		pr_err("nfc ven gpio req failed ret %d\n", ret);
		gpio_set_value(firm_gpio, 0);
		gpio_free(firm_gpio);
		return -EIO;
	}

	ret = gpio_direction_output(ven_gpio, 0);
	if (ret) {
		pr_err("ven direction set failed ret %d\n", ret);
		gpio_set_value(firm_gpio, 0);
		gpio_free(firm_gpio);
		gpio_free(ven_gpio);
		return -EIO;
	}

	pr_debug("VEN GPIO level %d\n", gpio_get_value(ven_gpio));
	usleep_range(10000, 10100);
	gpio_set_value(ven_gpio, 1);
	pr_debug("VEN GPIO level %d\n", gpio_get_value(ven_gpio));

	gpio_free(ven_gpio);
	gpio_free(firm_gpio);
	return ret;
}

module_init(nfc_i3c_gpio_cfg_init);

static void __exit nfc_i3c_gpio_cfg_exit(void)
{
	pr_debug("Unloading I3C NFC GPIO Config driver\n");
}

module_exit(nfc_i3c_gpio_cfg_exit);

MODULE_DESCRIPTION("QTI NFC I3C GPIO Config driver");
MODULE_LICENSE("GPL v2");