diff --git a/drivers/nfc/qti/Makefile b/drivers/nfc/qti/Makefile index c5f02b67a21c..0463f8027f04 100644 --- a/drivers/nfc/qti/Makefile +++ b/drivers/nfc/qti/Makefile @@ -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 diff --git a/drivers/nfc/qti/nfc_common.c b/drivers/nfc/qti/nfc_common.c index 5cc17d2c37a3..fe8173d49333 100644 --- a/drivers/nfc/qti/nfc_common.c +++ b/drivers/nfc/qti/nfc_common.c @@ -8,24 +8,6 @@ #include #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); diff --git a/drivers/nfc/qti/nfc_common.h b/drivers/nfc/qti/nfc_common.h index 243ecafb70f3..762c4193b14e 100644 --- a/drivers/nfc/qti/nfc_common.h +++ b/drivers/nfc/qti/nfc_common.h @@ -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); diff --git a/drivers/nfc/qti/nfc_i2c_drv.c b/drivers/nfc/qti/nfc_i2c_drv.c index 1d235f01fa6c..924c8531df5a 100644 --- a/drivers/nfc/qti/nfc_i2c_drv.c +++ b/drivers/nfc/qti/nfc_i2c_drv.c @@ -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); diff --git a/drivers/nfc/qti/nfc_i2c_drv.h b/drivers/nfc/qti/nfc_i2c_drv.h index 43c7b56a8bde..732c8ce1e3e7 100644 --- a/drivers/nfc/qti/nfc_i2c_drv.h +++ b/drivers/nfc/qti/nfc_i2c_drv.h @@ -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; } diff --git a/drivers/nfc/qti/nfc_i3c_drv.c b/drivers/nfc/qti/nfc_i3c_drv.c index 063ab48fdd85..d72e5ad4ab8f 100644 --- a/drivers/nfc/qti/nfc_i3c_drv.c +++ b/drivers/nfc/qti/nfc_i3c_drv.c @@ -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); diff --git a/drivers/nfc/qti/nfc_i3c_drv.h b/drivers/nfc/qti/nfc_i3c_drv.h index f0a7485b5bae..78be4a7ff3be 100644 --- a/drivers/nfc/qti/nfc_i3c_drv.h +++ b/drivers/nfc/qti/nfc_i3c_drv.h @@ -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; }