mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-29 03:01:39 -04:00
NFC: Made the QTI NFC drivers GKI compliant
Removed circular dependency of nfc_common.c on NFC I2C and I3C drivers, by setting interface specific API for nfc read,write,enable and disable interrupts, in the interface drivers. Change-Id: I66587d39ad92556d6e8fda3281e7bbcf1980683d Signed-off-by: Karthik Poosa <[email protected]>
This commit is contained in:
parent
eb81b68b14
commit
5e2a9b4b62
7 changed files with 119 additions and 140 deletions
|
|
@ -3,8 +3,8 @@
|
|||
# Makefile for qti nfc drivers
|
||||
#
|
||||
|
||||
obj-$(CONFIG_NFC_QTI_I2C) += nfc_i2c_drv.o
|
||||
nfc_i2c_drv-objs:= nfc_common.o nfc_i2c_drv.o
|
||||
obj-$(CONFIG_NFC_QTI_I2C) += nfc_i2c.o
|
||||
nfc_i2c-objs:= nfc_common.o nfc_i2c_drv.o
|
||||
|
||||
obj-$(CONFIG_NFC_QTI_I3C) += nfc_i3c_drv.o
|
||||
nfc_i3c_drv-objs:= nfc_common.o nfc_i3c_drv.o
|
||||
obj-$(CONFIG_NFC_QTI_I3C) += nfc_i3c.o
|
||||
nfc_i3c-objs:= nfc_common.o nfc_i3c_drv.o
|
||||
|
|
|
|||
|
|
@ -8,24 +8,6 @@
|
|||
#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)
|
||||
|
|
@ -69,7 +51,6 @@ int nfc_parse_dt(struct device *dev, struct platform_gpio *nfc_gpio,
|
|||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(nfc_parse_dt);
|
||||
|
||||
void gpio_set_ven(struct nfc_dev *nfc_dev, int value)
|
||||
{
|
||||
|
|
@ -126,7 +107,6 @@ int configure_gpio(unsigned int gpio, int flag)
|
|||
}
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(configure_gpio);
|
||||
|
||||
void nfc_misc_remove(struct nfc_dev *nfc_dev, int count)
|
||||
{
|
||||
|
|
@ -138,7 +118,6 @@ void nfc_misc_remove(struct nfc_dev *nfc_dev, int count)
|
|||
class_destroy(nfc_dev->nfc_class);
|
||||
unregister_chrdev_region(nfc_dev->devno, count);
|
||||
}
|
||||
EXPORT_SYMBOL(nfc_misc_remove);
|
||||
|
||||
int nfc_misc_probe(struct nfc_dev *nfc_dev,
|
||||
const struct file_operations *nfc_fops, int count,
|
||||
|
|
@ -191,23 +170,7 @@ int nfc_misc_probe(struct nfc_dev *nfc_dev,
|
|||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(nfc_misc_probe);
|
||||
|
||||
static void enable_interrupt(struct nfc_dev *nfc_dev)
|
||||
{
|
||||
if (nfc_dev->interface == PLATFORM_IF_I2C)
|
||||
i2c_enable_irq(&nfc_dev->i2c_dev);
|
||||
else
|
||||
i3c_enable_ibi(&nfc_dev->i3c_dev);
|
||||
}
|
||||
|
||||
static void disable_interrupt(struct nfc_dev *nfc_dev)
|
||||
{
|
||||
if (nfc_dev->interface == PLATFORM_IF_I2C)
|
||||
i2c_disable_irq(&nfc_dev->i2c_dev);
|
||||
else
|
||||
i3c_disable_ibi(&nfc_dev->i3c_dev);
|
||||
}
|
||||
|
||||
static int send_cold_reset_cmd(struct nfc_dev *nfc_dev)
|
||||
{
|
||||
|
|
@ -233,7 +196,7 @@ 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;
|
||||
|
||||
ret = nfc_write(nfc_dev, cold_reset_cmd,
|
||||
ret = nfc_dev->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",
|
||||
|
|
@ -261,7 +224,7 @@ void read_cold_reset_rsp(struct nfc_dev *nfc_dev, char *header)
|
|||
if ((!cold_reset->is_nfc_enabled) &&
|
||||
(nfc_dev->interface == PLATFORM_IF_I2C)) {
|
||||
|
||||
ret = i2c_read(&nfc_dev->i2c_dev, cold_reset_rsp,
|
||||
ret = nfc_dev->nfc_read(nfc_dev, cold_reset_rsp,
|
||||
NCI_HDR_LEN);
|
||||
if (ret <= 0) {
|
||||
pr_err("%s: failure to read cold reset rsp header\n",
|
||||
|
|
@ -288,11 +251,11 @@ void read_cold_reset_rsp(struct nfc_dev *nfc_dev, char *header)
|
|||
}
|
||||
|
||||
if (nfc_dev->interface == PLATFORM_IF_I2C)
|
||||
ret = i2c_read(&nfc_dev->i2c_dev,
|
||||
ret = nfc_dev->nfc_read(nfc_dev,
|
||||
&cold_reset_rsp[NCI_PAYLOAD_IDX],
|
||||
cold_reset_rsp[2]);
|
||||
else
|
||||
ret = i3c_read(&nfc_dev->i3c_dev,
|
||||
ret = nfc_dev->i3c_dev.nfc_read_direct(nfc_dev,
|
||||
&cold_reset_rsp[NCI_PAYLOAD_IDX],
|
||||
cold_reset_rsp[2]);
|
||||
|
||||
|
|
@ -306,7 +269,6 @@ void read_cold_reset_rsp(struct nfc_dev *nfc_dev, char *header)
|
|||
error:
|
||||
kfree(cold_reset_rsp);
|
||||
}
|
||||
EXPORT_SYMBOL(read_cold_reset_rsp);
|
||||
|
||||
/*
|
||||
* Power management of the eSE
|
||||
|
|
@ -367,7 +329,7 @@ int nfc_ese_pwr(struct nfc_dev *nfc_dev, unsigned long arg)
|
|||
|
||||
// Read data as NFC thread is not active
|
||||
|
||||
enable_interrupt(nfc_dev);
|
||||
nfc_dev->nfc_enable_intr(nfc_dev);
|
||||
|
||||
if (nfc_dev->interface == PLATFORM_IF_I2C) {
|
||||
ret = wait_event_interruptible_timeout(
|
||||
|
|
@ -375,7 +337,7 @@ int nfc_ese_pwr(struct nfc_dev *nfc_dev, unsigned long arg)
|
|||
!nfc_dev->i2c_dev.irq_enabled,
|
||||
msecs_to_jiffies(MAX_IRQ_WAIT_TIME));
|
||||
if (ret <= 0) {
|
||||
disable_interrupt(nfc_dev);
|
||||
nfc_dev->nfc_disable_intr(nfc_dev);
|
||||
nfc_dev->cold_reset.rsp_pending = false;
|
||||
return nfc_dev->cold_reset.status;
|
||||
}
|
||||
|
|
@ -385,7 +347,7 @@ int nfc_ese_pwr(struct nfc_dev *nfc_dev, unsigned long arg)
|
|||
wait_event_interruptible(
|
||||
nfc_dev->cold_reset.read_wq,
|
||||
!nfc_dev->cold_reset.rsp_pending);
|
||||
disable_interrupt(nfc_dev);
|
||||
nfc_dev->nfc_disable_intr(nfc_dev);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -400,7 +362,6 @@ int nfc_ese_pwr(struct nfc_dev *nfc_dev, unsigned long arg)
|
|||
}
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(nfc_ese_pwr);
|
||||
|
||||
/*
|
||||
* nfc_ioctl_power_states() - power control
|
||||
|
|
@ -422,7 +383,7 @@ static int nfc_ioctl_power_states(struct nfc_dev *nfc_dev, unsigned long arg)
|
|||
* interrupts to avoid spurious notifications to upper
|
||||
* layers.
|
||||
*/
|
||||
disable_interrupt(nfc_dev);
|
||||
nfc_dev->nfc_disable_intr(nfc_dev);
|
||||
pr_debug("gpio firm disable\n");
|
||||
if (gpio_is_valid(nfc_dev->gpio.dwl_req)) {
|
||||
gpio_set_value(nfc_dev->gpio.dwl_req, 0);
|
||||
|
|
@ -435,7 +396,7 @@ static int nfc_ioctl_power_states(struct nfc_dev *nfc_dev, unsigned long arg)
|
|||
nfc_dev->nfc_ven_enabled = false;
|
||||
|
||||
} else if (arg == NFC_POWER_ON) {
|
||||
enable_interrupt(nfc_dev);
|
||||
nfc_dev->nfc_enable_intr(nfc_dev);
|
||||
pr_debug("gpio_set_value enable: %s:\n", __func__);
|
||||
if (gpio_is_valid(nfc_dev->gpio.dwl_req)) {
|
||||
gpio_set_value(nfc_dev->gpio.dwl_req, 0);
|
||||
|
|
@ -575,7 +536,6 @@ long nfc_dev_ioctl(struct file *pfile, unsigned int cmd, unsigned long arg)
|
|||
}
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(nfc_dev_ioctl);
|
||||
|
||||
int nfc_dev_open(struct inode *inode, struct file *filp)
|
||||
{
|
||||
|
|
@ -596,7 +556,7 @@ int nfc_dev_open(struct inode *inode, struct file *filp)
|
|||
gpio_set_value(nfc_dev->gpio.dwl_req, 0);
|
||||
usleep_range(10000, 10100);
|
||||
}
|
||||
enable_interrupt(nfc_dev);
|
||||
nfc_dev->nfc_enable_intr(nfc_dev);
|
||||
}
|
||||
nfc_dev->dev_ref_count = nfc_dev->dev_ref_count + 1;
|
||||
|
||||
|
|
@ -604,7 +564,6 @@ int nfc_dev_open(struct inode *inode, struct file *filp)
|
|||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(nfc_dev_open);
|
||||
|
||||
int nfc_dev_close(struct inode *inode, struct file *filp)
|
||||
{
|
||||
|
|
@ -620,7 +579,7 @@ int nfc_dev_close(struct inode *inode, struct file *filp)
|
|||
|
||||
if (nfc_dev->dev_ref_count == 1) {
|
||||
|
||||
disable_interrupt(nfc_dev);
|
||||
nfc_dev->nfc_disable_intr(nfc_dev);
|
||||
|
||||
if (gpio_is_valid(nfc_dev->gpio.dwl_req)) {
|
||||
gpio_set_value(nfc_dev->gpio.dwl_req, 0);
|
||||
|
|
@ -637,13 +596,12 @@ 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);
|
||||
nfc_dev->nfc_enable_intr(nfc_dev);
|
||||
|
||||
ret = wait_event_interruptible_timeout(nfc_dev->read_wq,
|
||||
!nfc_dev->i2c_dev.irq_enabled,
|
||||
|
|
@ -693,7 +651,7 @@ int nfcc_hw_check(struct nfc_dev *nfc_dev)
|
|||
}
|
||||
|
||||
if (nfc_dev->interface == PLATFORM_IF_I3C)
|
||||
enable_interrupt(nfc_dev);
|
||||
nfc_dev->nfc_enable_intr(nfc_dev);
|
||||
else {
|
||||
/* making sure that the NFCC starts in a clean state. */
|
||||
gpio_set_ven(nfc_dev, 1);/* HPD : Enable*/
|
||||
|
|
@ -707,7 +665,7 @@ int nfcc_hw_check(struct nfc_dev *nfc_dev)
|
|||
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,
|
||||
ret = nfc_dev->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__);
|
||||
|
|
@ -731,7 +689,7 @@ int nfcc_hw_check(struct nfc_dev *nfc_dev)
|
|||
nci_get_version_cmd[6] = 0x6E;
|
||||
nci_get_version_cmd[7] = 0xEF;
|
||||
|
||||
ret = nfc_write(nfc_dev, nci_get_version_cmd,
|
||||
ret = nfc_dev->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",
|
||||
|
|
@ -742,14 +700,14 @@ int nfcc_hw_check(struct nfc_dev *nfc_dev)
|
|||
if (nfc_dev->interface == PLATFORM_IF_I2C) {
|
||||
ret = is_data_available_for_read(nfc_dev);
|
||||
if (ret <= 0) {
|
||||
disable_interrupt(nfc_dev);
|
||||
nfc_dev->nfc_disable_intr(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,
|
||||
ret = nfc_dev->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",
|
||||
|
|
@ -774,7 +732,7 @@ int nfcc_hw_check(struct nfc_dev *nfc_dev)
|
|||
if (nfc_dev->interface == PLATFORM_IF_I2C) {
|
||||
ret = is_data_available_for_read(nfc_dev);
|
||||
if (ret <= 0) {
|
||||
disable_interrupt(nfc_dev);
|
||||
nfc_dev->nfc_disable_intr(nfc_dev);
|
||||
pr_err("%s: - error waiting for core reset rsp ret %d\n",
|
||||
__func__, ret);
|
||||
|
||||
|
|
@ -783,7 +741,7 @@ int nfcc_hw_check(struct nfc_dev *nfc_dev)
|
|||
}
|
||||
|
||||
/* Read Response of RESET command */
|
||||
ret = nfc_read(nfc_dev, nci_reset_rsp, NCI_RESET_RSP_LEN);
|
||||
ret = nfc_dev->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);
|
||||
|
|
@ -795,13 +753,13 @@ int nfcc_hw_check(struct nfc_dev *nfc_dev)
|
|||
if (ret <= 0) {
|
||||
pr_err("%s: - error waiting for core reset ntf ret %d\n",
|
||||
__func__, ret);
|
||||
disable_interrupt(nfc_dev);
|
||||
nfc_dev->nfc_disable_intr(nfc_dev);
|
||||
goto err_nfcc_hw_check;
|
||||
}
|
||||
}
|
||||
|
||||
/* Read Notification of RESET command */
|
||||
ret = nfc_read(nfc_dev, nci_reset_ntf, NCI_RESET_NTF_LEN);
|
||||
ret = nfc_dev->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;
|
||||
|
|
@ -856,7 +814,7 @@ err_nfcc_hw_check:
|
|||
|
||||
disable_i3c_intr:
|
||||
if (nfc_dev->interface == PLATFORM_IF_I3C)
|
||||
disable_interrupt(nfc_dev);
|
||||
nfc_dev->nfc_disable_intr(nfc_dev);
|
||||
done:
|
||||
kfree(nci_reset_rsp);
|
||||
kfree(nci_reset_ntf);
|
||||
|
|
@ -866,4 +824,3 @@ done:
|
|||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(nfcc_hw_check);
|
||||
|
|
|
|||
|
|
@ -197,6 +197,13 @@ struct nfc_dev {
|
|||
u8 *kbuf;
|
||||
|
||||
union nqx_uinfo nqx_info;
|
||||
|
||||
int (*nfc_read)(struct nfc_dev *dev,
|
||||
char *buf, size_t count);
|
||||
int (*nfc_write)(struct nfc_dev *dev,
|
||||
const char *buf, const size_t count, int max_retry_cnt);
|
||||
int (*nfc_enable_intr)(struct nfc_dev *dev);
|
||||
int (*nfc_disable_intr)(struct nfc_dev *dev);
|
||||
};
|
||||
|
||||
int nfc_dev_open(struct inode *inode, struct file *filp);
|
||||
|
|
|
|||
|
|
@ -11,18 +11,20 @@
|
|||
* Check if interrupt is disabled or not
|
||||
* and disable interrupt
|
||||
*
|
||||
* Return: void
|
||||
* Return: int
|
||||
*/
|
||||
void i2c_disable_irq(struct i2c_dev *i2c_dev)
|
||||
int i2c_disable_irq(struct nfc_dev *dev)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&i2c_dev->irq_enabled_lock, flags);
|
||||
if (i2c_dev->irq_enabled) {
|
||||
disable_irq_nosync(i2c_dev->client->irq);
|
||||
i2c_dev->irq_enabled = false;
|
||||
spin_lock_irqsave(&dev->i2c_dev.irq_enabled_lock, flags);
|
||||
if (dev->i2c_dev.irq_enabled) {
|
||||
disable_irq_nosync(dev->i2c_dev.client->irq);
|
||||
dev->i2c_dev.irq_enabled = false;
|
||||
}
|
||||
spin_unlock_irqrestore(&i2c_dev->irq_enabled_lock, flags);
|
||||
spin_unlock_irqrestore(&dev->i2c_dev.irq_enabled_lock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -31,18 +33,20 @@ void i2c_disable_irq(struct i2c_dev *i2c_dev)
|
|||
* Check if interrupt is enabled or not
|
||||
* and enable interrupt
|
||||
*
|
||||
* Return: void
|
||||
* Return: int
|
||||
*/
|
||||
void i2c_enable_irq(struct i2c_dev *i2c_dev)
|
||||
int i2c_enable_irq(struct nfc_dev *dev)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&i2c_dev->irq_enabled_lock, flags);
|
||||
if (!i2c_dev->irq_enabled) {
|
||||
i2c_dev->irq_enabled = true;
|
||||
enable_irq(i2c_dev->client->irq);
|
||||
spin_lock_irqsave(&dev->i2c_dev.irq_enabled_lock, flags);
|
||||
if (!dev->i2c_dev.irq_enabled) {
|
||||
dev->i2c_dev.irq_enabled = true;
|
||||
enable_irq(dev->i2c_dev.client->irq);
|
||||
}
|
||||
spin_unlock_irqrestore(&i2c_dev->irq_enabled_lock, flags);
|
||||
spin_unlock_irqrestore(&dev->i2c_dev.irq_enabled_lock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static irqreturn_t i2c_irq_handler(int irq, void *dev_id)
|
||||
|
|
@ -53,19 +57,19 @@ static irqreturn_t i2c_irq_handler(int irq, void *dev_id)
|
|||
if (device_may_wakeup(&i2c_dev->client->dev))
|
||||
pm_wakeup_event(&i2c_dev->client->dev, WAKEUP_SRC_TIMEOUT);
|
||||
|
||||
i2c_disable_irq(i2c_dev);
|
||||
i2c_disable_irq(nfc_dev);
|
||||
wake_up(&nfc_dev->read_wq);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
int i2c_read(struct i2c_dev *i2c_dev, char *buf, size_t count)
|
||||
int i2c_read(struct nfc_dev *dev, char *buf, size_t count)
|
||||
{
|
||||
int ret;
|
||||
|
||||
pr_debug("%s : reading %zu bytes.\n", __func__, count);
|
||||
/* Read data */
|
||||
ret = i2c_master_recv(i2c_dev->client, buf, count);
|
||||
ret = i2c_master_recv(dev->i2c_dev.client, buf, count);
|
||||
if (ret <= 0) {
|
||||
pr_err("%s: i2c_master_recv returned %d\n", __func__, ret);
|
||||
goto i2c_read_err;
|
||||
|
|
@ -80,9 +84,8 @@ int i2c_read(struct i2c_dev *i2c_dev, char *buf, size_t count)
|
|||
i2c_read_err:
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(i2c_read);
|
||||
|
||||
int i2c_write(struct i2c_dev *i2c_dev, char *buf, size_t count,
|
||||
int i2c_write(struct nfc_dev *dev, const char *buf, size_t count,
|
||||
int max_retry_cnt)
|
||||
{
|
||||
int ret = -EINVAL;
|
||||
|
|
@ -91,7 +94,7 @@ int i2c_write(struct i2c_dev *i2c_dev, char *buf, size_t count,
|
|||
pr_debug("%s : writing %zu bytes.\n", __func__, count);
|
||||
|
||||
for (retry_cnt = 1; retry_cnt <= max_retry_cnt; retry_cnt++) {
|
||||
ret = i2c_master_send(i2c_dev->client, buf, count);
|
||||
ret = i2c_master_send(dev->i2c_dev.client, buf, count);
|
||||
if (ret <= 0) {
|
||||
pr_warn("%s: write failed, Maybe in Standby Mode - Retry(%d)\n",
|
||||
__func__, retry_cnt);
|
||||
|
|
@ -101,7 +104,6 @@ int i2c_write(struct i2c_dev *i2c_dev, char *buf, size_t count,
|
|||
}
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(i2c_write);
|
||||
|
||||
ssize_t nfc_i2c_dev_read(struct file *filp, char __user *buf,
|
||||
size_t count, loff_t *offset)
|
||||
|
|
@ -142,7 +144,7 @@ ssize_t nfc_i2c_dev_read(struct file *filp, char __user *buf,
|
|||
goto err;
|
||||
}
|
||||
}
|
||||
i2c_disable_irq(i2c_dev);
|
||||
i2c_disable_irq(nfc_dev);
|
||||
|
||||
if (gpio_get_value(nfc_dev->gpio.irq))
|
||||
break;
|
||||
|
|
@ -166,7 +168,7 @@ ssize_t nfc_i2c_dev_read(struct file *filp, char __user *buf,
|
|||
memset(tmp, 0x00, count);
|
||||
|
||||
/* Read data */
|
||||
ret = i2c_read(i2c_dev, tmp, count);
|
||||
ret = i2c_read(nfc_dev, tmp, count);
|
||||
if (ret <= 0) {
|
||||
pr_err("%s: i2c_master_recv returned %d\n", __func__, ret);
|
||||
goto err;
|
||||
|
|
@ -206,7 +208,6 @@ ssize_t nfc_i2c_dev_write(struct file *filp, const char __user *buf,
|
|||
int ret;
|
||||
char *tmp = NULL;
|
||||
struct nfc_dev *nfc_dev = filp->private_data;
|
||||
struct i2c_dev *i2c_dev = &nfc_dev->i2c_dev;
|
||||
|
||||
if (!nfc_dev) {
|
||||
ret = -ENODEV;
|
||||
|
|
@ -226,7 +227,7 @@ ssize_t nfc_i2c_dev_write(struct file *filp, const char __user *buf,
|
|||
goto out;
|
||||
}
|
||||
|
||||
ret = i2c_write(i2c_dev, tmp, count, NO_RETRY);
|
||||
ret = i2c_write(nfc_dev, tmp, count, NO_RETRY);
|
||||
if (ret != count) {
|
||||
pr_err("%s: failed to write %d\n", __func__, ret);
|
||||
ret = -EIO;
|
||||
|
|
@ -279,6 +280,10 @@ int nfc_i2c_dev_probe(struct i2c_client *client, const struct i2c_device_id *id)
|
|||
nfc_dev->interface = PLATFORM_IF_I2C;
|
||||
nfc_dev->i2c_dev.client = client;
|
||||
i2c_dev = &nfc_dev->i2c_dev;
|
||||
nfc_dev->nfc_read = i2c_read;
|
||||
nfc_dev->nfc_write = i2c_write;
|
||||
nfc_dev->nfc_enable_intr = i2c_enable_irq;
|
||||
nfc_dev->nfc_disable_intr = i2c_disable_irq;
|
||||
|
||||
ret = configure_gpio(nfc_gpio.ven, GPIO_OUTPUT);
|
||||
if (ret) {
|
||||
|
|
@ -333,7 +338,7 @@ int nfc_i2c_dev_probe(struct i2c_client *client, const struct i2c_device_id *id)
|
|||
pr_err("%s: request_irq failed\n", __func__);
|
||||
goto err_nfc_misc_remove;
|
||||
}
|
||||
i2c_disable_irq(i2c_dev);
|
||||
i2c_disable_irq(nfc_dev);
|
||||
i2c_set_clientdata(client, nfc_dev);
|
||||
|
||||
ret = nfcc_hw_check(nfc_dev);
|
||||
|
|
|
|||
|
|
@ -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_I2C_DRV_H_
|
||||
|
|
@ -10,6 +10,8 @@
|
|||
#define NFC_I2C_DRV_STR "qcom,sn-nci" /*kept same as dts */
|
||||
#define NFC_I2C_DEV_ID "sn-i2c"
|
||||
|
||||
struct nfc_dev;
|
||||
|
||||
//Interface specific parameters
|
||||
struct i2c_dev {
|
||||
struct i2c_client *client;
|
||||
|
|
@ -26,31 +28,33 @@ int nfc_i2c_dev_remove(struct i2c_client *client);
|
|||
int nfc_i2c_dev_suspend(struct device *device);
|
||||
int nfc_i2c_dev_resume(struct device *device);
|
||||
|
||||
#ifdef CONFIG_NFC_QTI_I2C
|
||||
#if IS_ENABLED(CONFIG_NFC_QTI_I2C)
|
||||
|
||||
void i2c_enable_irq(struct i2c_dev *i2c_dev);
|
||||
void i2c_disable_irq(struct i2c_dev *i2c_dev);
|
||||
int i2c_write(struct i2c_dev *i2c_dev, char *buf, size_t count,
|
||||
int i2c_enable_irq(struct nfc_dev *dev);
|
||||
int i2c_disable_irq(struct nfc_dev *dev);
|
||||
int i2c_write(struct nfc_dev *dev, const char *buf, size_t count,
|
||||
int max_retry_cnt);
|
||||
int i2c_read(struct i2c_dev *i2c_dev, char *buf, size_t count);
|
||||
int i2c_read(struct nfc_dev *dev, char *buf, size_t count);
|
||||
|
||||
#else
|
||||
|
||||
static inline void i2c_enable_irq(struct i2c_dev *i2c_dev)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void i2c_disable_irq(struct i2c_dev *i2c_dev)
|
||||
{
|
||||
}
|
||||
|
||||
static inline int i2c_write(struct i2c_dev *i2c_dev, char *buf, size_t count,
|
||||
int max_retry_cnt)
|
||||
static inline int i2c_enable_irq(struct nfc_dev *dev)
|
||||
{
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
static inline int i2c_read(struct i2c_dev *i2c_dev, char *buf, size_t count)
|
||||
static inline int i2c_disable_irq(struct nfc_dev *dev)
|
||||
{
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
static inline int i2c_write(struct nfc_dev *dev, const char *buf,
|
||||
size_t count, int max_retry_cnt)
|
||||
{
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
static inline int i2c_read(struct nfc_dev *dev, char *buf, size_t count)
|
||||
{
|
||||
return -ENXIO;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
*
|
||||
* @return ret number of bytes written ,negative error core otherwise.
|
||||
*/
|
||||
ssize_t i3c_write(struct i3c_dev *i3c_dev, const char *buf, const size_t count,
|
||||
int i3c_write(struct nfc_dev *dev, const char *buf, const size_t count,
|
||||
int max_retry_cnt)
|
||||
{
|
||||
int ret = -EIO;
|
||||
|
|
@ -26,7 +26,7 @@ ssize_t i3c_write(struct i3c_dev *i3c_dev, const char *buf, const size_t count,
|
|||
};
|
||||
|
||||
do {
|
||||
ret = i3c_device_do_priv_xfers(i3c_dev->device, &write_buf,
|
||||
ret = i3c_device_do_priv_xfers(dev->i3c_dev.device, &write_buf,
|
||||
(sizeof(write_buf) / sizeof(struct i3c_priv_xfer)));
|
||||
|
||||
pr_debug("%s exit ret = %x\n", __func__, ret);
|
||||
|
|
@ -42,7 +42,6 @@ ssize_t i3c_write(struct i3c_dev *i3c_dev, const char *buf, const size_t count,
|
|||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(i3c_write);
|
||||
|
||||
/** @brief This API used to read data from I3C device.
|
||||
*
|
||||
|
|
@ -52,7 +51,7 @@ EXPORT_SYMBOL(i3c_write);
|
|||
*
|
||||
* @return number of bytes read ,negative error code otherwise.
|
||||
*/
|
||||
ssize_t i3c_read(struct i3c_dev *i3c_dev, char *buf, size_t count)
|
||||
int i3c_read(struct nfc_dev *dev, char *buf, size_t count)
|
||||
{
|
||||
int ret = -EIO;
|
||||
struct i3c_priv_xfer read_buf = {
|
||||
|
|
@ -61,7 +60,7 @@ ssize_t i3c_read(struct i3c_dev *i3c_dev, char *buf, size_t count)
|
|||
.data.in = buf
|
||||
};
|
||||
|
||||
ret = i3c_device_do_priv_xfers(i3c_dev->device, &read_buf,
|
||||
ret = i3c_device_do_priv_xfers(dev->i3c_dev.device, &read_buf,
|
||||
(sizeof(read_buf) / sizeof(struct i3c_priv_xfer)));
|
||||
pr_debug("%s exit ret = %x\n", __func__, ret);
|
||||
if (!ret)
|
||||
|
|
@ -71,7 +70,6 @@ ssize_t i3c_read(struct i3c_dev *i3c_dev, char *buf, size_t count)
|
|||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(i3c_read);
|
||||
|
||||
/** @brief This API can be used to write data to nci buf.
|
||||
* The API will overwrite the existing memory if
|
||||
|
|
@ -154,12 +152,13 @@ static ssize_t i3c_kbuf_store(struct i3c_dev *i3c_dev, const char *buf,
|
|||
*
|
||||
* @return number of bytes copied , error code for failures .
|
||||
*/
|
||||
ssize_t i3c_nci_kbuf_retrieve(struct i3c_dev *i3c_dev, char *buf,
|
||||
int i3c_nci_kbuf_retrieve(struct nfc_dev *dev, char *buf,
|
||||
size_t count)
|
||||
{
|
||||
size_t requested_size = count;
|
||||
size_t available_size = 0;
|
||||
size_t copied_size = 0;
|
||||
struct i3c_dev *i3c_dev = &dev->i3c_dev;
|
||||
int ret = 0;
|
||||
|
||||
if (i3c_dev == NULL)
|
||||
|
|
@ -245,7 +244,6 @@ 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.
|
||||
*
|
||||
|
|
@ -264,7 +262,6 @@ ssize_t nfc_i3c_dev_read(struct file *filp, char __user *buf,
|
|||
int ret;
|
||||
char *tmp = NULL;
|
||||
struct nfc_dev *nfc_dev = filp->private_data;
|
||||
struct i3c_dev *i3c_dev = &nfc_dev->i3c_dev;
|
||||
|
||||
if (count > nfc_dev->kbuflen)
|
||||
count = nfc_dev->kbuflen;
|
||||
|
|
@ -274,7 +271,7 @@ ssize_t nfc_i3c_dev_read(struct file *filp, char __user *buf,
|
|||
mutex_lock(&nfc_dev->read_mutex);
|
||||
|
||||
tmp = nfc_dev->kbuf;
|
||||
ret = i3c_nci_kbuf_retrieve(i3c_dev, tmp, count);
|
||||
ret = i3c_nci_kbuf_retrieve(nfc_dev, tmp, count);
|
||||
if (ret != count) {
|
||||
pr_err("%s: kbuf read err ret (%d)\n",
|
||||
__func__, ret);
|
||||
|
|
@ -303,7 +300,6 @@ ssize_t nfc_i3c_dev_write(struct file *filp, const char __user *buf,
|
|||
int ret;
|
||||
char *tmp = NULL;
|
||||
struct nfc_dev *nfc_dev = filp->private_data;
|
||||
struct i3c_dev *i3c_dev = &nfc_dev->i3c_dev;
|
||||
|
||||
if (!nfc_dev)
|
||||
return -ENODEV;
|
||||
|
|
@ -321,7 +317,7 @@ ssize_t nfc_i3c_dev_write(struct file *filp, const char __user *buf,
|
|||
goto out;
|
||||
}
|
||||
|
||||
ret = i3c_write(i3c_dev, tmp, count, NO_RETRY);
|
||||
ret = i3c_write(nfc_dev, tmp, count, NO_RETRY);
|
||||
if (ret != count) {
|
||||
pr_err("%s: i3c_write err ret %d\n", __func__, ret);
|
||||
ret = -EIO;
|
||||
|
|
@ -368,7 +364,7 @@ static void i3c_workqueue_handler(struct work_struct *work)
|
|||
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);
|
||||
ret = i3c_read(nfc_dev, tmp, hdr_len);
|
||||
if (ret < 0) {
|
||||
pr_err("%s: i3c_read returned error %d\n", __func__, ret);
|
||||
return;
|
||||
|
|
@ -396,7 +392,7 @@ static void i3c_workqueue_handler(struct work_struct *work)
|
|||
return;
|
||||
}
|
||||
|
||||
ret = i3c_read(i3c_dev, tmp + hdr_len, length_byte);
|
||||
ret = i3c_read(nfc_dev, tmp + hdr_len, length_byte);
|
||||
if (ret < 0) {
|
||||
pr_err("%s: i3c_read returned error %d\n", __func__, ret);
|
||||
i3c_kbuf_store(i3c_dev, tmp, hdr_len);
|
||||
|
|
@ -439,17 +435,17 @@ static void i3c_ibi_handler(struct i3c_device *device,
|
|||
*
|
||||
* @return 0 on success, error code for failures.
|
||||
*/
|
||||
int i3c_enable_ibi(struct i3c_dev *i3c_dev)
|
||||
int i3c_enable_ibi(struct nfc_dev *dev)
|
||||
{
|
||||
int ret = 0;
|
||||
int retry_count = 0;
|
||||
|
||||
if (!i3c_dev->ibi_enabled) {
|
||||
if (!dev->i3c_dev.ibi_enabled) {
|
||||
|
||||
do {
|
||||
ret = i3c_device_enable_ibi(i3c_dev->device);
|
||||
ret = i3c_device_enable_ibi(dev->i3c_dev.device);
|
||||
if (!ret) {
|
||||
i3c_dev->ibi_enabled = true;
|
||||
dev->i3c_dev.ibi_enabled = true;
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -470,17 +466,17 @@ int i3c_enable_ibi(struct i3c_dev *i3c_dev)
|
|||
*
|
||||
* @return 0 on success, error code for failures.
|
||||
*/
|
||||
int i3c_disable_ibi(struct i3c_dev *i3c_dev)
|
||||
int i3c_disable_ibi(struct nfc_dev *dev)
|
||||
{
|
||||
int ret = 0;
|
||||
int retry_count = 0;
|
||||
|
||||
if (i3c_dev->ibi_enabled) {
|
||||
if (dev->i3c_dev.ibi_enabled) {
|
||||
|
||||
do {
|
||||
ret = i3c_device_disable_ibi(i3c_dev->device);
|
||||
ret = i3c_device_disable_ibi(dev->i3c_dev.device);
|
||||
if (!ret) {
|
||||
i3c_dev->ibi_enabled = false;
|
||||
dev->i3c_dev.ibi_enabled = false;
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -615,6 +611,11 @@ int nfc_i3c_dev_probe(struct i3c_device *device)
|
|||
nfc_dev->i3c_dev.buf.total_size = PAGE_SIZE;
|
||||
i3c_reset_nci_buf(&nfc_dev->i3c_dev);
|
||||
nfc_dev->interface = PLATFORM_IF_I3C;
|
||||
nfc_dev->nfc_write = i3c_write;
|
||||
nfc_dev->nfc_read = i3c_nci_kbuf_retrieve;
|
||||
nfc_dev->i3c_dev.nfc_read_direct = i3c_read;
|
||||
nfc_dev->nfc_enable_intr = i3c_enable_ibi;
|
||||
nfc_dev->nfc_disable_intr = i3c_disable_ibi;
|
||||
nfc_dev->i3c_dev.device = device;
|
||||
|
||||
ret = configure_gpio(nfc_gpio.ven, GPIO_OUTPUT_HIGH);
|
||||
|
|
|
|||
|
|
@ -41,6 +41,8 @@
|
|||
// I3C WorkQueue name
|
||||
#define NFC_I3C_WORKQUEUE "nfc_i3c_workq"
|
||||
|
||||
struct nfc_dev;
|
||||
|
||||
/**
|
||||
* struct nci_buf - NCI buffer used to store and retrieve read data from device.
|
||||
* @read_offset: The offset pointing to data available to read in nci buf.
|
||||
|
|
@ -69,6 +71,7 @@ struct nci_buf {
|
|||
* @read_hdr Header size for reads.
|
||||
* @ibi_enabled: IBI enabled or not.
|
||||
* @pm_state: PM state of NFC I3C device.
|
||||
* @nfc_read_direct Do NFC read bypassing the read buffer.
|
||||
*/
|
||||
struct i3c_dev {
|
||||
struct i3c_device *device;
|
||||
|
|
@ -82,6 +85,8 @@ struct i3c_dev {
|
|||
unsigned char read_hdr;
|
||||
bool ibi_enabled;
|
||||
atomic_t pm_state;
|
||||
int (*nfc_read_direct)(struct nfc_dev *dev,
|
||||
char *buf, size_t count);
|
||||
};
|
||||
|
||||
int nfc_i3c_dev_probe(struct i3c_device *device);
|
||||
|
|
@ -89,42 +94,42 @@ int nfc_i3c_dev_remove(struct i3c_device *device);
|
|||
int nfc_i3c_dev_suspend(struct device *device);
|
||||
int nfc_i3c_dev_resume(struct device *device);
|
||||
|
||||
#ifdef CONFIG_NFC_QTI_I3C
|
||||
#if IS_ENABLED(CONFIG_NFC_QTI_I3C)
|
||||
|
||||
int i3c_enable_ibi(struct i3c_dev *i3c_dev);
|
||||
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 i3c_enable_ibi(struct nfc_dev *dev);
|
||||
int i3c_disable_ibi(struct nfc_dev *dev);
|
||||
int i3c_write(struct nfc_dev *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,
|
||||
int i3c_read(struct nfc_dev *dev, char *buf, size_t count);
|
||||
int i3c_nci_kbuf_retrieve(struct nfc_dev *dev, char *buf,
|
||||
size_t count);
|
||||
|
||||
#else
|
||||
|
||||
static inline int i3c_enable_ibi(struct i3c_dev *i3c_dev)
|
||||
static inline int i3c_enable_ibi(struct nfc_dev *dev)
|
||||
{
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
static inline int i3c_disable_ibi(struct i3c_dev *i3c_dev)
|
||||
static inline int i3c_disable_ibi(struct nfc_dev *dev)
|
||||
{
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
static inline ssize_t i3c_write(struct i3c_dev *i3c_dev,
|
||||
static inline int i3c_write(struct nfc_dev *dev,
|
||||
const char *buf, const size_t count, int max_retry_cnt)
|
||||
{
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
static inline ssize_t i3c_read(struct i3c_dev *i3c_dev,
|
||||
static inline int i3c_read(struct nfc_dev *dev,
|
||||
char *buf, size_t count)
|
||||
{
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
ssize_t i3c_nci_kbuf_retrieve(struct i3c_dev *i3c_dev, char *buf,
|
||||
size_t count)
|
||||
static inline int i3c_nci_kbuf_retrieve(struct nfc_dev *dev,
|
||||
char *buf, size_t count)
|
||||
{
|
||||
return -ENXIO;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue