Updated corresponding to - NFC_AR_00_E800_12.10.00_OpnSrc
This commit is contained in:
25
nfc/common.c
25
nfc/common.c
@@ -286,6 +286,31 @@ static int nfc_ioctl_power_states(struct nfc_dev *nfc_dev, unsigned long arg)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_COMPAT
|
||||||
|
/**
|
||||||
|
* nfc_dev_compat_ioctl - used to set or get data from upper layer.
|
||||||
|
* @pfile file node for opened device.
|
||||||
|
* @cmd ioctl type from upper layer.
|
||||||
|
* @arg ioctl arg from upper layer.
|
||||||
|
*
|
||||||
|
* NFC and ESE Device power control, based on the argument value
|
||||||
|
*
|
||||||
|
* Return: -ENOIOCTLCMD if arg is not supported
|
||||||
|
* 0 if Success(or no issue)
|
||||||
|
* 0 or 1 in case of arg is ESE_GET_PWR/ESE_POWER_STATE
|
||||||
|
* and error ret code otherwise
|
||||||
|
*/
|
||||||
|
long nfc_dev_compat_ioctl(struct file *pfile, unsigned int cmd,
|
||||||
|
unsigned long arg)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
arg = (compat_u64)arg;
|
||||||
|
pr_debug("%s: cmd = %x arg = %zx\n", __func__, cmd, arg);
|
||||||
|
ret = nfc_dev_ioctl(pfile, cmd, arg);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* nfc_dev_ioctl - used to set or get data from upper layer.
|
* nfc_dev_ioctl - used to set or get data from upper layer.
|
||||||
* @pfile file node for opened device.
|
* @pfile file node for opened device.
|
||||||
|
@@ -74,9 +74,9 @@
|
|||||||
|
|
||||||
/* Ioctls */
|
/* Ioctls */
|
||||||
/* The type should be aligned with MW HAL definitions */
|
/* The type should be aligned with MW HAL definitions */
|
||||||
#define NFC_SET_PWR _IOW(NFC_MAGIC, 0x01, long)
|
#define NFC_SET_PWR _IOW(NFC_MAGIC, 0x01, uint32_t)
|
||||||
#define ESE_SET_PWR _IOW(NFC_MAGIC, 0x02, long)
|
#define ESE_SET_PWR _IOW(NFC_MAGIC, 0x02, uint32_t)
|
||||||
#define ESE_GET_PWR _IOR(NFC_MAGIC, 0x03, long)
|
#define ESE_GET_PWR _IOR(NFC_MAGIC, 0x03, uint32_t)
|
||||||
|
|
||||||
#define DTS_IRQ_GPIO_STR "nxp,pn544-irq"
|
#define DTS_IRQ_GPIO_STR "nxp,pn544-irq"
|
||||||
#define DTS_VEN_GPIO_STR "nxp,pn544-ven"
|
#define DTS_VEN_GPIO_STR "nxp,pn544-ven"
|
||||||
@@ -196,6 +196,8 @@ struct nfc_dev {
|
|||||||
int nfc_dev_open(struct inode *inode, struct file *filp);
|
int nfc_dev_open(struct inode *inode, struct file *filp);
|
||||||
int nfc_dev_flush(struct file *pfile, fl_owner_t id);
|
int nfc_dev_flush(struct file *pfile, fl_owner_t id);
|
||||||
int nfc_dev_close(struct inode *inode, struct file *filp);
|
int nfc_dev_close(struct inode *inode, struct file *filp);
|
||||||
|
long nfc_dev_compat_ioctl(struct file *pfile, unsigned int cmd,
|
||||||
|
unsigned long arg);
|
||||||
long nfc_dev_ioctl(struct file *pfile, unsigned int cmd, 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,
|
int nfc_parse_dt(struct device *dev, struct platform_configs *nfc_configs,
|
||||||
uint8_t interface);
|
uint8_t interface);
|
||||||
|
@@ -54,7 +54,6 @@ static int send_cold_reset_protection_cmd(struct nfc_dev *nfc_dev,
|
|||||||
uint8_t *cmd = nfc_dev->write_kbuf;
|
uint8_t *cmd = nfc_dev->write_kbuf;
|
||||||
struct cold_reset *cold_reset = &nfc_dev->cold_reset;
|
struct cold_reset *cold_reset = &nfc_dev->cold_reset;
|
||||||
|
|
||||||
mutex_lock(&nfc_dev->write_mutex);
|
|
||||||
*cmd++ = NCI_PROP_MSG_CMD;
|
*cmd++ = NCI_PROP_MSG_CMD;
|
||||||
|
|
||||||
if (requestType) { /* reset protection */
|
if (requestType) { /* reset protection */
|
||||||
@@ -84,7 +83,6 @@ static int send_cold_reset_protection_cmd(struct nfc_dev *nfc_dev,
|
|||||||
cmd[NCI_HDR_IDX], cmd[NCI_HDR_OID_IDX],
|
cmd[NCI_HDR_IDX], cmd[NCI_HDR_OID_IDX],
|
||||||
cmd[NCI_PAYLOAD_LEN_IDX]);
|
cmd[NCI_PAYLOAD_LEN_IDX]);
|
||||||
exit:
|
exit:
|
||||||
mutex_unlock(&nfc_dev->write_mutex);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -152,7 +150,6 @@ static int perform_cold_reset_protection(struct nfc_dev *nfc_dev,
|
|||||||
int timeout = 0;
|
int timeout = 0;
|
||||||
char *rsp = nfc_dev->read_kbuf;
|
char *rsp = nfc_dev->read_kbuf;
|
||||||
struct cold_reset *cold_reset = &nfc_dev->cold_reset;
|
struct cold_reset *cold_reset = &nfc_dev->cold_reset;
|
||||||
bool nfc_dev_opened = false;
|
|
||||||
|
|
||||||
/* check if NFCC not in the FW download or hard reset state */
|
/* check if NFCC not in the FW download or hard reset state */
|
||||||
ret = validate_nfc_state_nci(nfc_dev);
|
ret = validate_nfc_state_nci(nfc_dev);
|
||||||
@@ -161,10 +158,6 @@ static int perform_cold_reset_protection(struct nfc_dev *nfc_dev,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check if NFC is enabled */
|
|
||||||
mutex_lock(&nfc_dev->dev_ref_mutex);
|
|
||||||
nfc_dev_opened = (nfc_dev->dev_ref_count > 0) ? true : false;
|
|
||||||
|
|
||||||
/* check if NFCC not in the FW download or hard reset state */
|
/* check if NFCC not in the FW download or hard reset state */
|
||||||
ret = validate_cold_reset_protection_request(cold_reset, arg);
|
ret = validate_cold_reset_protection_request(cold_reset, arg);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
@@ -178,21 +171,23 @@ static int perform_cold_reset_protection(struct nfc_dev *nfc_dev,
|
|||||||
ret = -EBUSY;
|
ret = -EBUSY;
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
/* set default value for status as failure */
|
|
||||||
|
/* enable interrupt if not enabled incase when devnode not opened by HAL */
|
||||||
|
nfc_dev->nfc_enable_intr(nfc_dev);
|
||||||
|
|
||||||
|
mutex_lock(&nfc_dev->write_mutex);
|
||||||
|
/* write api has 15ms maximum wait to clear any pending read before */
|
||||||
cold_reset->status = -EIO;
|
cold_reset->status = -EIO;
|
||||||
cold_reset->rsp_pending = true;
|
cold_reset->rsp_pending = true;
|
||||||
|
|
||||||
/* enable interrupt before sending cmd, when devnode not opened by HAL */
|
|
||||||
if (!nfc_dev_opened)
|
|
||||||
nfc_dev->nfc_enable_intr(nfc_dev);
|
|
||||||
|
|
||||||
ret = send_cold_reset_protection_cmd(nfc_dev, IS_RST_PROT_REQ(arg));
|
ret = send_cold_reset_protection_cmd(nfc_dev, IS_RST_PROT_REQ(arg));
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
|
mutex_unlock(&nfc_dev->write_mutex);
|
||||||
|
cold_reset->rsp_pending = false;
|
||||||
pr_err("%s: failed to send cold reset/protection cmd\n",
|
pr_err("%s: failed to send cold reset/protection cmd\n",
|
||||||
__func__);
|
__func__);
|
||||||
cold_reset->rsp_pending = false;
|
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
/* start the cold reset guard timer */
|
/* start the cold reset guard timer */
|
||||||
if (IS_CLD_RST_REQ(arg)) {
|
if (IS_CLD_RST_REQ(arg)) {
|
||||||
@@ -200,6 +195,7 @@ static int perform_cold_reset_protection(struct nfc_dev *nfc_dev,
|
|||||||
if (!(cold_reset->reset_protection && IS_SRC_NFC(arg))) {
|
if (!(cold_reset->reset_protection && IS_SRC_NFC(arg))) {
|
||||||
ret = start_cold_reset_guard_timer(cold_reset);
|
ret = start_cold_reset_guard_timer(cold_reset);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
|
mutex_unlock(&nfc_dev->write_mutex);
|
||||||
pr_err("%s: error in mod_timer\n", __func__);
|
pr_err("%s: error in mod_timer\n", __func__);
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
@@ -208,28 +204,27 @@ static int perform_cold_reset_protection(struct nfc_dev *nfc_dev,
|
|||||||
|
|
||||||
timeout = NCI_CMD_RSP_TIMEOUT_MS;
|
timeout = NCI_CMD_RSP_TIMEOUT_MS;
|
||||||
do {
|
do {
|
||||||
|
/* call read api directly if reader thread is not blocked */
|
||||||
|
if (mutex_trylock(&nfc_dev->read_mutex)) {
|
||||||
|
pr_debug("%s: reader thread not pending\n", __func__);
|
||||||
|
ret = nfc_dev->nfc_read(nfc_dev, rsp, 3,
|
||||||
|
timeout);
|
||||||
|
mutex_unlock(&nfc_dev->read_mutex);
|
||||||
|
if (!ret)
|
||||||
|
break;
|
||||||
|
usleep_range(READ_RETRY_WAIT_TIME_US,
|
||||||
|
READ_RETRY_WAIT_TIME_US + 500);
|
||||||
/* Read pending response form the HAL service */
|
/* Read pending response form the HAL service */
|
||||||
if (nfc_dev_opened) {
|
} else if (!wait_event_interruptible_timeout(
|
||||||
if (!wait_event_interruptible_timeout(
|
cold_reset->read_wq,
|
||||||
cold_reset->read_wq,
|
cold_reset->rsp_pending == false,
|
||||||
cold_reset->rsp_pending == false,
|
msecs_to_jiffies(timeout))) {
|
||||||
msecs_to_jiffies(timeout))) {
|
pr_err("%s: cold reset/prot response timeout\n", __func__);
|
||||||
pr_err("%s: cold reset/prot response timeout\n",
|
ret = -EAGAIN;
|
||||||
__func__);
|
|
||||||
ret = -EAGAIN;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
/* Read response here as NFC thread is not active */
|
|
||||||
if (nfc_dev->interface == PLATFORM_IF_I2C) {
|
|
||||||
ret = nfc_dev->nfc_read(nfc_dev, rsp, 3,
|
|
||||||
timeout);
|
|
||||||
if (!ret)
|
|
||||||
break;
|
|
||||||
usleep_range(READ_RETRY_WAIT_TIME_US,
|
|
||||||
READ_RETRY_WAIT_TIME_US + 500);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} while (ret == -ERESTARTSYS || ret == -EFAULT);
|
} while (ret == -ERESTARTSYS || ret == -EFAULT);
|
||||||
|
mutex_unlock(&nfc_dev->write_mutex);
|
||||||
|
|
||||||
timeout = ESE_CLD_RST_REBOOT_GUARD_TIME_MS;
|
timeout = ESE_CLD_RST_REBOOT_GUARD_TIME_MS;
|
||||||
if (ret == 0) { /* success case */
|
if (ret == 0) { /* success case */
|
||||||
ret = cold_reset->status;
|
ret = cold_reset->status;
|
||||||
|
@@ -40,7 +40,9 @@
|
|||||||
#include <linux/delay.h>
|
#include <linux/delay.h>
|
||||||
#include <linux/uaccess.h>
|
#include <linux/uaccess.h>
|
||||||
#include <linux/gpio.h>
|
#include <linux/gpio.h>
|
||||||
|
#ifdef CONFIG_COMPAT
|
||||||
|
#include <linux/compat.h>
|
||||||
|
#endif
|
||||||
#include "common_ese.h"
|
#include "common_ese.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -256,6 +258,10 @@ ssize_t nfc_i2c_dev_read(struct file *filp, char __user *buf, size_t count,
|
|||||||
int ret;
|
int ret;
|
||||||
struct nfc_dev *nfc_dev = (struct nfc_dev *)filp->private_data;
|
struct nfc_dev *nfc_dev = (struct nfc_dev *)filp->private_data;
|
||||||
|
|
||||||
|
if (!nfc_dev) {
|
||||||
|
pr_err("%s: device doesn't exist anymore\n", __func__);
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
mutex_lock(&nfc_dev->read_mutex);
|
mutex_lock(&nfc_dev->read_mutex);
|
||||||
if (filp->f_flags & O_NONBLOCK) {
|
if (filp->f_flags & O_NONBLOCK) {
|
||||||
ret = i2c_master_recv(nfc_dev->i2c_dev.client, nfc_dev->read_kbuf, count);
|
ret = i2c_master_recv(nfc_dev->i2c_dev.client, nfc_dev->read_kbuf, count);
|
||||||
@@ -282,6 +288,11 @@ ssize_t nfc_i2c_dev_write(struct file *filp, const char __user *buf,
|
|||||||
if (count > MAX_DL_BUFFER_SIZE)
|
if (count > MAX_DL_BUFFER_SIZE)
|
||||||
count = MAX_DL_BUFFER_SIZE;
|
count = MAX_DL_BUFFER_SIZE;
|
||||||
|
|
||||||
|
if (!nfc_dev) {
|
||||||
|
pr_err("%s: device doesn't exist anymore\n", __func__);
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
mutex_lock(&nfc_dev->write_mutex);
|
mutex_lock(&nfc_dev->write_mutex);
|
||||||
if (copy_from_user(nfc_dev->write_kbuf, buf, count)) {
|
if (copy_from_user(nfc_dev->write_kbuf, buf, count)) {
|
||||||
pr_err("%s: failed to copy from user space\n", __func__);
|
pr_err("%s: failed to copy from user space\n", __func__);
|
||||||
@@ -302,6 +313,9 @@ static const struct file_operations nfc_i2c_dev_fops = {
|
|||||||
.flush = nfc_dev_flush,
|
.flush = nfc_dev_flush,
|
||||||
.release = nfc_dev_close,
|
.release = nfc_dev_close,
|
||||||
.unlocked_ioctl = nfc_dev_ioctl,
|
.unlocked_ioctl = nfc_dev_ioctl,
|
||||||
|
#ifdef CONFIG_COMPAT
|
||||||
|
.compat_ioctl = nfc_dev_compat_ioctl,
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
int nfc_i2c_dev_probe(struct i2c_client *client, const struct i2c_device_id *id)
|
int nfc_i2c_dev_probe(struct i2c_client *client, const struct i2c_device_id *id)
|
||||||
@@ -454,12 +468,18 @@ int nfc_i2c_dev_suspend(struct device *device)
|
|||||||
{
|
{
|
||||||
struct i2c_client *client = to_i2c_client(device);
|
struct i2c_client *client = to_i2c_client(device);
|
||||||
struct nfc_dev *nfc_dev = i2c_get_clientdata(client);
|
struct nfc_dev *nfc_dev = i2c_get_clientdata(client);
|
||||||
struct i2c_dev *i2c_dev = &nfc_dev->i2c_dev;
|
struct i2c_dev *i2c_dev = NULL;
|
||||||
|
if (!nfc_dev) {
|
||||||
|
pr_err("%s: device doesn't exist anymore\n", __func__);
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
i2c_dev = &nfc_dev->i2c_dev;
|
||||||
|
|
||||||
if (device_may_wakeup(&client->dev) && i2c_dev->irq_enabled) {
|
if (device_may_wakeup(&client->dev) && i2c_dev->irq_enabled) {
|
||||||
if (!enable_irq_wake(client->irq))
|
if (!enable_irq_wake(client->irq))
|
||||||
i2c_dev->irq_wake_up = true;
|
i2c_dev->irq_wake_up = true;
|
||||||
}
|
}
|
||||||
|
pr_debug("%s: irq_wake_up = %d", __func__, i2c_dev->irq_wake_up);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -467,12 +487,18 @@ int nfc_i2c_dev_resume(struct device *device)
|
|||||||
{
|
{
|
||||||
struct i2c_client *client = to_i2c_client(device);
|
struct i2c_client *client = to_i2c_client(device);
|
||||||
struct nfc_dev *nfc_dev = i2c_get_clientdata(client);
|
struct nfc_dev *nfc_dev = i2c_get_clientdata(client);
|
||||||
struct i2c_dev *i2c_dev = &nfc_dev->i2c_dev;
|
struct i2c_dev *i2c_dev = NULL;
|
||||||
|
if (!nfc_dev) {
|
||||||
|
pr_err("%s: device doesn't exist anymore\n", __func__);
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
i2c_dev = &nfc_dev->i2c_dev;
|
||||||
|
|
||||||
if (device_may_wakeup(&client->dev) && i2c_dev->irq_wake_up) {
|
if (device_may_wakeup(&client->dev) && i2c_dev->irq_wake_up) {
|
||||||
if (!disable_irq_wake(client->irq))
|
if (!disable_irq_wake(client->irq))
|
||||||
i2c_dev->irq_wake_up = false;
|
i2c_dev->irq_wake_up = false;
|
||||||
}
|
}
|
||||||
|
pr_debug("%s: irq_wake_up = %d", __func__, i2c_dev->irq_wake_up);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Referens i nytt ärende
Block a user