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

This commit is contained in:
qctecmdr 2020-01-13 11:37:44 -08:00 • committed by Gerrit - the friendly Code Review server
commit 1f37c7cca2
7 changed files with 393 additions and 45 deletions

View file

@ -1,6 +1,6 @@
// 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,
COLD_RESET_CMD_LEN, MAX_RETRY_COUNT);
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);
@ -248,7 +262,7 @@ void read_cold_reset_rsp(struct nfc_dev *nfc_dev, char *header)
(nfc_dev->interface == PLATFORM_IF_I2C)) {
ret = i2c_read(&nfc_dev->i2c_dev, cold_reset_rsp,
NCI_HDR_LEN);
NCI_HDR_LEN);
if (ret <= 0) {
pr_err("%s: failure to read cold reset rsp header\n",
__func__);
@ -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);

View file

@ -1,6 +1,6 @@
/* 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_

View file

@ -1,6 +1,6 @@
// 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);
}
ret = wait_event_interruptible(nfc_dev->read_wq,
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;
}
if (ret) {
pr_err("error wakeup of read wq\n");
goto err;
}
}
i2c_disable_irq(i2c_dev);
if (!gpio_get_value(nfc_dev->gpio.ven)) {
pr_info("%s: releasing read\n", __func__);
ret = -EIO;
goto err;
}
if (gpio_get_value(nfc_dev->gpio.irq))
break;
if (!gpio_get_value(nfc_dev->gpio.ven)) {
pr_info("%s: ven low in read !\n", __func__);
ret = -ENODEV;
goto err;
}
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);
}

View file

@ -1,6 +1,6 @@
// 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);
}

View file

@ -1,6 +1,6 @@
/* 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;
}

11
include/linux/nfcinfo.h Normal file
View file

@ -0,0 +1,11 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2016-2020, The Linux Foundation. All rights reserved.
*/
#ifndef _NFCINFO_H
#define _NFCINFO_H
#include <uapi/linux/nfc/nfcinfo.h>
#endif

View file

@ -0,0 +1,26 @@
/* SPDX-License-Identifier: GPL-2.0-only WITH Linux-syscall-note */
/*
* Copyright (c) 2018-2020 The Linux Foundation. All rights reserved.
*/
#ifndef _UAPI_NFCINFO_H_
#define _UAPI_NFCINFO_H_
#include <linux/ioctl.h>
#define NFCC_MAGIC 0xE9
#define NFCC_GET_INFO _IOW(NFCC_MAGIC, 0x09, unsigned int)
struct nqx_devinfo {
unsigned char chip_type;
unsigned char rom_version;
unsigned char fw_major;
unsigned char fw_minor;
};
union nqx_uinfo {
unsigned int i;
struct nqx_devinfo info;
};
#endif