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

Commit 1f37c7cc authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "NFC: Add NFC hardware check and get info ioctl"

parents 137a997b eb81b68b
Loading
Loading
Loading
Loading
+276 −9
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2015-2019, The Linux Foundation. All rights reserved.
 * Copyright (c) 2015-2020, The Linux Foundation. All rights reserved.
 */

#include <linux/of_gpio.h>
@@ -8,6 +8,25 @@
#include <linux/delay.h>
#include "nfc_common.h"

int nfc_read(struct nfc_dev *nfc_dev, char *buf, size_t count)
{
	if (nfc_dev->interface == PLATFORM_IF_I2C)
		return i2c_read(&nfc_dev->i2c_dev, buf, count);
	else
		return i3c_nci_kbuf_retrieve(&nfc_dev->i3c_dev, buf, count);
}
EXPORT_SYMBOL(nfc_read);

int nfc_write(struct nfc_dev *nfc_dev, char *buf, size_t count,
					uint8_t retry_cnt)
{
	if (nfc_dev->interface == PLATFORM_IF_I2C)
		return i2c_write(&nfc_dev->i2c_dev, buf, count, retry_cnt);
	else
		return i3c_write(&nfc_dev->i3c_dev, buf, count, retry_cnt);
}
EXPORT_SYMBOL(nfc_write);

