From f64dad377ca84304fb7931eb2a35f7e0c7fbbe67 Mon Sep 17 00:00:00 2001 From: nxf35421 Date: Thu, 29 Apr 2021 20:39:02 +0530 Subject: [PATCH] Updated corresponding to - NFC_AR_00_E000_12.04.01_OpnSrc --- nfc/Makefile | 1 - nfc/common.c | 428 ++++++++--------------------------------------- nfc/common.h | 188 +++++++++------------ nfc/common_ese.c | 199 ++++++++++++---------- nfc/common_ese.h | 80 ++++----- nfc/i2c_drv.c | 173 ++++++++++--------- nfc/i2c_drv.h | 19 ++- 7 files changed, 404 insertions(+), 684 deletions(-) diff --git a/nfc/Makefile b/nfc/Makefile index ddbea678de..16c477495a 100644 --- a/nfc/Makefile +++ b/nfc/Makefile @@ -3,6 +3,5 @@ # obj-$(CONFIG_NXP_NFC_I2C) += pn553_i2c.o pn553_i2c-objs := common.o common_ese.o i2c_drv.o -pn553_i2c-$(CONFIG_NXP_NFC_RECOVERY) += recovery_seq.o recovery_fw.o #ccflags-y += -DDEBUG diff --git a/nfc/common.c b/nfc/common.c index cf80332049..30231f8c37 100644 --- a/nfc/common.c +++ b/nfc/common.c @@ -1,7 +1,7 @@ /****************************************************************************** - * Copyright (C) 2015, The Linux Foundation. All rights reserved. - * Copyright (C) 2019-2021 NXP - * * + * Copyright (C) 2015, The Linux Foundation. All rights reserved. + * Copyright (C) 2019-2021 NXP + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or @@ -17,13 +17,11 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ******************************************************************************/ +#include #include -#include #include -#include -#include "common.h" + #include "common_ese.h" -#include "recovery_seq.h" int nfc_parse_dt(struct device *dev, struct platform_configs *nfc_configs, uint8_t interface) @@ -32,7 +30,7 @@ int nfc_parse_dt(struct device *dev, struct platform_configs *nfc_configs, struct platform_gpio *nfc_gpio = &nfc_configs->gpio; if (!np) { - pr_err("nfc of_node NULL\n"); + pr_err("%s: nfc of_node NULL\n", __func__); return -EINVAL; } @@ -40,26 +38,28 @@ int nfc_parse_dt(struct device *dev, struct platform_configs *nfc_configs, nfc_gpio->dwl_req = -EINVAL; nfc_gpio->ven = -EINVAL; - //required for i2c based chips only + /* irq required for i2c based chips only */ if (interface == PLATFORM_IF_I2C) { nfc_gpio->irq = of_get_named_gpio(np, DTS_IRQ_GPIO_STR, 0); if ((!gpio_is_valid(nfc_gpio->irq))) { - pr_err("nfc irq gpio invalid %d\n", nfc_gpio->irq); + pr_err("%s: irq gpio invalid %d\n", __func__, + nfc_gpio->irq); return -EINVAL; } pr_info("%s: irq %d\n", __func__, nfc_gpio->irq); } nfc_gpio->ven = of_get_named_gpio(np, DTS_VEN_GPIO_STR, 0); if ((!gpio_is_valid(nfc_gpio->ven))) { - pr_err("nfc ven gpio invalid %d\n", nfc_gpio->ven); + pr_err("%s: ven gpio invalid %d\n", __func__, nfc_gpio->ven); return -EINVAL; } - + /* some products like sn220 does not required fw dwl pin */ nfc_gpio->dwl_req = of_get_named_gpio(np, DTS_FWDN_GPIO_STR, 0); if ((!gpio_is_valid(nfc_gpio->dwl_req))) - pr_warn("nfc dwl_req gpio invalid %d\n", nfc_gpio->dwl_req); + pr_warn("%s: dwl_req gpio invalid %d\n", __func__, + nfc_gpio->dwl_req); - pr_info("%s: %d, %d, %d, %d\n", __func__, nfc_gpio->irq, nfc_gpio->ven, + pr_info("%s: %d, %d, %d\n", __func__, nfc_gpio->irq, nfc_gpio->ven, nfc_gpio->dwl_req); return 0; } @@ -67,11 +67,11 @@ int nfc_parse_dt(struct device *dev, struct platform_configs *nfc_configs, void set_valid_gpio(int gpio, int value) { if (gpio_is_valid(gpio)) { - pr_debug("%s gpio %d value %d\n", __func__, gpio, value); + pr_debug("%s: gpio %d value %d\n", __func__, gpio, value); gpio_set_value(gpio, value); - // hardware dependent delay - usleep_range(NFC_GPIO_SET_WAIT_TIME_USEC, - NFC_GPIO_SET_WAIT_TIME_USEC + 100); + /* hardware dependent delay */ + usleep_range(NFC_GPIO_SET_WAIT_TIME_US, + NFC_GPIO_SET_WAIT_TIME_US + 100); } } @@ -81,7 +81,7 @@ int get_valid_gpio(int gpio) if (gpio_is_valid(gpio)) { value = gpio_get_value(gpio); - pr_debug("%s gpio %d value %d\n", __func__, gpio, value); + pr_debug("%s: gpio %d value %d\n", __func__, gpio, value); } return value; } @@ -92,14 +92,14 @@ void gpio_set_ven(struct nfc_dev *nfc_dev, int value) if (gpio_get_value(nfc_gpio->ven) != value) { pr_debug("%s: value %d\n", __func__, value); - /*reset on change in level from high to low */ + /* reset on change in level from high to low */ if (value) ese_cold_reset_release(nfc_dev); gpio_set_value(nfc_gpio->ven, value); - // hardware dependent delay - usleep_range(NFC_GPIO_SET_WAIT_TIME_USEC, - NFC_GPIO_SET_WAIT_TIME_USEC + 100); + /* hardware dependent delay */ + usleep_range(NFC_GPIO_SET_WAIT_TIME_US, + NFC_GPIO_SET_WAIT_TIME_US + 100); } } @@ -111,32 +111,37 @@ int configure_gpio(unsigned int gpio, int flag) if (gpio_is_valid(gpio)) { ret = gpio_request(gpio, "nfc_gpio"); if (ret) { - pr_err("%s: unable to request nfc gpio [%d]\n", __func__, gpio); + pr_err("%s: unable to request nfc gpio [%d]\n", + __func__, gpio); return ret; } - /*set direction and value for output pin */ + /* set direction and value for output pin */ if (flag & GPIO_OUTPUT) { ret = gpio_direction_output(gpio, (GPIO_HIGH & flag)); - pr_debug("nfc o/p gpio %d level %d\n", gpio, gpio_get_value(gpio)); + pr_debug("%s: nfc o/p gpio %d level %d\n", __func__, + gpio, gpio_get_value(gpio)); } else { ret = gpio_direction_input(gpio); - pr_debug("nfc i/p gpio %d\n", gpio); + pr_debug("%s: nfc i/p gpio %d\n", __func__, gpio); } if (ret) { - pr_err("%s: unable to set direction for nfc gpio [%d]\n", __func__, gpio); + pr_err("%s: unable to set direction for nfc gpio [%d]\n", + __func__, gpio); gpio_free(gpio); return ret; } - /*Consider value as control for input IRQ pin */ + /* Consider value as control for input IRQ pin */ if (flag & GPIO_IRQ) { ret = gpio_to_irq(gpio); if (ret < 0) { - pr_err("%s: unable to set irq for nfc gpio [%d]\n", __func__, gpio); + pr_err("%s: unable to set irq [%d]\n", __func__, + gpio); gpio_free(gpio); return ret; } - pr_debug("%s: gpio_to_irq successful [%d]\n", __func__, gpio); + pr_debug("%s: gpio_to_irq successful [%d]\n", __func__, + gpio); return ret; } } else { @@ -170,20 +175,22 @@ void nfc_misc_unregister(struct nfc_dev *nfc_dev, int count) } int nfc_misc_register(struct nfc_dev *nfc_dev, - const struct file_operations *nfc_fops, - int count, char *devname, char *classname) + const struct file_operations *nfc_fops, int count, + char *devname, char *classname) { int ret = 0; ret = alloc_chrdev_region(&nfc_dev->devno, 0, count, devname); if (ret < 0) { - pr_err("%s: failed to alloc chrdev region ret %d\n", __func__, ret); + pr_err("%s: failed to alloc chrdev region ret %d\n", __func__, + ret); return ret; } nfc_dev->nfc_class = class_create(THIS_MODULE, classname); if (IS_ERR(nfc_dev->nfc_class)) { ret = PTR_ERR(nfc_dev->nfc_class); - pr_err("%s: failed to register device class ret %d\n", __func__, ret); + pr_err("%s: failed to register device class ret %d\n", __func__, + ret); unregister_chrdev_region(nfc_dev->devno, count); return ret; } @@ -199,7 +206,8 @@ int nfc_misc_register(struct nfc_dev *nfc_dev, nfc_dev->devno, nfc_dev, devname); if (IS_ERR(nfc_dev->nfc_device)) { ret = PTR_ERR(nfc_dev->nfc_device); - pr_err("%s: failed to create the device ret %d\n", __func__, ret); + pr_err("%s: failed to create the device ret %d\n", __func__, + ret); cdev_del(&nfc_dev->c_dev); class_destroy(nfc_dev->nfc_class); unregister_chrdev_region(nfc_dev->devno, count); @@ -208,7 +216,7 @@ int nfc_misc_register(struct nfc_dev *nfc_dev, return 0; } -/* +/** * nfc_ioctl_power_states() - power control * @nfc_dev: nfc device data structure * @arg: mode that we want to move to @@ -271,19 +279,21 @@ static int nfc_ioctl_power_states(struct nfc_dev *nfc_dev, unsigned long arg) set_valid_gpio(nfc_gpio->dwl_req, 0); nfc_dev->nfc_state = NFC_STATE_NCI; } else { - pr_err("%s bad arg %lu\n", __func__, arg); + pr_err("%s: bad arg %lu\n", __func__, arg); ret = -ENOIOCTLCMD; } return ret; } -/** @brief IOCTL function to be 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. + * @cmd ioctl type from upper layer. + * @arg ioctl arg from upper layer. * - * @param pfile fil 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 0 on success, error code for failures. + * Return: -ENOIOCTLCMD if arg is not supported, 0 or other in any other case */ long nfc_dev_ioctl(struct file *pfile, unsigned int cmd, unsigned long arg) { @@ -293,7 +303,7 @@ long nfc_dev_ioctl(struct file *pfile, unsigned int cmd, unsigned long arg) if (!nfc_dev) return -ENODEV; - pr_debug("%s cmd = %x arg = %zx\n", __func__, cmd, arg); + pr_debug("%s: cmd = %x arg = %zx\n", __func__, cmd, arg); switch (cmd) { case NFC_SET_PWR: ret = nfc_ioctl_power_states(nfc_dev, arg); @@ -304,11 +314,8 @@ 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 NFC_GET_IRQ_STATE: - ret = gpio_get_value(nfc_dev->configs.gpio.irq); - break; default: - pr_err("%s bad cmd %lu\n", __func__, arg); + pr_err("%s: bad cmd %lu\n", __func__, arg); ret = -ENOIOCTLCMD; }; return ret; @@ -316,7 +323,11 @@ long nfc_dev_ioctl(struct file *pfile, unsigned int cmd, unsigned long arg) int nfc_dev_open(struct inode *inode, struct file *filp) { - struct nfc_dev *nfc_dev = container_of(inode->i_cdev, struct nfc_dev, c_dev); + struct nfc_dev *nfc_dev = + container_of(inode->i_cdev, struct nfc_dev, c_dev); + + if (!nfc_dev) + return -ENODEV; pr_debug("%s: %d, %d\n", __func__, imajor(inode), iminor(inode)); @@ -336,7 +347,11 @@ int nfc_dev_open(struct inode *inode, struct file *filp) int nfc_dev_close(struct inode *inode, struct file *filp) { - struct nfc_dev *nfc_dev = container_of(inode->i_cdev, struct nfc_dev, c_dev); + struct nfc_dev *nfc_dev = + container_of(inode->i_cdev, struct nfc_dev, c_dev); + + if (!nfc_dev) + return -ENODEV; pr_debug("%s: %d, %d\n", __func__, imajor(inode), iminor(inode)); mutex_lock(&nfc_dev->dev_ref_mutex); @@ -347,11 +362,12 @@ int nfc_dev_close(struct inode *inode, struct file *filp) if (nfc_dev->dev_ref_count > 0) nfc_dev->dev_ref_count = nfc_dev->dev_ref_count - 1; else { - nfc_ese_pwr(nfc_dev, ESE_RST_PROT_DIS_NFC); - /* Uncomment below line incase of eSE calls flow is via NFC driver + /* + * Use "ESE_RST_PROT_DIS" as argument + * if eSE calls flow is via NFC driver * i.e. direct calls from SPI HAL to NFC driver */ - //nfc_ese_pwr(nfc_dev, ESE_RST_PROT_DIS); + nfc_ese_pwr(nfc_dev, ESE_RST_PROT_DIS_NFC); } filp->private_data = NULL; @@ -359,320 +375,20 @@ int nfc_dev_close(struct inode *inode, struct file *filp) return 0; } -/** - * get_nfcc_chip_type_dl() - get chip type in fw download command; - * @nfc_dev: nfc device data structure - * - * Perform get version command and determine chip - * type from response. - * - * @Return: enum chip_types value - * - */ -static enum chip_types get_nfcc_chip_type_dl(struct nfc_dev *nfc_dev) -{ - int ret = 0; - int cmd_length = 0; - uint8_t *cmd = nfc_dev->write_kbuf; - uint8_t *rsp = nfc_dev->read_kbuf; - enum chip_types chip_type = CHIP_UNKNOWN; - - *cmd++ = 0x00; - *cmd++ = 0x04; - *cmd++ = 0xF1; - *cmd++ = 0x00; - *cmd++ = 0x00; - *cmd++ = 0x00; - *cmd++ = 0x6E; - *cmd++ = 0xEF; - cmd_length = cmd - nfc_dev->write_kbuf; - - pr_debug("%s:Sending GET_VERSION cmd of size=%d\n", __func__, cmd_length); - ret = nfc_dev->nfc_write(nfc_dev, nfc_dev->write_kbuf, cmd_length, MAX_RETRY_COUNT); - if (ret <= 0) { - pr_err("%s: - nfc get version cmd error ret %d\n", __func__, ret); - goto err; - } - memset(rsp, 0x00, DL_GET_VERSION_RSP_LEN_2); - pr_debug("%s:Reading response of GET_VERSION cmd\n", __func__); - ret = nfc_dev->nfc_read(nfc_dev, rsp, DL_GET_VERSION_RSP_LEN_2, NCI_CMD_RSP_TIMEOUT); - if (ret <= 0) { - pr_err("%s: - nfc get version rsp error ret %d\n", __func__, ret); - goto err; - } - if (rsp[0] == FW_MSG_CMD_RSP && ret >= DL_GET_VERSION_RSP_LEN_2) { - - nfc_dev->fw_major_version = rsp[FW_MAJOR_VER_OFFSET]; - - if (rsp[FW_ROM_CODE_VER_OFFSET] == SN1XX_ROM_VER && - rsp[FW_MAJOR_VER_OFFSET] == SN1xx_MAJOR_VER) - chip_type = CHIP_SN1XX; - else if (rsp[FW_ROM_CODE_VER_OFFSET] == SN220_ROM_VER && - rsp[FW_MAJOR_VER_OFFSET] == SN220_MAJOR_VER) - chip_type = CHIP_SN220; - pr_info("%s:NFC Chip Type 0x%02x Rom Version 0x%02x FW Minor 0x%02x Major 0x%02x\n", - __func__, rsp[3], rsp[4], rsp[6], rsp[7]); - } -err: - return chip_type; -} - -/** - * get_nfcc_session_state_dl() - gets the session state - * @nfc_dev: nfc device data structure - * - * Performs get session command and determine - * the nfcc state based on session status. - * - * @Return nfcc state based on session status. - * NFC_STATE_FW_TEARED if sessionis not closed - * NFC_STATE_FW_DWL if session closed - * NFC_STATE_UNKNOWN in error cases. - */ -enum nfc_state_flags get_nfcc_session_state_dl(struct nfc_dev *nfc_dev) -{ - int ret = 0; - int cmd_length = 0; - uint8_t *cmd = nfc_dev->write_kbuf; - uint8_t *rsp = nfc_dev->read_kbuf; - enum nfc_state_flags nfc_state = NFC_STATE_UNKNOWN; - - *cmd++ = 0x00; - *cmd++ = 0x04; - *cmd++ = 0xF2; - *cmd++ = 0x00; - *cmd++ = 0x00; - *cmd++ = 0x00; - *cmd++ = 0xF5; - *cmd++ = 0x33; - cmd_length = cmd - nfc_dev->write_kbuf; - - pr_debug("%s:Sending GET_SESSION_STATE cmd of size=%d\n", __func__, cmd_length); - ret = nfc_dev->nfc_write(nfc_dev, nfc_dev->write_kbuf, cmd_length, MAX_RETRY_COUNT); - if (ret <= 0) { - pr_err("%s: - nfc get session cmd error ret %d\n", __func__, ret); - goto err; - } - memset(rsp, 0x00, DL_GET_SESSION_STATE_RSP_LEN); - pr_debug("%s:Reading response of GET_SESSION_STATE cmd\n", __func__); - ret = nfc_dev->nfc_read(nfc_dev, rsp, DL_GET_SESSION_STATE_RSP_LEN, NCI_CMD_RSP_TIMEOUT); - if (ret <= 0) { - pr_err("%s: - nfc get session rsp error ret %d\n", __func__, ret); - goto err; - } - if (rsp[0] != FW_MSG_CMD_RSP) { - pr_err("%s: - nfc invalid get session state rsp\n", __func__); - goto err; - } - pr_debug("Response bytes are %02x%02x%02x%02x%02x%02x%02x%02x", - rsp[0], rsp[1], rsp[2], rsp[3], rsp[4], rsp[5], rsp[6], rsp[7]); - /*verify fw in non-teared state */ - if (rsp[GET_SESSION_STS_OFF] != NFCC_SESSION_STS_CLOSED) { - pr_err("%s NFCC booted in FW teared state\n", __func__); - nfc_state = NFC_STATE_FW_TEARED; - } else { - pr_info("%s NFCC booted in FW DN mode\n", __func__); - nfc_state = NFC_STATE_FW_DWL; - } -err: - return nfc_state; -} - -/** - * get_nfcc_chip_type() - get nfcc chip type in nci mode. - * @nfc_dev: nfc device data structure. - * - * Function to perform nci core reset and extract - * chip type from the response. - * - * @Return: enum chip_types value - * - */ -static enum chip_types get_nfcc_chip_type(struct nfc_dev *nfc_dev) -{ - int ret = 0; - int cmd_length = 0; - uint8_t major_version = 0; - uint8_t rom_version = 0; - uint8_t *cmd = nfc_dev->write_kbuf; - uint8_t *rsp = nfc_dev->read_kbuf; - enum chip_types chip_type = CHIP_UNKNOWN; - - *cmd++ = 0x20; - *cmd++ = 0x00; - *cmd++ = 0x01; - *cmd++ = 0x00; - cmd_length = cmd - nfc_dev->write_kbuf; - - pr_debug("%s:Sending NCI Core Reset cmd of size=%d\n", __func__, cmd_length); - ret = nfc_dev->nfc_write(nfc_dev, nfc_dev->write_kbuf, cmd_length, NO_RETRY); - if (ret <= 0) { - pr_err("%s: - nfc nci core reset cmd error ret %d\n", __func__, ret); - goto err; - } - usleep_range(NCI_RESET_RESP_READ_DELAY, NCI_RESET_RESP_READ_DELAY + 100); - nfc_dev->nfc_enable_intr(nfc_dev); - - memset(rsp, 0x00, NCI_RESET_RSP_LEN); - pr_debug("%s:Reading NCI Core Reset rsp\n", __func__); - ret = nfc_dev->nfc_read(nfc_dev, rsp, NCI_RESET_RSP_LEN, NCI_CMD_RSP_TIMEOUT); - if (ret <= 0) { - pr_err("%s: - nfc nci core reset rsp error ret %d\n", __func__, ret); - goto err_disable_intr; - } - - pr_debug(" %s: nci core reset response 0x%02x%02x%02x%02x\n", - __func__, rsp[0], rsp[1], rsp[2], rsp[3]); - if (rsp[0] != NCI_MSG_RSP) { - /* reset response failed response*/ - pr_err("%s invalid nci core reset response", __func__); - goto err_disable_intr; - } - - memset(rsp, 0x00, NCI_RESET_NTF_LEN); - /* read nci rest response ntf */ - ret = nfc_dev->nfc_read(nfc_dev, rsp, NCI_RESET_NTF_LEN, NCI_CMD_RSP_TIMEOUT); - if (ret <= 0) { - pr_err("%s - nfc nci rest rsp ntf error status %d\n", __func__, ret); - goto err_disable_intr; - } - if (rsp[0] == NCI_MSG_NTF) { - /* read version info from NCI Reset Notification */ - rom_version = rsp[NCI_HDR_LEN + rsp[NCI_PAYLOAD_LEN_IDX] - 3]; - major_version = rsp[NCI_HDR_LEN + rsp[NCI_PAYLOAD_LEN_IDX] - 2]; - /* determine chip type based on version info */ - if (rom_version == SN1XX_ROM_VER && major_version == SN1xx_MAJOR_VER) - chip_type = CHIP_SN1XX; - else if (rom_version == SN220_ROM_VER && major_version == SN220_MAJOR_VER) - chip_type = CHIP_SN220; - pr_debug(" %s:NCI Core Reset ntf 0x%02x%02x%02x%02x\n", - __func__, rsp[0], rsp[1], rsp[2], rsp[3]); - } -err_disable_intr: - nfc_dev->nfc_disable_intr(nfc_dev); -err: - return chip_type; -} - -/** - * validate_download_gpio() - validate download gpio. - * @nfc_dev: nfc_dev device data structure. - * @chip_type: chip type of the platform. - * - * Validates dwnld gpio should configured for supported and - * should not be configured for unsupported platform. - * - * @Return: true if gpio validation successful ortherwise - * false if validation fails. - */ -static bool validate_download_gpio(struct nfc_dev *nfc_dev, enum chip_types chip_type) -{ - bool status = false; - struct platform_gpio *nfc_gpio; - - if (nfc_dev == NULL) { - pr_err("%s nfc devices structure is null\n"); - return status; - } - nfc_gpio = &nfc_dev->configs.gpio; - if (chip_type == CHIP_SN1XX) { - /* gpio should be configured for SN1xx */ - status = gpio_is_valid(nfc_gpio->dwl_req); - } else if (chip_type == CHIP_SN220) { - /* gpio should not be configured for SN220 */ - set_valid_gpio(nfc_gpio->dwl_req, 0); - gpio_free(nfc_gpio->dwl_req); - nfc_gpio->dwl_req = -EINVAL; - status = true; - } - return status; -} - -/* Check for availability of NFC controller hardware */ -int nfcc_hw_check(struct nfc_dev *nfc_dev) -{ - int ret = 0; - enum nfc_state_flags nfc_state = NFC_STATE_UNKNOWN; - enum chip_types chip_type = CHIP_UNKNOWN; - struct platform_gpio *nfc_gpio = &nfc_dev->configs.gpio; - - /*get fw version in nci mode*/ - gpio_set_ven(nfc_dev, 0); - gpio_set_ven(nfc_dev, 1); - chip_type = get_nfcc_chip_type(nfc_dev); - - /*get fw version in fw dwl mode*/ - if (chip_type == CHIP_UNKNOWN) { - nfc_dev->nfc_enable_intr(nfc_dev); - /*Chip is unknown, initially assume with fw dwl pin enabled*/ - set_valid_gpio(nfc_gpio->dwl_req, 1); - gpio_set_ven(nfc_dev, 0); - gpio_set_ven(nfc_dev, 1); - chip_type = get_nfcc_chip_type_dl(nfc_dev); - /*get the state of nfcc normal/teared in fw dwl mode*/ - } else { - nfc_state = NFC_STATE_NCI; - } - - /*validate gpio config required as per the chip*/ - if (!validate_download_gpio(nfc_dev, chip_type)) { - pr_info("%s gpio validation fail", __func__); - ret = -ENXIO; - goto err; - } - - /*check whether the NFCC is in FW DN or Teared state*/ - if (nfc_state != NFC_STATE_NCI) - nfc_state = get_nfcc_session_state_dl(nfc_dev); - - /*nfcc state specific operations */ - switch (nfc_state) { - case NFC_STATE_FW_TEARED: - pr_warn("%s: - NFCC FW Teared State\n", __func__); -#if IS_ENABLED(CONFIG_NXP_NFC_RECOVERY) - /* recovery neeeded only for SN1xx */ - if (chip_type == CHIP_SN1XX) { - if (do_recovery(nfc_dev) == STATUS_FAILED) - pr_debug("%s: - nfcc recoverey failed\n", __func__); - else - pr_debug("%s: - nfcc recovered successfully\n", __func__); - nfc_state = get_nfcc_session_state_dl(nfc_dev); - } -#endif - /*fallthrough*/ - case NFC_STATE_FW_DWL: - case NFC_STATE_NCI: - break; - case NFC_STATE_UNKNOWN: - default: - ret = -ENXIO; - pr_err("%s: - NFCC HW not available\n", __func__); - goto err; - }; - nfc_dev->nfc_state = nfc_state; - nfc_dev->nfc_ven_enabled = true; -err: - nfc_dev->nfc_disable_intr(nfc_dev); - set_valid_gpio(nfc_gpio->dwl_req, 0); - gpio_set_ven(nfc_dev, 0); - gpio_set_ven(nfc_dev, 1); - return ret; -} - int validate_nfc_state_nci(struct nfc_dev *nfc_dev) { struct platform_gpio *nfc_gpio = &nfc_dev->configs.gpio; if (!gpio_get_value(nfc_gpio->ven)) { - pr_err("VEN LOW - NFCC powered off\n"); + pr_err("%s: ven low - nfcc powered off\n", __func__); return -ENODEV; } if (get_valid_gpio(nfc_gpio->dwl_req) == 1) { - pr_err("FW download in-progress\n"); + pr_err("%s: fw download in-progress\n", __func__); return -EBUSY; } if (nfc_dev->nfc_state != NFC_STATE_NCI) { - pr_err("FW download state\n"); + pr_err("%s: fw download state\n", __func__); return -EBUSY; } return 0; diff --git a/nfc/common.h b/nfc/common.h index 363c6f3f83..c96958fe3a 100644 --- a/nfc/common.h +++ b/nfc/common.h @@ -1,7 +1,7 @@ /****************************************************************************** - * Copyright (C) 2015, The Linux Foundation. All rights reserved. - * Copyright (C) 2019-2021 NXP - * * + * Copyright (C) 2015, The Linux Foundation. All rights reserved. + * Copyright (C) 2019-2021 NXP + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or @@ -19,96 +19,68 @@ ******************************************************************************/ #ifndef _COMMON_H_ #define _COMMON_H_ -#include -#include -#include -#include -#include + #include -#include -#include #include "i2c_drv.h" -#define DEV_COUNT 1 /* Max device count for this driver */ -#define CLASS_NAME "nfc" /* i2c device class */ +/* Max device count for this driver */ +#define DEV_COUNT 1 +/* i2c device class */ +#define CLASS_NAME "nfc" -// NFC character device name, this will be in /dev/ -#define NFC_CHAR_DEV_NAME "pn553" +/* NFC character device name, this will be in /dev/ */ +#define NFC_CHAR_DEV_NAME "pn553" -// NCI packet details -#define NCI_MSG_CMD 0x20 -#define NCI_MSG_RSP 0x40 -#define NCI_MSG_NTF 0x60 -#define NCI_HDR_LEN 3 -#define NCI_PAYLOAD_IDX 3 -#define NCI_PAYLOAD_LEN_IDX 2 -/*Time to wait for first NCI rest response*/ -#define NCI_RESET_RESP_READ_DELAY (10000) // 10ms -#define NCI_RESET_RESP_TIMEOUT (500) // 500ms +/* NCI packet details */ +#define NCI_CMD (0x20) +#define NCI_RSP (0x40) +#define NCI_HDR_LEN (3) +#define NCI_HDR_IDX (0) +#define NCI_HDR_OID_IDX (1) +#define NCI_PAYLOAD_IDX (3) +#define NCI_PAYLOAD_LEN_IDX (2) -// FW DNLD packet details -#define FW_MSG_CMD_RSP 0x00 -#define FW_HDR_LEN 2 -#define FW_PAYLOAD_LEN_IDX 1 -#define FW_CRC_LEN 2 -#define FW_MIN_PAYLOAD_LEN 4 -#define MIN_NFC_DL_FRAME_SIZE 3 +/* FW DNLD packet details */ +#define DL_HDR_LEN (2) +#define DL_CRC_LEN (2) -#define NCI_RESET_CMD_LEN (4) -#define NCI_RESET_RSP_LEN (4) -#define NCI_RESET_NTF_LEN (13) +#define MAX_NCI_PAYLOAD_LEN (255) +#define MAX_NCI_BUFFER_SIZE (NCI_HDR_LEN + MAX_NCI_PAYLOAD_LEN) +#define MAX_DL_PAYLOAD_LEN (550) +#define MAX_DL_BUFFER_SIZE (DL_HDR_LEN + DL_CRC_LEN + \ + MAX_DL_PAYLOAD_LEN) -#define SN1XX_ROM_VER 0x01 -#define SN1xx_MAJOR_VER 0x10 -#define SN220_ROM_VER 0x01 -#define SN220_MAJOR_VER 0x01 -#define FW_ROM_CODE_VER_OFFSET 4 -#define FW_MAJOR_VER_OFFSET 7 -#define DL_GET_VERSION_CMD_LEN (8) -#define DL_GET_VERSION_RSP_LEN_1 (12) -#define DL_GET_VERSION_RSP_LEN_2 (20) +/* Retry count for normal write */ +#define NO_RETRY (1) +/* Maximum retry count for standby writes */ +#define MAX_RETRY_COUNT (3) +#define MAX_WRITE_IRQ_COUNT (5) +#define MAX_IRQ_WAIT_TIME (90) +#define WAKEUP_SRC_TIMEOUT (2000) -#define DL_RESET_CMD_LEN (8) -#define DL_GET_SESSION_STATE_CMD_LEN (8) -#define DL_GET_SESSION_STATE_RSP_LEN (8) -#define GET_SESSION_STS_OFF (3) -#define NFCC_SESSION_STS_CLOSED (0x0) -#define MAX_NCI_PAYLOAD_LEN (255) -#define MAX_BUFFER_SIZE (NCI_HDR_LEN + MAX_NCI_PAYLOAD_LEN) -#define MAX_DL_PAYLOAD_LEN (550) -#define MAX_DL_BUFFER_SIZE (FW_HDR_LEN + FW_CRC_LEN + MAX_DL_PAYLOAD_LEN) -// Maximum retry count for standby writes -#define MAX_RETRY_COUNT (3) -// Retry count for normal write -#define NO_RETRY (1) -#define MAX_IRQ_WAIT_TIME (90) -#define WAKEUP_SRC_TIMEOUT (2000) +/* command response timeout */ +#define NCI_CMD_RSP_TIMEOUT_MS (2000) +/* Time to wait for NFCC to be ready again after any change in the GPIO */ +#define NFC_GPIO_SET_WAIT_TIME_US (10000) +/* Time to wait for IRQ low during write 5*3ms */ +#define NFC_WRITE_IRQ_WAIT_TIME_US (3000) +/* Time to wait before retrying i2c/I3C writes */ +#define WRITE_RETRY_WAIT_TIME_US (1000) +/* Time to wait before retrying read for some specific usecases */ +#define READ_RETRY_WAIT_TIME_US (3500) +#define NFC_MAGIC (0xE9) -/*command response timeout*/ -#define NCI_CMD_RSP_TIMEOUT (2000) //2s -/*Time to wait for NFCC to be ready again after any change in the GPIO*/ -#define NFC_GPIO_SET_WAIT_TIME_USEC (10000) -/*Time to wait after soft reset via any NCI/DL cmd*/ -#define NFC_SOFT_RESET_WAIT_TIME_USEC (5000) -/*Time to wait before retrying i2c/I3C writes*/ -#define WRITE_RETRY_WAIT_TIME_USEC (1000) -/*Time to wait before retrying read for some specific usecases*/ -#define READ_RETRY_WAIT_TIME_USEC (3500) -#define NFC_MAGIC 0xE9 +/* Ioctls */ +/* The type should be aligned with MW HAL definitions */ +#define NFC_SET_PWR _IOW(NFC_MAGIC, 0x01, long) +#define ESE_SET_PWR _IOW(NFC_MAGIC, 0x02, long) +#define ESE_GET_PWR _IOR(NFC_MAGIC, 0x03, long) -/*Ioctls*/ -// The type should be aligned with MW HAL definitions -#define NFC_SET_PWR _IOW(NFC_MAGIC, 0x01, long) -#define ESE_SET_PWR _IOW(NFC_MAGIC, 0x02, long) -#define ESE_GET_PWR _IOR(NFC_MAGIC, 0x03, long) -/* NFC HAL can call this ioctl to get the current IRQ state */ -#define NFC_GET_IRQ_STATE _IO(NFC_MAGIC, 0x06) - -#define DTS_IRQ_GPIO_STR "nxp,pn544-irq" -#define DTS_VEN_GPIO_STR "nxp,pn544-ven" -#define DTS_FWDN_GPIO_STR "nxp,pn544-fw-dwnld" +#define DTS_IRQ_GPIO_STR "nxp,pn544-irq" +#define DTS_VEN_GPIO_STR "nxp,pn544-ven" +#define DTS_FWDN_GPIO_STR "nxp,pn544-fw-dwnld" enum nfcc_ioctl_request { /* NFC disable request with VEN LOW */ @@ -127,21 +99,21 @@ enum nfcc_ioctl_request { NFC_FW_DWL_LOW, }; -/*nfc platform interface type*/ +/* nfc platform interface type */ enum interface_flags { - /*I2C physical IF for NFCC */ + /* I2C physical IF for NFCC */ PLATFORM_IF_I2C = 0, }; -/*nfc state flags*/ +/* nfc state flags */ enum nfc_state_flags { - /*nfc in unknown state */ + /* nfc in unknown state */ NFC_STATE_UNKNOWN = 0, - /*nfc in download mode */ + /* nfc in download mode */ NFC_STATE_FW_DWL = 0x1, - /*nfc booted in NCI mode */ + /* nfc booted in NCI mode */ NFC_STATE_NCI = 0x2, - /*nfc booted in Fw teared mode */ + /* nfc booted in Fw teared mode */ NFC_STATE_FW_TEARED = 0x4, }; /* @@ -154,7 +126,7 @@ enum pm_state_flags { PM_STATE_IBI_BEFORE_RESUME, }; -/* Enum for GPIO values*/ +/* Enum for GPIO values */ enum gpio_values { GPIO_INPUT = 0x0, GPIO_OUTPUT = 0x1, @@ -163,35 +135,29 @@ enum gpio_values { GPIO_IRQ = 0x4, }; -// NFC GPIO variables +/* NFC GPIO variables */ struct platform_gpio { unsigned int irq; unsigned int ven; unsigned int dwl_req; }; -// NFC Struct to get all the required configs from DTS +/* NFC Struct to get all the required configs from DTS */ struct platform_configs { struct platform_gpio gpio; }; -//cold reset Features specific Parameters +/* cold reset Features specific Parameters */ struct cold_reset { - bool rsp_pending; /*cmd rsp pending status */ - bool in_progress; /*for cold reset when gurad timer in progress */ - bool reset_protection; /*reset protection enabled/disabled */ - uint8_t status; /*status from response buffer */ - uint8_t rst_prot_src; /*reset protection source (SPI, NFC) */ + bool rsp_pending; /* cmd rsp pending status */ + bool in_progress; /* for cold reset when gurad timer in progress */ + bool reset_protection; /* reset protection enabled/disabled */ + uint8_t status; /* status from response buffer */ + uint8_t rst_prot_src; /* reset protection source (SPI, NFC) */ struct timer_list timer; wait_queue_head_t read_wq; }; -enum chip_types { - CHIP_SN1XX = 0x01, - CHIP_SN220 = 0x02, - CHIP_UNKNOWN = 0xFF, -}; - /* Device specific structure */ struct nfc_dev { wait_queue_head_t read_wq; @@ -211,18 +177,17 @@ struct nfc_dev { uint8_t nfc_state; /* NFC VEN pin state */ bool nfc_ven_enabled; - /* current firmware major version */ - uint8_t fw_major_version; union { struct i2c_dev i2c_dev; }; struct platform_configs configs; struct cold_reset cold_reset; - /*function pointers for the common i2c functionality */ - int (*nfc_read)(struct nfc_dev *dev, char *buf, size_t count, int timeout); - int (*nfc_write)(struct nfc_dev *dev, const char *buf, const size_t count, - int max_retry_cnt); + /* function pointers for the common i2c functionality */ + int (*nfc_read)(struct nfc_dev *dev, char *buf, size_t count, + int timeout); + 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); }; @@ -233,12 +198,11 @@ 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, uint8_t interface); int nfc_misc_register(struct nfc_dev *nfc_dev, - const struct file_operations *nfc_fops, int count, char *devname, - char *classname); + const struct file_operations *nfc_fops, int count, + char *devname, char *classname); void nfc_misc_unregister(struct nfc_dev *nfc_dev, int count); int configure_gpio(unsigned int gpio, int flag); void gpio_set_ven(struct nfc_dev *nfc_dev, int value); void gpio_free_all(struct nfc_dev *nfc_dev); int validate_nfc_state_nci(struct nfc_dev *nfc_dev); -int nfcc_hw_check(struct nfc_dev *nfc_dev); -#endif //_COMMON_H_ +#endif /* _COMMON_H_ */ diff --git a/nfc/common_ese.c b/nfc/common_ese.c index cf63a15690..18b3d34e1f 100644 --- a/nfc/common_ese.c +++ b/nfc/common_ese.c @@ -1,6 +1,6 @@ /****************************************************************************** - * Copyright (C) 2020-2021 NXP - * * + * Copyright (C) 2020-2021 NXP + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or @@ -16,23 +16,17 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ******************************************************************************/ - -#include -#include -#include #include #include -#include -#include -#include -#include "common.h" +#include + #include "common_ese.h" static void cold_reset_gaurd_timer_callback(struct timer_list *t) { struct cold_reset *cold_reset = from_timer(cold_reset, t, timer); - pr_debug("%s: Enter\n", __func__); + pr_debug("%s: entry\n", __func__); cold_reset->in_progress = false; } @@ -41,18 +35,19 @@ static long start_cold_reset_guard_timer(struct cold_reset *cold_reset) long ret = -EINVAL; if (timer_pending(&cold_reset->timer) == 1) { - pr_debug("ese_cold_reset_guard_timer: delete pending timer\n"); + pr_debug("%s: delete pending timer\n", __func__); /* delete timer if already pending */ del_timer(&cold_reset->timer); } cold_reset->in_progress = true; timer_setup(&cold_reset->timer, cold_reset_gaurd_timer_callback, 0); ret = mod_timer(&cold_reset->timer, - jiffies + msecs_to_jiffies(ESE_CLD_RST_GUARD_TIME)); + jiffies + msecs_to_jiffies(ESE_CLD_RST_GUARD_TIME_MS)); return ret; } -static int send_cold_reset_protection_cmd(struct nfc_dev *nfc_dev, bool requestType) +static int send_cold_reset_protection_cmd(struct nfc_dev *nfc_dev, + bool requestType) { int ret = 0; int cmd_length = 0; @@ -62,30 +57,32 @@ static int send_cold_reset_protection_cmd(struct nfc_dev *nfc_dev, bool requestT mutex_lock(&nfc_dev->write_mutex); *cmd++ = NCI_PROP_MSG_CMD; - if (requestType) { /*reset protection*/ + if (requestType) { /* reset protection */ *cmd++ = RST_PROT_OID; *cmd++ = RST_PROT_PAYLOAD_SIZE; *cmd++ = (!cold_reset->reset_protection) ? 1 : 0; - } else { /*cold reset*/ + } else { /* cold reset */ *cmd++ = CLD_RST_OID; *cmd++ = CLD_RST_PAYLOAD_SIZE; } cmd_length = cmd - nfc_dev->write_kbuf; - ret = nfc_dev->nfc_write(nfc_dev, nfc_dev->write_kbuf, cmd_length, MAX_RETRY_COUNT); + ret = nfc_dev->nfc_write(nfc_dev, nfc_dev->write_kbuf, cmd_length, + MAX_RETRY_COUNT); if (ret != cmd_length) { ret = -EIO; - pr_err("%s : nfc_write returned %d\n", __func__, ret); - goto exit; + pr_err("%s: nfc_write returned %d\n", __func__, ret); + goto exit; } cmd = nfc_dev->write_kbuf; - if (requestType) { - pr_debug("%s: NxpNciX: %d > %02X%02X%02X%02X\n", __func__, ret, cmd[0], cmd[1], - cmd[2], cmd[3]); - } else { - pr_debug("%s: NxpNciX: %d > %02X%02X%02X\n", __func__, ret, cmd[0], cmd[1], - cmd[2]); - } + if (requestType) + pr_debug(" %s: NxpNciX: %d > 0x%02x%02x%02x%02x\n", __func__, + ret, cmd[NCI_HDR_IDX], cmd[NCI_HDR_OID_IDX], + cmd[NCI_PAYLOAD_LEN_IDX], cmd[NCI_PAYLOAD_IDX]); + else + pr_debug(" %s: NxpNciX: %d > 0x%02x%02x%02x\n", __func__, ret, + cmd[NCI_HDR_IDX], cmd[NCI_HDR_OID_IDX], + cmd[NCI_PAYLOAD_LEN_IDX]); exit: mutex_unlock(&nfc_dev->write_mutex); return ret; @@ -97,64 +94,71 @@ void wakeup_on_prop_rsp(struct nfc_dev *nfc_dev, uint8_t *buf) cold_reset->status = -EIO; if ((NCI_HDR_LEN + buf[NCI_PAYLOAD_LEN_IDX]) != NCI_PROP_MSG_RSP_LEN) - pr_err("%s: - invalid response for cold_reset/protection\n", __func__); + pr_err("%s: invalid response for cold_reset/protection\n", + __func__); else cold_reset->status = buf[NCI_PAYLOAD_IDX]; - pr_debug("%s NxpNciR : len = 4 > %02X%02X%02X%02X\n", __func__, buf[0], buf[1], - buf[2], buf[3]); + pr_debug(" %s: NxpNciR 0x%02x%02x%02x%02x\n", __func__, + buf[NCI_HDR_IDX], buf[NCI_HDR_OID_IDX], + buf[NCI_PAYLOAD_LEN_IDX], buf[NCI_PAYLOAD_IDX]); cold_reset->rsp_pending = false; wake_up_interruptible(&cold_reset->read_wq); } static int validate_cold_reset_protection_request(struct cold_reset *cold_reset, - unsigned long arg) + unsigned long arg) { int ret = 0; if (!cold_reset->reset_protection) { if (IS_RST_PROT_EN_REQ(arg) && IS_SRC_VALID_PROT(arg)) { - pr_debug("%s:req - reset protection enable\n", __func__); + pr_debug("%s: reset protection enable\n", __func__); } else if (IS_CLD_RST_REQ(arg) && IS_SRC_VALID(arg)) { - pr_debug("%s:req - cold reset\n", __func__); + pr_debug("%s: cold reset\n", __func__); } else if (IS_RST_PROT_DIS_REQ(arg) && IS_SRC_VALID_PROT(arg)) { - pr_debug("%s:req - reset protection already disable\n", __func__); + pr_debug("%s: reset protection already disable\n", + __func__); ret = -EINVAL; } else { - pr_err("%s:Operation not permitted\n", __func__); + pr_err("%s: operation not permitted\n", __func__); ret = -EPERM; } } else { - if (IS_RST_PROT_DIS_REQ(arg) - && IS_SRC(arg, cold_reset->rst_prot_src)) { - pr_debug("%s:req - disable reset protection from same src\n", __func__); - } else if (IS_CLD_RST_REQ(arg) - && IS_SRC(arg, cold_reset->rst_prot_src)) { - pr_debug("%s:req - cold reset from same source\n", __func__); - } else if (IS_RST_PROT_EN_REQ(arg) - && IS_SRC(arg, cold_reset->rst_prot_src)) { - pr_debug("%s:req - enable reset protection from same src\n", __func__); + if (IS_RST_PROT_DIS_REQ(arg) && + IS_SRC(arg, cold_reset->rst_prot_src)) { + pr_debug("%s: disable reset protection from same src\n", + __func__); + } else if (IS_CLD_RST_REQ(arg) && + IS_SRC(arg, cold_reset->rst_prot_src)) { + pr_debug("%s: cold reset from same source\n", __func__); + } else if (IS_RST_PROT_EN_REQ(arg) && + IS_SRC(arg, cold_reset->rst_prot_src)) { + pr_debug("%s: enable reset protection from same src\n", + __func__); } else { - pr_err("%s: Operation not permitted\n", __func__); + pr_err("%s: operation not permitted\n", __func__); ret = -EPERM; } } return ret; } -static int perform_cold_reset_protection(struct nfc_dev *nfc_dev, unsigned long arg) +static int perform_cold_reset_protection(struct nfc_dev *nfc_dev, + unsigned long arg) { int ret = 0; + int timeout = 0; struct file filp; char *rsp = nfc_dev->read_kbuf; 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); if (ret < 0) { - pr_err("%s: invalid cmd", __func__); + pr_err("%s: invalid cmd\n", __func__); return ret; } @@ -162,16 +166,16 @@ static int perform_cold_reset_protection(struct nfc_dev *nfc_dev, unsigned long 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); if (ret < 0) { - pr_err("%s: invalid cmd", __func__); + pr_err("%s: invalid cmd\n", __func__); goto err; } - /*check if cold reset already in progress */ + /* check if cold reset already in progress */ if (IS_CLD_RST_REQ(arg) && cold_reset->in_progress) { - pr_err("%s: cold reset already in progress", __func__); + pr_err("%s: cold reset already in progress\n", __func__); ret = -EBUSY; goto err; } @@ -179,65 +183,69 @@ static int perform_cold_reset_protection(struct nfc_dev *nfc_dev, unsigned long cold_reset->status = -EIO; cold_reset->rsp_pending = true; - /*enable interrupt before sending cmd, when devnode not opened by HAL */ + /* 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)); if (ret < 0) { - pr_err("failed to send cold reset/protection command\n"); + pr_err("%s: failed to send cold reset/protection cmd\n", + __func__); cold_reset->rsp_pending = false; goto err; } ret = 0; - /*start the cold reset guard timer */ + /* start the cold reset guard timer */ if (IS_CLD_RST_REQ(arg)) { - /*Guard timer not needed when OSU over NFC*/ + /* Guard timer not needed when OSU over NFC */ if (!(cold_reset->reset_protection && IS_SRC_NFC(arg))) { ret = start_cold_reset_guard_timer(cold_reset); if (ret) { - pr_err("%s: Error in mod_timer\n", __func__); + pr_err("%s: error in mod_timer\n", __func__); goto err; } } } + timeout = NCI_CMD_RSP_TIMEOUT_MS; do { - /* Read is pending from the HAL service which will complete the response */ + /* Read pending response form the HAL service */ if (nfc_dev_opened) { - if (!wait_event_interruptible_timeout - (cold_reset->read_wq, - cold_reset->rsp_pending == false, - msecs_to_jiffies(NCI_CMD_RSP_TIMEOUT))) { - pr_err("%s:cold reset/protection response timeout\n", __func__); + if (!wait_event_interruptible_timeout( + cold_reset->read_wq, + cold_reset->rsp_pending == false, + msecs_to_jiffies(timeout))) { + pr_err("%s: cold reset/prot response timeout\n", + __func__); ret = -EAGAIN; } } else { - /* Read data as NFC thread is not active */ + /* Read response here as NFC thread is not active */ filp.private_data = nfc_dev; if (nfc_dev->interface == PLATFORM_IF_I2C) { filp.f_flags &= ~O_NONBLOCK; - ret = nfc_dev->nfc_read(nfc_dev, rsp, 3, NCI_CMD_RSP_TIMEOUT); + ret = nfc_dev->nfc_read(nfc_dev, rsp, 3, + timeout); if (!ret) break; - usleep_range(READ_RETRY_WAIT_TIME_USEC, - READ_RETRY_WAIT_TIME_USEC + 500); + usleep_range(READ_RETRY_WAIT_TIME_US, + READ_RETRY_WAIT_TIME_US + 500); } } } while (ret == -ERESTARTSYS || ret == -EFAULT); - - if (ret == 0) { /* success case */ + timeout = ESE_CLD_RST_REBOOT_GUARD_TIME_MS; + if (ret == 0) { /* success case */ ret = cold_reset->status; if (IS_RST_PROT_REQ(arg)) { cold_reset->reset_protection = IS_RST_PROT_EN_REQ(arg); - cold_reset->rst_prot_src = - IS_RST_PROT_EN_REQ(arg) ? GET_SRC(arg) : SRC_NONE; + cold_reset->rst_prot_src = IS_RST_PROT_EN_REQ(arg) ? + GET_SRC(arg) : + SRC_NONE; /* wait for reboot guard timer */ - } else if (wait_event_interruptible_timeout - (cold_reset->read_wq, true, - msecs_to_jiffies(ESE_CLD_RST_REBOOT_GUARD_TIME)) == - 0) { - pr_info("%s: reboot guard timer timeout", __func__); + } else if (wait_event_interruptible_timeout( + cold_reset->read_wq, true, + msecs_to_jiffies(timeout)) == 0) { + pr_info("%s: reboot guard timer timeout\n", __func__); } } err: @@ -245,11 +253,15 @@ err: return ret; } -/* - * Power management of the eSE - * eSE and NFCC both are powered using VEN gpio, - * VEN HIGH - eSE and NFCC both are powered on - * VEN LOW - eSE and NFCC both are power down +/** + * nfc_ese_pwr() - power control for ese + * @nfc_dev: nfc device data structure + * @arg: mode that we want to move to + * + * Device power control. Depending on the arg value, device moves to + * different states, refer common_ese.h for args + * + * Return: -ENOIOCTLCMD if arg is not supported, 0 in any other case */ int nfc_ese_pwr(struct nfc_dev *nfc_dev, unsigned long arg) { @@ -257,7 +269,7 @@ int nfc_ese_pwr(struct nfc_dev *nfc_dev, unsigned long arg) struct platform_gpio *nfc_gpio = &nfc_dev->configs.gpio; if (arg == ESE_POWER_ON) { - /** + /* * Let's store the NFC VEN pin state * will check stored value in case of eSE power off request, * to find out if NFC MW also sent request to set VEN HIGH @@ -266,25 +278,28 @@ int nfc_ese_pwr(struct nfc_dev *nfc_dev, unsigned long arg) */ nfc_dev->nfc_ven_enabled = gpio_get_value(nfc_gpio->ven); if (!nfc_dev->nfc_ven_enabled) { - pr_debug("eSE HAL service setting ven HIGH\n"); + pr_debug("%s: ese hal service setting ven high\n", + __func__); gpio_set_ven(nfc_dev, 1); } else { - pr_debug("ven already HIGH\n"); + pr_debug("%s: ven already high\n", __func__); } } else if (arg == ESE_POWER_OFF) { if (!nfc_dev->nfc_ven_enabled) { - pr_debug("NFC not enabled, disabling ven\n"); + pr_debug("%s: nfc not enabled, disabling ven\n", + __func__); gpio_set_ven(nfc_dev, 0); } else { - pr_debug("keep ven high as NFC is enabled\n"); + pr_debug("%s: keep ven high as nfc is enabled\n", + __func__); } } else if (arg == ESE_POWER_STATE) { - // eSE get power state + /* eSE get power state */ ret = gpio_get_value(nfc_gpio->ven); } else if (IS_CLD_RST_REQ(arg) || IS_RST_PROT_REQ(arg)) { ret = perform_cold_reset_protection(nfc_dev, arg); } else { - pr_err("%s bad arg %lu\n", __func__, arg); + pr_err("%s: bad arg %lu\n", __func__, arg); ret = -ENOIOCTLCMD; } return ret; @@ -310,15 +325,15 @@ int perform_ese_cold_reset(unsigned long arg) if (IS_CLD_RST_REQ(arg) && IS_SRC_OTHER(arg)) { ret = nfc_ese_pwr(nfc_dev_legacy, arg); } else { - pr_err("%s : Operation not permitted\n", __func__); + pr_err("%s: operation not permitted\n", __func__); return -EPERM; } } - pr_debug("%s:%d exit, status:%lu", __func__, arg, ret); + pr_debug("%s: arg = %d ret = %lu\n", __func__, arg, ret); return ret; } EXPORT_SYMBOL(perform_ese_cold_reset); -#endif //ESE_LEGACY_INTERFACE +#endif /* ESE_LEGACY_INTERFACE */ void ese_cold_reset_release(struct nfc_dev *nfc_dev) { @@ -340,12 +355,12 @@ void common_ese_init(struct nfc_dev *nfc_dev) ese_cold_reset_release(nfc_dev); #ifdef ESE_LEGACY_INTERFACE nfc_dev_legacy = nfc_dev; -#endif //ESE_LEGACY_INTERFACE +#endif /* ESE_LEGACY_INTERFACE */ } void common_ese_exit(struct nfc_dev *nfc_dev) { #ifdef ESE_LEGACY_INTERFACE nfc_dev_legacy = NULL; -#endif //ESE_LEGACY_INTERFACE +#endif /* ESE_LEGACY_INTERFACE */ } diff --git a/nfc/common_ese.h b/nfc/common_ese.h index 46d8d2f27c..c8d563724b 100644 --- a/nfc/common_ese.h +++ b/nfc/common_ese.h @@ -1,6 +1,6 @@ /****************************************************************************** - * Copyright (C) 2020-2021 NXP - * * + * Copyright (C) 2020-2021 NXP + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or @@ -16,33 +16,32 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ******************************************************************************/ - #ifndef _COMMON_ESE_H_ #define _COMMON_ESE_H_ #include "common.h" -/*nci prop msg 1st byte*/ -#define NCI_PROP_MSG_GID 0x0F -#define NCI_PROP_MSG_CMD (NCI_MSG_CMD | NCI_PROP_MSG_GID) -#define NCI_PROP_MSG_RSP (NCI_MSG_RSP | NCI_PROP_MSG_GID) +/* nci prop msg 1st byte */ +#define NCI_PROP_MSG_GID 0x0F +#define NCI_PROP_MSG_CMD (NCI_CMD | NCI_PROP_MSG_GID) +#define NCI_PROP_MSG_RSP (NCI_RSP | NCI_PROP_MSG_GID) -/*nci prop msg 2nd byte*/ -#define CLD_RST_OID 0x1E -#define RST_PROT_OID 0x1F +/* nci prop msg 2nd byte */ +#define CLD_RST_OID 0x1E +#define RST_PROT_OID 0x1F -/*nci prop msg 3rd byte*/ -#define CLD_RST_PAYLOAD_SIZE 0x00 -#define RST_PROT_PAYLOAD_SIZE 0x01 +/* nci prop msg 3rd byte */ +#define CLD_RST_PAYLOAD_SIZE 0x00 +#define RST_PROT_PAYLOAD_SIZE 0x01 -/*nci prop msg response length*/ -#define NCI_PROP_MSG_RSP_LEN 0x04 +/* nci prop msg response length */ +#define NCI_PROP_MSG_RSP_LEN 0x04 -/*cold reset guard time to allow back to back cold reset after some time*/ -#define ESE_CLD_RST_GUARD_TIME (3000) //3s -/*guard time to reboot after reset*/ -#define ESE_CLD_RST_REBOOT_GUARD_TIME (50) //50ms -/*sources of reset protection and cold reset*/ +/* cold reset guard time to allow back to back cold reset after some time */ +#define ESE_CLD_RST_GUARD_TIME_MS (3000) +/* guard time to reboot after reset */ +#define ESE_CLD_RST_REBOOT_GUARD_TIME_MS (50) +/* sources of reset protection and cold reset */ enum reset_source { SRC_SPI = 0, SRC_NFC = 0x10, @@ -55,38 +54,41 @@ enum ese_ioctl_request { ESE_POWER_OFF, /* eSE POWER OFF */ ESE_POWER_STATE, /* eSE GET POWER STATE */ - /*ese reset requests from eSE service/hal/driver */ + /* ese reset requests from eSE service/hal/driver */ ESE_CLD_RST, /* eSE COLD RESET */ ESE_RST_PROT_EN, /* eSE RESET PROTECTION ENABLE */ ESE_RST_PROT_DIS, /* eSE RESET PROTECTION DISABLE */ - /*similar ese reset requests from nfc service/hal/driver */ + /* similar ese reset requests from nfc service/hal/driver */ ESE_CLD_RST_NFC = ESE_CLD_RST | SRC_NFC, ESE_RST_PROT_EN_NFC = ESE_RST_PROT_EN | SRC_NFC, ESE_RST_PROT_DIS_NFC = ESE_RST_PROT_DIS | SRC_NFC, - /*similar ese reset requests from other service/hal/driver */ + /* similar ese reset requests from other service/hal/driver */ ESE_CLD_RST_OTHER = ESE_CLD_RST | SRC_OTHER, }; -#define GET_SRC(arg) (arg & 0xF0) -#define IS_SRC(arg, src) (GET_SRC(arg) == src) -#define IS_SRC_SPI(arg) IS_SRC(arg, SRC_SPI) -#define IS_SRC_NFC(arg) IS_SRC(arg, SRC_NFC) -#define IS_SRC_OTHER(arg) IS_SRC(arg, SRC_OTHER) -#define IS_SRC_VALID(arg) (IS_SRC_SPI(arg) || IS_SRC_NFC(arg) || \ - IS_SRC_OTHER(arg)) -#define IS_SRC_VALID_PROT(arg) (IS_SRC_SPI(arg) || IS_SRC_NFC(arg)) +#define GET_SRC(arg) (arg & 0xF0) +#define IS_SRC(arg, src) (GET_SRC(arg) == src) +#define IS_SRC_SPI(arg) IS_SRC(arg, SRC_SPI) +#define IS_SRC_NFC(arg) IS_SRC(arg, SRC_NFC) +#define IS_SRC_OTHER(arg) IS_SRC(arg, SRC_OTHER) +#define IS_SRC_VALID(arg) (IS_SRC_SPI(arg) || \ + IS_SRC_NFC(arg) || \ + IS_SRC_OTHER(arg)) +#define IS_SRC_VALID_PROT(arg) (IS_SRC_SPI(arg) || \ + IS_SRC_NFC(arg)) -#define IS_RST(arg, type) ((arg & 0xF) == type) -#define IS_CLD_RST_REQ(arg) IS_RST(arg, ESE_CLD_RST) -#define IS_RST_PROT_EN_REQ(arg) IS_RST(arg, ESE_RST_PROT_EN) -#define IS_RST_PROT_DIS_REQ(arg) IS_RST(arg, ESE_RST_PROT_DIS) -#define IS_RST_PROT_REQ(arg) (IS_RST_PROT_EN_REQ(arg) || IS_RST_PROT_DIS_REQ(arg)) +#define IS_RST(arg, type) ((arg & 0xF) == type) +#define IS_CLD_RST_REQ(arg) IS_RST(arg, ESE_CLD_RST) +#define IS_RST_PROT_EN_REQ(arg) IS_RST(arg, ESE_RST_PROT_EN) +#define IS_RST_PROT_DIS_REQ(arg) IS_RST(arg, ESE_RST_PROT_DIS) +#define IS_RST_PROT_REQ(arg) (IS_RST_PROT_EN_REQ(arg) || \ + IS_RST_PROT_DIS_REQ(arg)) /* This macro evaluates to 1 if prop cmd response is received */ -#define IS_PROP_CMD_RSP(buf) \ - ((buf[0] == NCI_PROP_MSG_RSP) && ((buf[1] == CLD_RST_OID) || \ - (buf[1] == RST_PROT_OID))) +#define IS_PROP_CMD_RSP(buf) ((buf[0] == NCI_PROP_MSG_RSP) && \ + ((buf[1] == CLD_RST_OID) || \ + (buf[1] == RST_PROT_OID))) void wakeup_on_prop_rsp(struct nfc_dev *nfc_dev, uint8_t *buf); int nfc_ese_pwr(struct nfc_dev *nfc_dev, unsigned long arg); diff --git a/nfc/i2c_drv.c b/nfc/i2c_drv.c index d6768858d7..83a1ed5d9e 100644 --- a/nfc/i2c_drv.c +++ b/nfc/i2c_drv.c @@ -1,7 +1,7 @@ /****************************************************************************** - * Copyright (C) 2015, The Linux Foundation. All rights reserved. - * Copyright (C) 2013-2021 NXP - * * + * Copyright (C) 2015, The Linux Foundation. All rights reserved. + * Copyright (C) 2013-2021 NXP + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or @@ -34,15 +34,13 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include -#include + #include -#include #include #include #include -#include -#include "common.h" +#include + #include "common_ese.h" /** @@ -103,20 +101,19 @@ static irqreturn_t i2c_irq_handler(int irq, void *dev_id) return IRQ_HANDLED; } - int i2c_read(struct nfc_dev *nfc_dev, char *buf, size_t count, int timeout) { int ret; struct i2c_dev *i2c_dev = &nfc_dev->i2c_dev; struct platform_gpio *nfc_gpio = &nfc_dev->configs.gpio; - pr_debug("%s : reading %zu bytes.\n", __func__, count); + pr_debug("%s: reading %zu bytes.\n", __func__, count); - if (timeout > NCI_CMD_RSP_TIMEOUT) - timeout = NCI_CMD_RSP_TIMEOUT; + if (timeout > NCI_CMD_RSP_TIMEOUT_MS) + timeout = NCI_CMD_RSP_TIMEOUT_MS; - if (count > MAX_BUFFER_SIZE) - count = MAX_BUFFER_SIZE; + if (count > MAX_NCI_BUFFER_SIZE) + count = MAX_NCI_BUFFER_SIZE; if (!gpio_get_value(nfc_gpio->irq)) { while (1) { @@ -127,18 +124,23 @@ int i2c_read(struct nfc_dev *nfc_dev, char *buf, size_t count, int timeout) } if (!gpio_get_value(nfc_gpio->irq)) { if (timeout) { - ret = wait_event_interruptible_timeout(nfc_dev->read_wq, - !i2c_dev->irq_enabled, msecs_to_jiffies(timeout)); + ret = wait_event_interruptible_timeout( + nfc_dev->read_wq, + !i2c_dev->irq_enabled, + msecs_to_jiffies(timeout)); if (ret <= 0) { - pr_err("%s timeout/error in read\n", __func__); + pr_err("%s: timeout error\n", + __func__); goto err; } } else { - ret = wait_event_interruptible(nfc_dev->read_wq, + ret = wait_event_interruptible( + nfc_dev->read_wq, !i2c_dev->irq_enabled); if (ret) { - pr_err("%s error wakeup of read wq\n", __func__); + pr_err("%s: err wakeup of wq\n", + __func__); goto err; } } @@ -170,10 +172,12 @@ int i2c_read(struct nfc_dev *nfc_dev, char *buf, size_t count, int timeout) if (nfc_dev->cold_reset.rsp_pending) { if (IS_PROP_CMD_RSP(buf)) { /* Read data */ - ret = i2c_master_recv(nfc_dev->i2c_dev.client, &buf[NCI_PAYLOAD_IDX], - buf[NCI_PAYLOAD_LEN_IDX]); + ret = i2c_master_recv(nfc_dev->i2c_dev.client, + &buf[NCI_PAYLOAD_IDX], + buf[NCI_PAYLOAD_LEN_IDX]); if (ret <= 0) { - pr_err("%s: error reading cold reset/prot rsp header\n", __func__); + pr_err("%s: error reading cold rst/prot rsp\n", + __func__); goto err; } wakeup_on_prop_rsp(nfc_dev, buf); @@ -194,19 +198,38 @@ int i2c_write(struct nfc_dev *nfc_dev, const char *buf, size_t count, { int ret = -EINVAL; int retry_cnt; + struct platform_gpio *nfc_gpio = &nfc_dev->configs.gpio; if (count > MAX_DL_BUFFER_SIZE) count = MAX_DL_BUFFER_SIZE; - pr_debug("%s : writing %zu bytes.\n", __func__, count); + pr_debug("%s: writing %zu bytes.\n", __func__, count); + /* + * Wait for any pending read for max 15ms before write + * This is to avoid any packet corruption during read, when + * the host cmds resets NFCC during any parallel read operation + */ + for (retry_cnt = 1; retry_cnt <= MAX_WRITE_IRQ_COUNT; retry_cnt++) { + if (gpio_get_value(nfc_gpio->irq)) { + pr_warn("%s: irq high during write, wait\n", __func__); + usleep_range(NFC_WRITE_IRQ_WAIT_TIME_US, + NFC_WRITE_IRQ_WAIT_TIME_US + 100); + } else { + break; + } + if (retry_cnt == MAX_WRITE_IRQ_COUNT && + gpio_get_value(nfc_gpio->irq)) { + pr_warn("%s: allow after maximum wait\n", __func__); + } + } for (retry_cnt = 1; retry_cnt <= max_retry_cnt; retry_cnt++) { ret = i2c_master_send(nfc_dev->i2c_dev.client, buf, count); if (ret <= 0) { - pr_warn("%s: failed to write ret(%d), Maybe in Standby Mode - Retry(%d)\n", __func__, - ret, retry_cnt); - usleep_range(WRITE_RETRY_WAIT_TIME_USEC, - WRITE_RETRY_WAIT_TIME_USEC + 100); + pr_warn("%s: write failed ret(%d), maybe in standby\n", + __func__, ret); + usleep_range(WRITE_RETRY_WAIT_TIME_US, + WRITE_RETRY_WAIT_TIME_US + 100); } else if (ret != count) { pr_err("%s: failed to write %d\n", __func__, ret); ret = -EIO; @@ -216,21 +239,21 @@ int i2c_write(struct nfc_dev *nfc_dev, const char *buf, size_t count, return ret; } -ssize_t nfc_i2c_dev_read(struct file *filp, char __user *buf, - size_t count, loff_t *offset) +ssize_t nfc_i2c_dev_read(struct file *filp, char __user *buf, size_t count, + loff_t *offset) { - int ret = 0; + int ret; struct nfc_dev *nfc_dev = (struct nfc_dev *)filp->private_data; if (filp->f_flags & O_NONBLOCK) { - pr_err(":f_falg has O_NONBLOCK. EAGAIN\n"); + pr_err("%s: f_flags has nonblock. try again\n", __func__); return -EAGAIN; } mutex_lock(&nfc_dev->read_mutex); ret = i2c_read(nfc_dev, nfc_dev->read_kbuf, count, 0); if (ret > 0) { if (copy_to_user(buf, nfc_dev->read_kbuf, ret)) { - pr_warn("%s : failed to copy to user space\n", __func__); + pr_warn("%s: failed to copy to user space\n", __func__); ret = -EFAULT; } } @@ -239,9 +262,9 @@ ssize_t nfc_i2c_dev_read(struct file *filp, char __user *buf, } ssize_t nfc_i2c_dev_write(struct file *filp, const char __user *buf, - size_t count, loff_t *offset) + size_t count, loff_t *offset) { - int ret = 0; + int ret; struct nfc_dev *nfc_dev = (struct nfc_dev *)filp->private_data; if (count > MAX_DL_BUFFER_SIZE) @@ -249,7 +272,7 @@ ssize_t nfc_i2c_dev_write(struct file *filp, const char __user *buf, mutex_lock(&nfc_dev->write_mutex); 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__); mutex_unlock(&nfc_dev->write_mutex); return -EFAULT; } @@ -277,15 +300,15 @@ int nfc_i2c_dev_probe(struct i2c_client *client, const struct i2c_device_id *id) struct platform_gpio *nfc_gpio = &nfc_configs.gpio; pr_debug("%s: enter\n", __func__); - /*retrieve details of gpios from dt */ + /* retrieve details of gpios from dt */ ret = nfc_parse_dt(&client->dev, &nfc_configs, PLATFORM_IF_I2C); if (ret) { - pr_err("%s : failed to parse dt\n", __func__); + pr_err("%s: failed to parse dt\n", __func__); goto err; } if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { - pr_err("%s : need I2C_FUNC_I2C\n", __func__); + pr_err("%s: need I2C_FUNC_I2C\n", __func__); ret = -ENODEV; goto err; } @@ -294,15 +317,15 @@ int nfc_i2c_dev_probe(struct i2c_client *client, const struct i2c_device_id *id) ret = -ENOMEM; goto err; } - nfc_dev->read_kbuf = kzalloc(MAX_BUFFER_SIZE, GFP_DMA | GFP_KERNEL); + nfc_dev->read_kbuf = kzalloc(MAX_NCI_BUFFER_SIZE, GFP_DMA | GFP_KERNEL); if (!nfc_dev->read_kbuf) { ret = -ENOMEM; - goto err; + goto err_free_nfc_dev; } nfc_dev->write_kbuf = kzalloc(MAX_DL_BUFFER_SIZE, GFP_DMA | GFP_KERNEL); if (!nfc_dev->write_kbuf) { ret = -ENOMEM; - goto err; + goto err_free_read_kbuf; } nfc_dev->interface = PLATFORM_IF_I2C; nfc_dev->nfc_state = NFC_STATE_NCI; @@ -312,26 +335,28 @@ int nfc_i2c_dev_probe(struct i2c_client *client, const struct i2c_device_id *id) nfc_dev->nfc_write = i2c_write; nfc_dev->nfc_enable_intr = i2c_enable_irq; nfc_dev->nfc_disable_intr = i2c_disable_irq; - nfc_dev->fw_major_version = 0; ret = configure_gpio(nfc_gpio->ven, GPIO_OUTPUT); if (ret) { - pr_err("%s: unable to request nfc reset gpio [%d]\n", __func__, nfc_gpio->ven); - goto err; + pr_err("%s: unable to request nfc reset gpio [%d]\n", __func__, + nfc_gpio->ven); + goto err_free_write_kbuf; } ret = configure_gpio(nfc_gpio->irq, GPIO_IRQ); if (ret <= 0) { - pr_err("%s: unable to request nfc irq gpio [%d]\n", __func__, nfc_gpio->irq); - goto err; + pr_err("%s: unable to request nfc irq gpio [%d]\n", __func__, + nfc_gpio->irq); + goto err_free_gpio; } client->irq = ret; ret = configure_gpio(nfc_gpio->dwl_req, GPIO_OUTPUT); if (ret) { - pr_err("%s: unable to request nfc firm downl gpio [%d]\n", __func__, - nfc_gpio->dwl_req); + pr_err("%s: unable to request nfc firm downl gpio [%d]\n", + __func__, nfc_gpio->dwl_req); } - /*copy the retrieved gpio details from DT */ - memcpy(&nfc_dev->configs, &nfc_configs, sizeof(struct platform_configs)); + /* copy the retrieved gpio details from DT */ + memcpy(&nfc_dev->configs, &nfc_configs, + sizeof(struct platform_configs)); /* init mutex and queues */ init_waitqueue_head(&nfc_dev->read_wq); @@ -347,28 +372,23 @@ int nfc_i2c_dev_probe(struct i2c_client *client, const struct i2c_device_id *id) goto err_mutex_destroy; } /* interrupt initializations */ - pr_info("%s : requesting IRQ %d\n", __func__, client->irq); + pr_info("%s: requesting IRQ %d\n", __func__, client->irq); i2c_dev->irq_enabled = true; - ret = request_irq(client->irq, i2c_irq_handler, - IRQF_TRIGGER_HIGH, client->name, nfc_dev); + ret = request_irq(client->irq, i2c_irq_handler, IRQF_TRIGGER_HIGH, + client->name, nfc_dev); if (ret) { pr_err("%s: request_irq failed\n", __func__); goto err_nfc_misc_unregister; } i2c_disable_irq(nfc_dev); - - ret = nfcc_hw_check(nfc_dev); - if (ret != 0) { - pr_err("nfc hw check failed ret %d\n", ret); - goto err_nfc_misc_unregister; - } - + gpio_set_ven(nfc_dev, 1); + gpio_set_ven(nfc_dev, 0); + gpio_set_ven(nfc_dev, 1); device_init_wakeup(&client->dev, true); - device_set_wakeup_capable(&client->dev, true); i2c_set_clientdata(client, nfc_dev); i2c_dev->irq_wake_up = false; - pr_info("%s probing nfc i2c successfully", __func__); + pr_info("%s: probing nfc i2c successfully\n", __func__); return 0; err_nfc_misc_unregister: nfc_misc_unregister(nfc_dev, DEV_COUNT); @@ -376,11 +396,15 @@ err_mutex_destroy: mutex_destroy(&nfc_dev->dev_ref_mutex); mutex_destroy(&nfc_dev->read_mutex); mutex_destroy(&nfc_dev->write_mutex); -err: +err_free_gpio: gpio_free_all(nfc_dev); - kfree(nfc_dev->read_kbuf); +err_free_write_kbuf: kfree(nfc_dev->write_kbuf); +err_free_read_kbuf: + kfree(nfc_dev->read_kbuf); +err_free_nfc_dev: kfree(nfc_dev); +err: pr_err("%s: probing not successful, check hardware\n", __func__); return ret; } @@ -439,19 +463,18 @@ int nfc_i2c_dev_resume(struct device *device) return 0; } -static const struct i2c_device_id nfc_i2c_dev_id[] = { - {NFC_I2C_DEV_ID, 0}, - {} -}; +static const struct i2c_device_id nfc_i2c_dev_id[] = { { NFC_I2C_DEV_ID, 0 }, + {} }; static const struct of_device_id nfc_i2c_dev_match_table[] = { - {.compatible = NFC_I2C_DRV_STR,}, + { + .compatible = NFC_I2C_DRV_STR, + }, {} }; -static const struct dev_pm_ops nfc_i2c_dev_pm_ops = { - SET_SYSTEM_SLEEP_PM_OPS(nfc_i2c_dev_suspend, nfc_i2c_dev_resume) -}; +static const struct dev_pm_ops nfc_i2c_dev_pm_ops = { SET_SYSTEM_SLEEP_PM_OPS( + nfc_i2c_dev_suspend, nfc_i2c_dev_resume) }; static struct i2c_driver nfc_i2c_dev_driver = { .id_table = nfc_i2c_dev_id, @@ -471,10 +494,10 @@ static int __init nfc_i2c_dev_init(void) { int ret = 0; - pr_info("Loading NXP NFC I2C driver\n"); + pr_info("%s: Loading NXP NFC I2C driver\n", __func__); ret = i2c_add_driver(&nfc_i2c_dev_driver); if (ret != 0) - pr_err("NFC I2C add driver error ret %d\n", ret); + pr_err("%s: NFC I2C add driver error ret %d\n", __func__, ret); return ret; } @@ -482,7 +505,7 @@ module_init(nfc_i2c_dev_init); static void __exit nfc_i2c_dev_exit(void) { - pr_info("Unloading NXP NFC I2C driver\n"); + pr_info("%s: Unloading NXP NFC I2C driver\n", __func__); i2c_del_driver(&nfc_i2c_dev_driver); } diff --git a/nfc/i2c_drv.h b/nfc/i2c_drv.h index 47b8884687..1508fd4163 100644 --- a/nfc/i2c_drv.h +++ b/nfc/i2c_drv.h @@ -1,7 +1,7 @@ /****************************************************************************** - * Copyright (C) 2015, The Linux Foundation. All rights reserved. - * Copyright (C) 2019-2021 NXP - * * + * Copyright (C) 2015, The Linux Foundation. All rights reserved. + * Copyright (C) 2019-2021 NXP + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or @@ -19,16 +19,17 @@ ******************************************************************************/ #ifndef _I2C_DRV_H_ #define _I2C_DRV_H_ + #include -/*kept same as dts */ -#define NFC_I2C_DRV_STR "nxp,pn544" -#define NFC_I2C_DEV_ID "pn553" +/* kept same as dts */ +#define NFC_I2C_DRV_STR "nxp,pn544" +#define NFC_I2C_DEV_ID "pn553" -//Interface specific parameters +/* Interface specific parameters */ struct i2c_dev { struct i2c_client *client; - /*IRQ parameters */ + /* IRQ parameters */ bool irq_enabled; spinlock_t irq_enabled_lock; /* NFC_IRQ wake-up state */ @@ -42,4 +43,4 @@ 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); -#endif //_I2C_DRV_H_ +#endif /* _I2C_DRV_H_ */