int nfc_parse_dt(struct device *dev, struct platform_gpio *nfc_gpio,
		 uint8_t interface)
{
@@ -214,13 +233,8 @@ static int send_cold_reset_cmd(struct nfc_dev *nfc_dev)
	cold_reset_cmd[1] = COLD_RESET_OID;
	cold_reset_cmd[2] = COLD_RESET_CMD_PAYLOAD_LEN;

	if (nfc_dev->interface == PLATFORM_IF_I2C)
		ret = i2c_write(&nfc_dev->i2c_dev, cold_reset_cmd,
			      COLD_RESET_CMD_LEN, MAX_RETRY_COUNT);
	else
		ret = i3c_write(&nfc_dev->i3c_dev, cold_reset_cmd,
	ret = nfc_write(nfc_dev, cold_reset_cmd,
					COLD_RESET_CMD_LEN, MAX_RETRY_COUNT);

	if (ret <= 0)
		pr_err("%s: write failed after max retry, ret %d\n",
			__func__, ret);
@@ -259,6 +273,7 @@ void read_cold_reset_rsp(struct nfc_dev *nfc_dev, char *header)
		/* For I3C driver, header is read by the worker thread */
		memcpy(cold_reset_rsp, header, NCI_HDR_LEN);
	}

	if ((cold_reset_rsp[0] != COLD_RESET_RSP_GID)
	    || (cold_reset_rsp[1] != COLD_RESET_OID)) {
		pr_err("%s: - invalid response GID or OID for cold_reset\n",
@@ -271,6 +286,7 @@ void read_cold_reset_rsp(struct nfc_dev *nfc_dev, char *header)
		ret = -EINVAL;
		goto error;
	}

	if (nfc_dev->interface == PLATFORM_IF_I2C)
		ret = i2c_read(&nfc_dev->i2c_dev,
			     &cold_reset_rsp[NCI_PAYLOAD_IDX],
@@ -438,6 +454,7 @@ static int nfc_ioctl_power_states(struct nfc_dev *nfc_dev, unsigned long arg)
		 */

		gpio_set_ven(nfc_dev, 1);

		if (gpio_is_valid(nfc_dev->gpio.dwl_req)) {
			gpio_set_value(nfc_dev->gpio.dwl_req, 1);
			usleep_range(10000, 10100);
@@ -503,6 +520,24 @@ static int nfc_ioctl_power_states(struct nfc_dev *nfc_dev, unsigned long arg)
	return ret;
}

/*
 * Inside nfc_ioctl_nfcc_info
 *
 * @brief   nfc_ioctl_nfcc_info
 *
 * Check the NFC Chipset and firmware version details
 */
unsigned int nfc_ioctl_nfcc_info(struct file *filp, unsigned long arg)
{
	unsigned int r = 0;
	struct nfc_dev *nfc_dev = filp->private_data;

	r = nfc_dev->nqx_info.i;
	pr_debug("nfc : %s r = %d\n", __func__, r);

	return r;
}

/** @brief   IOCTL function  to be used to set or get data from upper layer.
 *
 *  @param   pfile  fil node for opened device.
@@ -531,6 +566,9 @@ long nfc_dev_ioctl(struct file *pfile, unsigned int cmd, unsigned long arg)
	case ESE_GET_PWR:
		ret = nfc_ese_pwr(nfc_dev, ESE_POWER_STATE);
		break;
	case NFCC_GET_INFO:
		ret = nfc_ioctl_nfcc_info(pfile, arg);
		break;
	default:
		pr_err("%s bad cmd %lu\n", __func__, arg);
		ret = -ENOIOCTLCMD;
@@ -600,3 +638,232 @@ int nfc_dev_close(struct inode *inode, struct file *filp)
	return 0;
}
EXPORT_SYMBOL(nfc_dev_close);

int is_data_available_for_read(struct nfc_dev *nfc_dev)
{
	int ret;

	enable_interrupt(nfc_dev);

	ret = wait_event_interruptible_timeout(nfc_dev->read_wq,
			!nfc_dev->i2c_dev.irq_enabled,
			msecs_to_jiffies(MAX_IRQ_WAIT_TIME));
	return ret;
}

/* Check for availability of NFC controller hardware */
int nfcc_hw_check(struct nfc_dev *nfc_dev)
{
	int ret = 0;
	unsigned char reset_ntf_len = 0;
	char *nci_reset_cmd = NULL;
	char *nci_reset_rsp = NULL;
	char *nci_reset_ntf = NULL;
	char *nci_get_version_cmd = NULL;
	char *nci_get_version_rsp = NULL;

	nci_reset_cmd = kzalloc(NCI_RESET_CMD_LEN + 1, GFP_DMA | GFP_KERNEL);
	if (!nci_reset_cmd)
		return -ENOMEM;

	nci_reset_rsp = kzalloc(NCI_RESET_RSP_LEN + 1,  GFP_DMA | GFP_KERNEL);
	if (!nci_reset_rsp) {
		ret = -ENOMEM;
		goto done;
	}

	nci_reset_ntf = kzalloc(NCI_RESET_NTF_LEN + 1,  GFP_DMA | GFP_KERNEL);
	if (!nci_reset_ntf) {
		ret = -ENOMEM;
		goto done;
	}

	nci_get_version_cmd = kzalloc(NCI_GET_VERSION_CMD_LEN + 1,
					GFP_DMA | GFP_KERNEL);
	if (!nci_get_version_cmd) {
		ret = -ENOMEM;
		goto done;
	}

	nci_get_version_rsp = kzalloc(NCI_GET_VERSION_RSP_LEN + 1,
					GFP_DMA | GFP_KERNEL);
	if (!nci_get_version_rsp) {
		ret = -ENOMEM;
		goto done;
	}

	if (nfc_dev->interface == PLATFORM_IF_I3C)
		enable_interrupt(nfc_dev);
	else {
		/* making sure that the NFCC starts in a clean state. */
		gpio_set_ven(nfc_dev, 1);/* HPD : Enable*/
		gpio_set_ven(nfc_dev, 0);/* ULPM: Disable */
		gpio_set_ven(nfc_dev, 1);/* HPD : Enable*/
	}

	nci_reset_cmd[0] = 0x20;
	nci_reset_cmd[1] = 0x00;
	nci_reset_cmd[2] = 0x01;
	nci_reset_cmd[3] = 0x00;

	/* send NCI CORE RESET CMD with Keep Config parameters */
	ret = nfc_write(nfc_dev, nci_reset_cmd, NCI_RESET_CMD_LEN,
				MAX_RETRY_COUNT);
	if (ret <= 0) {
		pr_err("%s: - nfc core reset error\n", __func__);

		if (gpio_is_valid(nfc_dev->gpio.dwl_req)) {
			gpio_set_value(nfc_dev->gpio.dwl_req, 1);
			usleep_range(10000, 10100);
		}

		if (nfc_dev->interface == PLATFORM_IF_I2C) {
			gpio_set_ven(nfc_dev, 0);
			gpio_set_ven(nfc_dev, 1);
		}

		nci_get_version_cmd[0] = 0x00;
		nci_get_version_cmd[1] = 0x04;
		nci_get_version_cmd[2] = 0xF1;
		nci_get_version_cmd[3] = 0x00;
		nci_get_version_cmd[4] = 0x00;
		nci_get_version_cmd[5] = 0x00;
		nci_get_version_cmd[6] = 0x6E;
		nci_get_version_cmd[7] = 0xEF;

		ret = nfc_write(nfc_dev, nci_get_version_cmd,
				NCI_GET_VERSION_CMD_LEN, MAX_RETRY_COUNT);
		if (ret <= 0) {
			pr_err("%s: - nfc get version cmd error ret %d\n",
					__func__, ret);
			goto err_nfcc_hw_check;
		}

		if (nfc_dev->interface == PLATFORM_IF_I2C) {
			ret = is_data_available_for_read(nfc_dev);
			if (ret <= 0) {
				disable_interrupt(nfc_dev);
				pr_err("%s: - error waiting for get version rsp ret %d\n",
					__func__, ret);
				goto err_nfcc_hw_check;
			}
		}

		ret = nfc_read(nfc_dev, nci_get_version_rsp,
					NCI_GET_VERSION_RSP_LEN);
		if (ret <= 0) {
			pr_err("%s: - nfc get version rsp error ret %d\n",
				__func__, ret);
			goto err_nfcc_hw_check;
		} else {
			nfc_dev->nqx_info.info.chip_type =
				nci_get_version_rsp[3];
			nfc_dev->nqx_info.info.rom_version =
				nci_get_version_rsp[4];
			nfc_dev->nqx_info.info.fw_minor =
				nci_get_version_rsp[6];
			nfc_dev->nqx_info.info.fw_major =
				nci_get_version_rsp[7];
		}

		gpio_set_value(nfc_dev->gpio.dwl_req, 0);

		goto err_nfcc_reset_failed;
	}

	if (nfc_dev->interface == PLATFORM_IF_I2C) {
		ret = is_data_available_for_read(nfc_dev);
		if (ret <= 0) {
			disable_interrupt(nfc_dev);
			pr_err("%s: - error waiting for core reset rsp ret %d\n",
					__func__, ret);

			goto err_nfcc_hw_check;
		}
	}

	/* Read Response of RESET command */
	ret = nfc_read(nfc_dev, nci_reset_rsp, NCI_RESET_RSP_LEN);
	if (ret <= 0) {
		pr_err("%s: - nfc rst rsp read err %d\n", __func__,
					ret);
		goto err_nfcc_hw_check;
	}

	if (nfc_dev->interface == PLATFORM_IF_I2C) {
		ret = is_data_available_for_read(nfc_dev);
		if (ret <= 0) {
			pr_err("%s: - error waiting for core reset ntf ret %d\n",
					__func__, ret);
			disable_interrupt(nfc_dev);
			goto err_nfcc_hw_check;
		}
	}

	/* Read Notification of RESET command */
	ret = nfc_read(nfc_dev, nci_reset_ntf, NCI_RESET_NTF_LEN);
	if (ret <= 0) {
		pr_err("%s: nfc nfc read error %d\n", __func__, ret);
		goto err_nfcc_hw_check;
	}

	reset_ntf_len = NCI_HDR_LEN + nci_reset_ntf[NCI_PAYLOAD_LEN_IDX] - 1;
	if (reset_ntf_len > NCI_HDR_LEN) {
		nfc_dev->nqx_info.info.chip_type =
			nci_reset_ntf[reset_ntf_len - NFC_CHIP_TYPE_OFF];
		nfc_dev->nqx_info.info.rom_version =
			nci_reset_ntf[reset_ntf_len - NFC_ROM_VERSION_OFF];
		nfc_dev->nqx_info.info.fw_major =
			nci_reset_ntf[reset_ntf_len - NFC_FW_MAJOR_OFF];
		nfc_dev->nqx_info.info.fw_minor =
				nci_reset_ntf[reset_ntf_len];
	}
	pr_debug("%s: - NFC reset rsp : NfcNciRx %x %x %x\n",
		__func__, nci_reset_rsp[0],
		nci_reset_rsp[1], nci_reset_rsp[2]);

err_nfcc_reset_failed:
	pr_info("NFC chip_type = %x\n",
		nfc_dev->nqx_info.info.chip_type);
	pr_info("NFC fw version = %x.%x.%x\n",
		nfc_dev->nqx_info.info.rom_version,
		nfc_dev->nqx_info.info.fw_major,
		nfc_dev->nqx_info.info.fw_minor);

	switch (nfc_dev->nqx_info.info.chip_type) {
	case NFCC_SN100_A:
	case NFCC_SN100_B:
		pr_debug("%s: ## NFCC == SN100x ##\n", __func__);
		break;
	default:
		pr_err("%s: - NFCC HW not Supported\n", __func__);
		break;
	}

	ret = 0;
	nfc_dev->nfc_ven_enabled = true;

	goto disable_i3c_intr;

err_nfcc_hw_check:
	if (nfc_dev->interface == PLATFORM_IF_I2C)
		gpio_set_ven(nfc_dev, 0);

	gpio_set_value(nfc_dev->gpio.dwl_req, 0);

	ret = -ENXIO;
	pr_debug("%s: - NFCC HW not available\n", __func__);

disable_i3c_intr:
	if (nfc_dev->interface == PLATFORM_IF_I3C)
		disable_interrupt(nfc_dev);
done:
	kfree(nci_reset_rsp);
	kfree(nci_reset_ntf);
	kfree(nci_get_version_cmd);
	kfree(nci_get_version_rsp);
	kfree(nci_reset_cmd);

	return ret;
}
EXPORT_SYMBOL(nfcc_hw_check);
+24 −1
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * Copyright (c) 2015-2019, The Linux Foundation. All rights reserved.
 * Copyright (c) 2015-2020, The Linux Foundation. All rights reserved.
 */

#ifndef _NFC_COMMON_H_
@@ -22,6 +22,7 @@
#include <linux/delay.h>
#include <linux/uaccess.h>
#include <linux/slab.h>
#include <linux/nfcinfo.h>

#include "nfc_i2c_drv.h"
#include "nfc_i3c_drv.h"
@@ -38,6 +39,19 @@
// HDR length of NCI packet
#define NCI_HDR_LEN				3
#define NCI_PAYLOAD_IDX			3
#define NCI_PAYLOAD_LEN_IDX		2

#define NCI_RESET_CMD_LEN			(4)
#define NCI_RESET_RSP_LEN			(4)
#define NCI_RESET_NTF_LEN			(13)
#define NCI_GET_VERSION_CMD_LEN		(8)
#define NCI_GET_VERSION_RSP_LEN		(12)

// Below offsets should be subtracted from core reset ntf len

#define NFC_CHIP_TYPE_OFF		(3)
#define NFC_ROM_VERSION_OFF		(2)
#define NFC_FW_MAJOR_OFF		(1)

#define COLD_RESET_CMD_LEN		3
#define COLD_RESET_RSP_LEN		4
@@ -134,6 +148,12 @@ enum gpio_values {
	GPIO_IRQ = 0x4,
};

enum nfcc_chip_variant {
	NFCC_SN100_A = 0xa3,	    /**< NFCC SN100_A */
	NFCC_SN100_B = 0xa4,	    /**< NFCC SN100_B */
	NFCC_NOT_SUPPORTED = 0xFF		/**< NFCC is not supported */
};

// NFC GPIO variables
struct platform_gpio {
	unsigned int irq;
@@ -175,6 +195,8 @@ struct nfc_dev {
	/* read buffer*/
	size_t kbuflen;
	u8 *kbuf;

	union nqx_uinfo nqx_info;
};

int nfc_dev_open(struct inode *inode, struct file *filp);
@@ -189,5 +211,6 @@ void nfc_misc_remove(struct nfc_dev *nfc_dev, int count);
int configure_gpio(unsigned int gpio, int flag);
void read_cold_reset_rsp(struct nfc_dev *nfc_dev, char *header);
void gpio_set_ven(struct nfc_dev *nfc_dev, int value);
int nfcc_hw_check(struct nfc_dev *nfc_dev);

#endif //_NFC_COMMON_H_
+27 −21
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2015-2019, The Linux Foundation. All rights reserved.
 * Copyright (c) 2015-2020, The Linux Foundation. All rights reserved.
 */

#include "nfc_common.h"
@@ -133,24 +133,26 @@ ssize_t nfc_i2c_dev_read(struct file *filp, char __user *buf,
				i2c_dev->irq_enabled = true;
				enable_irq(i2c_dev->client->irq);
			}
			if (!gpio_get_value(nfc_dev->gpio.irq)) {
				ret = wait_event_interruptible(nfc_dev->read_wq,
						       !i2c_dev->irq_enabled);

				if (ret) {
					pr_err("error wakeup of read wq\n");
					goto err;
				}

			}
			i2c_disable_irq(i2c_dev);

			if (gpio_get_value(nfc_dev->gpio.irq))
				break;

			if (!gpio_get_value(nfc_dev->gpio.ven)) {
				pr_info("%s: releasing read\n", __func__);
				ret = -EIO;
				pr_info("%s: ven low in read !\n", __func__);
				ret = -ENODEV;
				goto err;
			}

			if (gpio_get_value(nfc_dev->gpio.irq))
				break;

			pr_warn("%s: spurious interrupt detected\n", __func__);
		}
	}
@@ -332,20 +334,22 @@ int nfc_i2c_dev_probe(struct i2c_client *client, const struct i2c_device_id *id)
		goto err_nfc_misc_remove;
	}
	i2c_disable_irq(i2c_dev);
	device_init_wakeup(&client->dev, true);
	device_set_wakeup_capable(&client->dev, true);
	i2c_set_clientdata(client, nfc_dev);

	ret = nfcc_hw_check(nfc_dev);
	if (ret) {
		pr_err("nfc hw check failed ret %d\n", ret);
		goto err_nfcc_hw_check;
	}

	device_init_wakeup(&client->dev, true);
	i2c_dev->irq_wake_up = false;

	//SET VEN GPIO LOW and HIGH
	gpio_set_value(nfc_dev->gpio.ven, 0);
	usleep_range(10000, 10100);
	gpio_set_value(nfc_dev->gpio.ven, 1);
	usleep_range(10000, 10100);
	nfc_dev->nfc_ven_enabled = true;
	pr_info("%s success\n", __func__);
	return 0;

err_nfcc_hw_check:
	free_irq(client->irq, nfc_dev);
err_nfc_misc_remove:
	nfc_misc_remove(nfc_dev, DEV_COUNT);
err_mutex_destroy:
@@ -377,6 +381,7 @@ int nfc_i2c_dev_remove(struct i2c_client *client)
		ret = -ENODEV;
		return ret;
	}
	device_init_wakeup(&client->dev, false);
	free_irq(client->irq, nfc_dev);
	nfc_misc_remove(nfc_dev, DEV_COUNT);
	mutex_destroy(&nfc_dev->dev_ref_mutex);
@@ -456,8 +461,9 @@ static int __init nfc_i2c_dev_init(void)
{
	int ret = 0;

	pr_info("Loading NFC I2C driver\n");
	ret = i2c_add_driver(&nfc_i2c_dev_driver);
	if (ret != 0)
		pr_err("NFC I2C add driver error ret %d\n", ret);
	return ret;
}

@@ -465,7 +471,7 @@ module_init(nfc_i2c_dev_init);

static void __exit nfc_i2c_dev_exit(void)
{
	pr_info("Unloading NFC I2C driver\n");
	pr_debug("Unloading NFC I2C driver\n");
	i2c_del_driver(&nfc_i2c_dev_driver);
}

+19 −12
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2019, The Linux Foundation. All rights reserved.
 * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
 */

#include "nfc_common.h"
@@ -154,7 +154,7 @@ static ssize_t i3c_kbuf_store(struct i3c_dev *i3c_dev, const char *buf,
 *
 *  @return number of bytes copied , error code for failures .
 */
static ssize_t i3c_nci_kbuf_retrieve(struct i3c_dev *i3c_dev, char *buf,
ssize_t i3c_nci_kbuf_retrieve(struct i3c_dev *i3c_dev, char *buf,
				     size_t count)
{
	size_t requested_size = count;
@@ -204,7 +204,7 @@ static ssize_t i3c_nci_kbuf_retrieve(struct i3c_dev *i3c_dev, char *buf,
		if (ret != 0) {
			pr_err("didn't get completion, interrupted!! ret %d\n",
			       ret);
			return -EINVAL;
			return ret;
		}
	} while (available_size < requested_size);

@@ -245,6 +245,7 @@ static ssize_t i3c_nci_kbuf_retrieve(struct i3c_dev *i3c_dev, char *buf,
	pr_debug("%s , count = %zx exit\n", __func__, count);
	return count;
}
EXPORT_SYMBOL(i3c_nci_kbuf_retrieve);

/** @brief   This API can be used to read data from I3C device from HAL layer.
 *
@@ -275,7 +276,7 @@ ssize_t nfc_i3c_dev_read(struct file *filp, char __user *buf,
	tmp = nfc_dev->kbuf;
	ret = i3c_nci_kbuf_retrieve(i3c_dev, tmp, count);
	if (ret != count) {
		pr_err("%s: buf read from I3C device returned error (%d)\n",
		pr_err("%s: kbuf read err ret (%d)\n",
		       __func__, ret);
		ret = -EIO;
	} else if (copy_to_user(buf, tmp, ret)) {
@@ -322,7 +323,7 @@ ssize_t nfc_i3c_dev_write(struct file *filp, const char __user *buf,

	ret = i3c_write(i3c_dev, tmp, count, NO_RETRY);
	if (ret != count) {
		pr_err("%s: failed to write %d\n", __func__, ret);
		pr_err("%s: i3c_write err ret %d\n", __func__, ret);
		ret = -EIO;
		goto out_free;
	}
@@ -364,7 +365,7 @@ static void i3c_workqueue_handler(struct work_struct *work)
		pr_err("%s: No memory to copy read data\n", __func__);
		return;
	}
	pr_info("%s: hdr_len = %d\n", __func__, hdr_len);
	pr_debug("%s: hdr_len = %d\n", __func__, hdr_len);
	memset(tmp, 0x00, i3c_dev->read_kbuf_len);

	ret = i3c_read(i3c_dev, tmp, hdr_len);
@@ -419,7 +420,7 @@ static void i3c_ibi_handler(struct i3c_device *device,
	struct nfc_dev *nfc_dev = i3cdev_get_drvdata(device);
	struct i3c_dev *i3c_dev = &nfc_dev->i3c_dev;

	pr_debug("%s: Received read IBI request from slave\n", __func__);
	pr_debug("%s\n", __func__);
	if (device_may_wakeup(&device->dev))
		pm_wakeup_event(&device->dev, WAKEUP_SRC_TIMEOUT);

@@ -665,15 +666,21 @@ int nfc_i3c_dev_probe(struct i3c_device *device)
		goto err_nfc_misc_remove;
	}

	atomic_set(&nfc_dev->i3c_dev.pm_state, PM_STATE_NORMAL);
	ret = nfcc_hw_check(nfc_dev);
	if (ret) {
		pr_err("nfc hw check failed ret %d\n", ret);
		goto err_nfcc_hw_check;
	}

	atomic_set(&nfc_dev->i3c_dev.pm_state, PM_STATE_NORMAL);
	device_init_wakeup(&device->dev, true);
	device_set_wakeup_capable(&device->dev, true);

	pr_info("%s success\n", __func__);

	return 0;

err_nfcc_hw_check:
	i3c_device_free_ibi(device);
err_nfc_misc_remove:
	nfc_misc_remove(nfc_dev, DEV_COUNT);
err_wq_destroy:
@@ -825,9 +832,9 @@ static int __init nfc_dev_i3c_init(void)
{
	int ret = 0;

	pr_info("Loading NFC I3C driver\n");
	ret = i3c_driver_register_with_owner(&nfc_i3c_dev_driver, THIS_MODULE);
	pr_debug("NFC i3c driver register ret = %d\n", ret);
	if (ret != 0)
		pr_err("NFC I3C driver register error ret = %d\n", ret);
	return ret;
}

@@ -835,7 +842,7 @@ module_init(nfc_dev_i3c_init);

static void __exit nfc_i3c_dev_exit(void)
{
	pr_info("Unloading NFC I3C driver\n");
	pr_debug("Unloading NFC I3C driver\n");
	i3c_driver_unregister(&nfc_i3c_dev_driver);
}

+10 −2
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * Copyright (c) 2019, The Linux Foundation. All rights reserved.
 * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
 */

#ifndef _NFC_I3C_DRV_H_
@@ -96,6 +96,8 @@ int i3c_disable_ibi(struct i3c_dev *i3c_dev);
ssize_t i3c_write(struct i3c_dev *i3c_dev, const char *buf, const size_t count,
		  int max_retry_cnt);
ssize_t i3c_read(struct i3c_dev *i3c_dev, char *buf, size_t count);
ssize_t i3c_nci_kbuf_retrieve(struct i3c_dev *i3c_dev, char *buf,
				     size_t count);

#else

@@ -116,7 +118,13 @@ static inline ssize_t i3c_write(struct i3c_dev *i3c_dev,
}

static inline ssize_t i3c_read(struct i3c_dev *i3c_dev,
				char *buf, size_t count);
				char *buf, size_t count)
{
	return -ENXIO;
}

ssize_t i3c_nci_kbuf_retrieve(struct i3c_dev *i3c_dev, char *buf,
				     size_t count)
{
	return -ENXIO;
}
Loading