summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2017-04-21 15:29:40 -0400
committerDavid S. Miller <davem@davemloft.net>2017-04-21 15:29:40 -0400
commit69e3948aaa559670da2662ad9d5cbc782bfc6885 (patch)
tree9cc3ef9f538b813d53a31056a93f8e56401569f7
parentea8ffc0818d8a47ffda423f61f1d8ad1caca8986 (diff)
parent4ea206395d3aede32bab94a75ec573530486fa44 (diff)
downloadlinux-69e3948aaa559670da2662ad9d5cbc782bfc6885.tar.gz
linux-69e3948aaa559670da2662ad9d5cbc782bfc6885.tar.bz2
linux-69e3948aaa559670da2662ad9d5cbc782bfc6885.zip
Merge tag 'nfc-next-4.12-1' of git://git.kernel.org/pub/scm/linux/kernel/git/sameo/nfc-next
Samuel Ortiz says: ==================== NFC 4.12 pull request This is the NFC pull request for 4.12. We have: - Improvements for the pn533 command queue handling and device registration order. - Removal of platform data for the pn544 and st21nfca drivers. - Additional device tree options to support more trf7970a hardware options. - Support for Sony's RC-S380P through the port100 driver. - Removal of the obsolte nfcwilink driver. - Headers inclusion cleanups (miscdevice.h, unaligned.h) for many drivers. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--Documentation/devicetree/bindings/net/nfc/trf7970a.txt8
-rw-r--r--MAINTAINERS2
-rw-r--r--drivers/nfc/Kconfig11
-rw-r--r--drivers/nfc/Makefile1
-rw-r--r--drivers/nfc/fdp/i2c.c6
-rw-r--r--drivers/nfc/nfcmrvl/fw_dnld.c7
-rw-r--r--drivers/nfc/nfcmrvl/spi.c6
-rw-r--r--drivers/nfc/nfcwilink.c578
-rw-r--r--drivers/nfc/nxp-nci/firmware.c2
-rw-r--r--drivers/nfc/nxp-nci/i2c.c7
-rw-r--r--drivers/nfc/pn533/i2c.c34
-rw-r--r--drivers/nfc/pn533/pn533.c82
-rw-r--r--drivers/nfc/pn533/pn533.h1
-rw-r--r--drivers/nfc/pn533/usb.c8
-rw-r--r--drivers/nfc/pn544/i2c.c221
-rw-r--r--drivers/nfc/port100.c44
-rw-r--r--drivers/nfc/st21nfca/core.c12
-rw-r--r--drivers/nfc/st21nfca/i2c.c123
-rw-r--r--drivers/nfc/trf7970a.c98
-rw-r--r--include/linux/platform_data/pn544.h43
-rw-r--r--include/linux/platform_data/st21nfca.h33
-rw-r--r--include/net/nfc/nfc.h1
-rw-r--r--net/nfc/netlink.c24
23 files changed, 289 insertions, 1063 deletions
diff --git a/Documentation/devicetree/bindings/net/nfc/trf7970a.txt b/Documentation/devicetree/bindings/net/nfc/trf7970a.txt
index 32b35a07abe4..c627bbb3009e 100644
--- a/Documentation/devicetree/bindings/net/nfc/trf7970a.txt
+++ b/Documentation/devicetree/bindings/net/nfc/trf7970a.txt
@@ -5,8 +5,8 @@ Required properties:
- spi-max-frequency: Maximum SPI frequency (<= 2000000).
- interrupt-parent: phandle of parent interrupt handler.
- interrupts: A single interrupt specifier.
-- ti,enable-gpios: Two GPIO entries used for 'EN' and 'EN2' pins on the
- TRF7970A.
+- ti,enable-gpios: One or two GPIO entries used for 'EN' and 'EN2' pins on the
+ TRF7970A. EN2 is optional.
- vin-supply: Regulator for supply voltage to VIN pin
Optional SoC Specific Properties:
@@ -21,6 +21,8 @@ Optional SoC Specific Properties:
- t5t-rmb-extra-byte-quirk: Specify that the trf7970a has the erratum
where an extra byte is returned by Read Multiple Block commands issued
to Type 5 tags.
+- vdd-io-supply: Regulator specifying voltage for vdd-io
+- clock-frequency: Set to specify that the input frequency to the trf7970a is 13560000Hz or 27120000Hz
Example (for ARM-based BeagleBone with TRF7970A on SPI1):
@@ -39,10 +41,12 @@ Example (for ARM-based BeagleBone with TRF7970A on SPI1):
<&gpio2 5 GPIO_ACTIVE_LOW>;
vin-supply = <&ldo3_reg>;
vin-voltage-override = <5000000>;
+ vdd-io-supply = <&ldo2_reg>;
autosuspend-delay = <30000>;
irq-status-read-quirk;
en2-rf-quirk;
t5t-rmb-extra-byte-quirk;
+ clock-frequency = <27120000>;
status = "okay";
};
};
diff --git a/MAINTAINERS b/MAINTAINERS
index 39aa09100a48..700d8906ff15 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -8876,8 +8876,6 @@ S: Supported
F: drivers/net/ethernet/qlogic/netxen/
NFC SUBSYSTEM
-M: Lauro Ramos Venancio <lauro.venancio@openbossa.org>
-M: Aloisio Almeida Jr <aloisio.almeida@openbossa.org>
M: Samuel Ortiz <sameo@linux.intel.com>
L: linux-wireless@vger.kernel.org
L: linux-nfc@lists.01.org (subscribers-only)
diff --git a/drivers/nfc/Kconfig b/drivers/nfc/Kconfig
index 9d2369269abf..c4208487fadc 100644
--- a/drivers/nfc/Kconfig
+++ b/drivers/nfc/Kconfig
@@ -5,17 +5,6 @@
menu "Near Field Communication (NFC) devices"
depends on NFC
-config NFC_WILINK
- tristate "Texas Instruments NFC WiLink driver"
- depends on TI_ST && NFC_NCI
- help
- This enables the NFC driver for Texas Instrument's BT/FM/GPS/NFC
- combo devices. This makes use of shared transport line discipline
- core driver to communicate with the NFC core of the combo chip.
-
- Say Y here to compile support for Texas Instrument's NFC WiLink driver
- into the kernel or say M to compile it as module.
-
config NFC_TRF7970A
tristate "Texas Instruments TRF7970a NFC driver"
depends on SPI && NFC_DIGITAL
diff --git a/drivers/nfc/Makefile b/drivers/nfc/Makefile
index bab8ef06ae35..640b7274371c 100644
--- a/drivers/nfc/Makefile
+++ b/drivers/nfc/Makefile
@@ -6,7 +6,6 @@ obj-$(CONFIG_NFC_FDP) += fdp/
obj-$(CONFIG_NFC_PN544) += pn544/
obj-$(CONFIG_NFC_MICROREAD) += microread/
obj-$(CONFIG_NFC_PN533) += pn533/
-obj-$(CONFIG_NFC_WILINK) += nfcwilink.o
obj-$(CONFIG_NFC_MEI_PHY) += mei_phy.o
obj-$(CONFIG_NFC_SIM) += nfcsim.o
obj-$(CONFIG_NFC_PORT100) += port100.o
diff --git a/drivers/nfc/fdp/i2c.c b/drivers/nfc/fdp/i2c.c
index 5e797d5c38ed..712936f5d2d6 100644
--- a/drivers/nfc/fdp/i2c.c
+++ b/drivers/nfc/fdp/i2c.c
@@ -210,14 +210,14 @@ static irqreturn_t fdp_nci_i2c_irq_thread_fn(int irq, void *phy_id)
struct sk_buff *skb;
int r;
- client = phy->i2c_dev;
- dev_dbg(&client->dev, "%s\n", __func__);
-
if (!phy || irq != phy->i2c_dev->irq) {
WARN_ON_ONCE(1);
return IRQ_NONE;
}
+ client = phy->i2c_dev;
+ dev_dbg(&client->dev, "%s\n", __func__);
+
r = fdp_nci_i2c_read(phy, &skb);
if (r == -EREMOTEIO)
diff --git a/drivers/nfc/nfcmrvl/fw_dnld.c b/drivers/nfc/nfcmrvl/fw_dnld.c
index f8dcdf4b24f6..c38bdd6a5a82 100644
--- a/drivers/nfc/nfcmrvl/fw_dnld.c
+++ b/drivers/nfc/nfcmrvl/fw_dnld.c
@@ -17,7 +17,7 @@
*/
#include <linux/module.h>
-#include <linux/unaligned/access_ok.h>
+#include <asm/unaligned.h>
#include <linux/firmware.h>
#include <linux/nfc.h>
#include <net/nfc/nci.h>
@@ -281,12 +281,11 @@ static int process_state_fw_dnld(struct nfcmrvl_private *priv,
return -EINVAL;
}
skb_pull(skb, 1);
- memcpy(&len, skb->data, 2);
+ len = get_unaligned_le16(skb->data);
skb_pull(skb, 2);
+ comp_len = get_unaligned_le16(skb->data);
memcpy(&comp_len, skb->data, 2);
skb_pull(skb, 2);
- len = get_unaligned_le16(&len);
- comp_len = get_unaligned_le16(&comp_len);
if (((~len) & 0xFFFF) != comp_len) {
nfc_err(priv->dev, "bad len complement: %x %x %x",
len, comp_len, (~len & 0xFFFF));
diff --git a/drivers/nfc/nfcmrvl/spi.c b/drivers/nfc/nfcmrvl/spi.c
index a7faa0bcc01e..8e0ddb434770 100644
--- a/drivers/nfc/nfcmrvl/spi.c
+++ b/drivers/nfc/nfcmrvl/spi.c
@@ -26,7 +26,6 @@
#include <net/nfc/nci.h>
#include <net/nfc/nci_core.h>
#include <linux/spi/spi.h>
-#include <linux/gpio.h>
#include "nfcmrvl.h"
#define SPI_WAIT_HANDSHAKE 1
@@ -96,10 +95,9 @@ static int nfcmrvl_spi_nci_send(struct nfcmrvl_private *priv,
/* Send the SPI packet */
err = nci_spi_send(drv_data->nci_spi, &drv_data->handshake_completion,
skb);
- if (err != 0) {
+ if (err)
nfc_err(priv->dev, "spi_send failed %d", err);
- kfree_skb(skb);
- }
+
return err;
}
diff --git a/drivers/nfc/nfcwilink.c b/drivers/nfc/nfcwilink.c
deleted file mode 100644
index 3fbd18b8e473..000000000000
--- a/drivers/nfc/nfcwilink.c
+++ /dev/null
@@ -1,578 +0,0 @@
-/*
- * Texas Instrument's NFC Driver For Shared Transport.
- *
- * NFC Driver acts as interface between NCI core and
- * TI Shared Transport Layer.
- *
- * Copyright (C) 2011 Texas Instruments, Inc.
- *
- * Written by Ilan Elias <ilane@ti.com>
- *
- * Acknowledgements:
- * This file is based on btwilink.c, which was written
- * by Raja Mani and Pavan Savoy.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
- *
- */
-#include <linux/platform_device.h>
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/firmware.h>
-#include <linux/nfc.h>
-#include <net/nfc/nci.h>
-#include <net/nfc/nci_core.h>
-#include <linux/ti_wilink_st.h>
-
-#define NFCWILINK_CHNL 12
-#define NFCWILINK_OPCODE 7
-#define NFCWILINK_MAX_FRAME_SIZE 300
-#define NFCWILINK_HDR_LEN 4
-#define NFCWILINK_OFFSET_LEN_IN_HDR 1
-#define NFCWILINK_LEN_SIZE 2
-#define NFCWILINK_REGISTER_TIMEOUT 8000 /* 8 sec */
-#define NFCWILINK_CMD_TIMEOUT 5000 /* 5 sec */
-
-#define BTS_FILE_NAME_MAX_SIZE 40
-#define BTS_FILE_HDR_MAGIC 0x42535442
-#define BTS_FILE_CMD_MAX_LEN 0xff
-#define BTS_FILE_ACTION_TYPE_SEND_CMD 1
-
-#define NCI_VS_NFCC_INFO_CMD_GID 0x2f
-#define NCI_VS_NFCC_INFO_CMD_OID 0x12
-#define NCI_VS_NFCC_INFO_RSP_GID 0x4f
-#define NCI_VS_NFCC_INFO_RSP_OID 0x12
-
-struct nfcwilink_hdr {
- __u8 chnl;
- __u8 opcode;
- __le16 len;
-} __packed;
-
-struct nci_vs_nfcc_info_cmd {
- __u8 gid;
- __u8 oid;
- __u8 plen;
-} __packed;
-
-struct nci_vs_nfcc_info_rsp {
- __u8 gid;
- __u8 oid;
- __u8 plen;
- __u8 status;
- __u8 hw_id;
- __u8 sw_ver_x;
- __u8 sw_ver_z;
- __u8 patch_id;
-} __packed;
-
-struct bts_file_hdr {
- __le32 magic;
- __le32 ver;
- __u8 rfu[24];
- __u8 actions[0];
-} __packed;
-
-struct bts_file_action {
- __le16 type;
- __le16 len;
- __u8 data[0];
-} __packed;
-
-struct nfcwilink {
- struct platform_device *pdev;
- struct nci_dev *ndev;
- unsigned long flags;
-
- int st_register_cb_status;
- long (*st_write) (struct sk_buff *);
-
- struct completion completed;
-
- struct nci_vs_nfcc_info_rsp nfcc_info;
-};
-
-/* NFCWILINK driver flags */
-enum {
- NFCWILINK_RUNNING,
- NFCWILINK_FW_DOWNLOAD,
-};
-
-static int nfcwilink_send(struct nci_dev *ndev, struct sk_buff *skb);
-
-static inline struct sk_buff *nfcwilink_skb_alloc(unsigned int len, gfp_t how)
-{
- struct sk_buff *skb;
-
- skb = alloc_skb(len + NFCWILINK_HDR_LEN, how);
- if (skb)
- skb_reserve(skb, NFCWILINK_HDR_LEN);
-
- return skb;
-}
-
-static void nfcwilink_fw_download_receive(struct nfcwilink *drv,
- struct sk_buff *skb)
-{
- struct nci_vs_nfcc_info_rsp *rsp = (void *)skb->data;
-
- /* Detect NCI_VS_NFCC_INFO_RSP and store the result */
- if ((skb->len > 3) && (rsp->gid == NCI_VS_NFCC_INFO_RSP_GID) &&
- (rsp->oid == NCI_VS_NFCC_INFO_RSP_OID)) {
- memcpy(&drv->nfcc_info, rsp,
- sizeof(struct nci_vs_nfcc_info_rsp));
- }
-
- kfree_skb(skb);
-
- complete(&drv->completed);
-}
-
-static int nfcwilink_get_bts_file_name(struct nfcwilink *drv, char *file_name)
-{
- struct nci_vs_nfcc_info_cmd *cmd;
- struct sk_buff *skb;
- unsigned long comp_ret;
- int rc;
-
- skb = nfcwilink_skb_alloc(sizeof(struct nci_vs_nfcc_info_cmd),
- GFP_KERNEL);
- if (!skb) {
- nfc_err(&drv->pdev->dev,
- "no memory for nci_vs_nfcc_info_cmd\n");
- return -ENOMEM;
- }
-
- cmd = (struct nci_vs_nfcc_info_cmd *)
- skb_put(skb, sizeof(struct nci_vs_nfcc_info_cmd));
- cmd->gid = NCI_VS_NFCC_INFO_CMD_GID;
- cmd->oid = NCI_VS_NFCC_INFO_CMD_OID;
- cmd->plen = 0;
-
- drv->nfcc_info.plen = 0;
-
- rc = nfcwilink_send(drv->ndev, skb);
- if (rc)
- return rc;
-
- comp_ret = wait_for_completion_timeout(&drv->completed,
- msecs_to_jiffies(NFCWILINK_CMD_TIMEOUT));
- dev_dbg(&drv->pdev->dev, "wait_for_completion_timeout returned %ld\n",
- comp_ret);
- if (comp_ret == 0) {
- nfc_err(&drv->pdev->dev,
- "timeout on wait_for_completion_timeout\n");
- return -ETIMEDOUT;
- }
-
- dev_dbg(&drv->pdev->dev, "nci_vs_nfcc_info_rsp: plen %d, status %d\n",
- drv->nfcc_info.plen, drv->nfcc_info.status);
-
- if ((drv->nfcc_info.plen != 5) || (drv->nfcc_info.status != 0)) {
- nfc_err(&drv->pdev->dev, "invalid nci_vs_nfcc_info_rsp\n");
- return -EINVAL;
- }
-
- snprintf(file_name, BTS_FILE_NAME_MAX_SIZE,
- "TINfcInit_%d.%d.%d.%d.bts",
- drv->nfcc_info.hw_id,
- drv->nfcc_info.sw_ver_x,
- drv->nfcc_info.sw_ver_z,
- drv->nfcc_info.patch_id);
-
- nfc_info(&drv->pdev->dev, "nfcwilink FW file name: %s\n", file_name);
-
- return 0;
-}
-
-static int nfcwilink_send_bts_cmd(struct nfcwilink *drv, __u8 *data, int len)
-{
- struct nfcwilink_hdr *hdr = (struct nfcwilink_hdr *)data;
- struct sk_buff *skb;
- unsigned long comp_ret;
- int rc;
-
- /* verify valid cmd for the NFC channel */
- if ((len <= sizeof(struct nfcwilink_hdr)) ||
- (len > BTS_FILE_CMD_MAX_LEN) ||
- (hdr->chnl != NFCWILINK_CHNL) ||
- (hdr->opcode != NFCWILINK_OPCODE)) {
- nfc_err(&drv->pdev->dev,
- "ignoring invalid bts cmd, len %d, chnl %d, opcode %d\n",
- len, hdr->chnl, hdr->opcode);
- return 0;
- }
-
- /* remove the ST header */
- len -= sizeof(struct nfcwilink_hdr);
- data += sizeof(struct nfcwilink_hdr);
-
- skb = nfcwilink_skb_alloc(len, GFP_KERNEL);
- if (!skb) {
- nfc_err(&drv->pdev->dev, "no memory for bts cmd\n");
- return -ENOMEM;
- }
-
- memcpy(skb_put(skb, len), data, len);
-
- rc = nfcwilink_send(drv->ndev, skb);
- if (rc)
- return rc;
-
- comp_ret = wait_for_completion_timeout(&drv->completed,
- msecs_to_jiffies(NFCWILINK_CMD_TIMEOUT));
- dev_dbg(&drv->pdev->dev, "wait_for_completion_timeout returned %ld\n",
- comp_ret);
- if (comp_ret == 0) {
- nfc_err(&drv->pdev->dev,
- "timeout on wait_for_completion_timeout\n");
- return -ETIMEDOUT;
- }
-
- return 0;
-}
-
-static int nfcwilink_download_fw(struct nfcwilink *drv)
-{
- unsigned char file_name[BTS_FILE_NAME_MAX_SIZE];
- const struct firmware *fw;
- __u16 action_type, action_len;
- __u8 *ptr;
- int len, rc;
-
- set_bit(NFCWILINK_FW_DOWNLOAD, &drv->flags);
-
- rc = nfcwilink_get_bts_file_name(drv, file_name);
- if (rc)
- goto exit;
-
- rc = request_firmware(&fw, file_name, &drv->pdev->dev);
- if (rc) {
- nfc_err(&drv->pdev->dev, "request_firmware failed %d\n", rc);
-
- /* if the file is not found, don't exit with failure */
- if (rc == -ENOENT)
- rc = 0;
-
- goto exit;
- }
-
- len = fw->size;
- ptr = (__u8 *)fw->data;
-
- if ((len == 0) || (ptr == NULL)) {
- dev_dbg(&drv->pdev->dev,
- "request_firmware returned size %d\n", len);
- goto release_fw;
- }
-
- if (__le32_to_cpu(((struct bts_file_hdr *)ptr)->magic) !=
- BTS_FILE_HDR_MAGIC) {
- nfc_err(&drv->pdev->dev, "wrong bts magic number\n");
- rc = -EINVAL;
- goto release_fw;
- }
-
- /* remove the BTS header */
- len -= sizeof(struct bts_file_hdr);
- ptr += sizeof(struct bts_file_hdr);
-
- while (len > 0) {
- action_type =
- __le16_to_cpu(((struct bts_file_action *)ptr)->type);
- action_len =
- __le16_to_cpu(((struct bts_file_action *)ptr)->len);
-
- dev_dbg(&drv->pdev->dev, "bts_file_action type %d, len %d\n",
- action_type, action_len);
-
- switch (action_type) {
- case BTS_FILE_ACTION_TYPE_SEND_CMD:
- rc = nfcwilink_send_bts_cmd(drv,
- ((struct bts_file_action *)ptr)->data,
- action_len);
- if (rc)
- goto release_fw;
- break;
- }
-
- /* advance to the next action */
- len -= (sizeof(struct bts_file_action) + action_len);
- ptr += (sizeof(struct bts_file_action) + action_len);
- }
-
-release_fw:
- release_firmware(fw);
-
-exit:
- clear_bit(NFCWILINK_FW_DOWNLOAD, &drv->flags);
- return rc;
-}
-
-/* Called by ST when registration is complete */
-static void nfcwilink_register_complete(void *priv_data, int data)
-{
- struct nfcwilink *drv = priv_data;
-
- /* store ST registration status */
- drv->st_register_cb_status = data;
-
- /* complete the wait in nfc_st_open() */
- complete(&drv->completed);
-}
-
-/* Called by ST when receive data is available */
-static long nfcwilink_receive(void *priv_data, struct sk_buff *skb)
-{
- struct nfcwilink *drv = priv_data;
- int rc;
-
- if (!skb)
- return -EFAULT;
-
- if (!drv) {
- kfree_skb(skb);
- return -EFAULT;
- }
-
- dev_dbg(&drv->pdev->dev, "receive entry, len %d\n", skb->len);
-
- /* strip the ST header
- (apart for the chnl byte, which is not received in the hdr) */
- skb_pull(skb, (NFCWILINK_HDR_LEN-1));
-
- if (test_bit(NFCWILINK_FW_DOWNLOAD, &drv->flags)) {
- nfcwilink_fw_download_receive(drv, skb);
- return 0;
- }
-
- /* Forward skb to NCI core layer */
- rc = nci_recv_frame(drv->ndev, skb);
- if (rc < 0) {
- nfc_err(&drv->pdev->dev, "nci_recv_frame failed %d\n", rc);
- return rc;
- }
-
- return 0;
-}
-
-/* protocol structure registered with ST */
-static struct st_proto_s nfcwilink_proto = {
- .chnl_id = NFCWILINK_CHNL,
- .max_frame_size = NFCWILINK_MAX_FRAME_SIZE,
- .hdr_len = (NFCWILINK_HDR_LEN-1), /* not including chnl byte */
- .offset_len_in_hdr = NFCWILINK_OFFSET_LEN_IN_HDR,
- .len_size = NFCWILINK_LEN_SIZE,
- .reserve = 0,
- .recv = nfcwilink_receive,
- .reg_complete_cb = nfcwilink_register_complete,
- .write = NULL,
-};
-
-static int nfcwilink_open(struct nci_dev *ndev)
-{
- struct nfcwilink *drv = nci_get_drvdata(ndev);
- unsigned long comp_ret;
- int rc;
-
- if (test_and_set_bit(NFCWILINK_RUNNING, &drv->flags)) {
- rc = -EBUSY;
- goto exit;
- }
-
- nfcwilink_proto.priv_data = drv;
-
- init_completion(&drv->completed);
- drv->st_register_cb_status = -EINPROGRESS;
-
- rc = st_register(&nfcwilink_proto);
- if (rc < 0) {
- if (rc == -EINPROGRESS) {
- comp_ret = wait_for_completion_timeout(
- &drv->completed,
- msecs_to_jiffies(NFCWILINK_REGISTER_TIMEOUT));
-
- dev_dbg(&drv->pdev->dev,
- "wait_for_completion_timeout returned %ld\n",
- comp_ret);
-
- if (comp_ret == 0) {
- /* timeout */
- rc = -ETIMEDOUT;
- goto clear_exit;
- } else if (drv->st_register_cb_status != 0) {
- rc = drv->st_register_cb_status;
- nfc_err(&drv->pdev->dev,
- "st_register_cb failed %d\n", rc);
- goto clear_exit;
- }
- } else {
- nfc_err(&drv->pdev->dev, "st_register failed %d\n", rc);
- goto clear_exit;
- }
- }
-
- /* st_register MUST fill the write callback */
- BUG_ON(nfcwilink_proto.write == NULL);
- drv->st_write = nfcwilink_proto.write;
-
- if (nfcwilink_download_fw(drv)) {
- nfc_err(&drv->pdev->dev, "nfcwilink_download_fw failed %d\n",
- rc);
- /* open should succeed, even if the FW download failed */
- }
-
- goto exit;
-
-clear_exit:
- clear_bit(NFCWILINK_RUNNING, &drv->flags);
-
-exit:
- return rc;
-}
-
-static int nfcwilink_close(struct nci_dev *ndev)
-{
- struct nfcwilink *drv = nci_get_drvdata(ndev);
- int rc;
-
- if (!test_and_clear_bit(NFCWILINK_RUNNING, &drv->flags))
- return 0;
-
- rc = st_unregister(&nfcwilink_proto);
- if (rc)
- nfc_err(&drv->pdev->dev, "st_unregister failed %d\n", rc);
-
- drv->st_write = NULL;
-
- return rc;
-}
-
-static int nfcwilink_send(struct nci_dev *ndev, struct sk_buff *skb)
-{
- struct nfcwilink *drv = nci_get_drvdata(ndev);
- struct nfcwilink_hdr hdr = {NFCWILINK_CHNL, NFCWILINK_OPCODE, 0x0000};
- long len;
-
- dev_dbg(&drv->pdev->dev, "send entry, len %d\n", skb->len);
-
- if (!test_bit(NFCWILINK_RUNNING, &drv->flags)) {
- kfree_skb(skb);
- return -EINVAL;
- }
-
- /* add the ST hdr to the start of the buffer */
- hdr.len = cpu_to_le16(skb->len);
- memcpy(skb_push(skb, NFCWILINK_HDR_LEN), &hdr, NFCWILINK_HDR_LEN);
-
- /* Insert skb to shared transport layer's transmit queue.
- * Freeing skb memory is taken care in shared transport layer,
- * so don't free skb memory here.
- */
- len = drv->st_write(skb);
- if (len < 0) {
- kfree_skb(skb);
- nfc_err(&drv->pdev->dev, "st_write failed %ld\n", len);
- return -EFAULT;
- }
-
- return 0;
-}
-
-static struct nci_ops nfcwilink_ops = {
- .open = nfcwilink_open,
- .close = nfcwilink_close,
- .send = nfcwilink_send,
-};
-
-static int nfcwilink_probe(struct platform_device *pdev)
-{
- struct nfcwilink *drv;
- int rc;
- __u32 protocols;
-
- drv = devm_kzalloc(&pdev->dev, sizeof(struct nfcwilink), GFP_KERNEL);
- if (!drv) {
- rc = -ENOMEM;
- goto exit;
- }
-
- drv->pdev = pdev;
-
- protocols = NFC_PROTO_JEWEL_MASK
- | NFC_PROTO_MIFARE_MASK | NFC_PROTO_FELICA_MASK
- | NFC_PROTO_ISO14443_MASK
- | NFC_PROTO_ISO14443_B_MASK
- | NFC_PROTO_NFC_DEP_MASK;
-
- drv->ndev = nci_allocate_device(&nfcwilink_ops,
- protocols,
- NFCWILINK_HDR_LEN,
- 0);
- if (!drv->ndev) {
- nfc_err(&pdev->dev, "nci_allocate_device failed\n");
- rc = -ENOMEM;
- goto exit;
- }
-
- nci_set_parent_dev(drv->ndev, &pdev->dev);
- nci_set_drvdata(drv->ndev, drv);
-
- rc = nci_register_device(drv->ndev);
- if (rc < 0) {
- nfc_err(&pdev->dev, "nci_register_device failed %d\n", rc);
- goto free_dev_exit;
- }
-
- dev_set_drvdata(&pdev->dev, drv);
-
- goto exit;
-
-free_dev_exit:
- nci_free_device(drv->ndev);
-
-exit:
- return rc;
-}
-
-static int nfcwilink_remove(struct platform_device *pdev)
-{
- struct nfcwilink *drv = dev_get_drvdata(&pdev->dev);
- struct nci_dev *ndev;
-
- if (!drv)
- return -EFAULT;
-
- ndev = drv->ndev;
-
- nci_unregister_device(ndev);
- nci_free_device(ndev);
-
- return 0;
-}
-
-static struct platform_driver nfcwilink_driver = {
- .probe = nfcwilink_probe,
- .remove = nfcwilink_remove,
- .driver = {
- .name = "nfcwilink",
- },
-};
-
-module_platform_driver(nfcwilink_driver);
-
-/* ------ Module Info ------ */
-
-MODULE_AUTHOR("Ilan Elias <ilane@ti.com>");
-MODULE_DESCRIPTION("NFC Driver for TI Shared Transport");
-MODULE_LICENSE("GPL");
diff --git a/drivers/nfc/nxp-nci/firmware.c b/drivers/nfc/nxp-nci/firmware.c
index 5291797324ba..553011f58339 100644
--- a/drivers/nfc/nxp-nci/firmware.c
+++ b/drivers/nfc/nxp-nci/firmware.c
@@ -24,7 +24,7 @@
#include <linux/completion.h>
#include <linux/firmware.h>
#include <linux/nfc.h>
-#include <linux/unaligned/access_ok.h>
+#include <asm/unaligned.h>
#include "nxp-nci.h"
diff --git a/drivers/nfc/nxp-nci/i2c.c b/drivers/nfc/nxp-nci/i2c.c
index 36099e557730..ff22d761183c 100644
--- a/drivers/nfc/nxp-nci/i2c.c
+++ b/drivers/nfc/nxp-nci/i2c.c
@@ -29,14 +29,13 @@
#include <linux/delay.h>
#include <linux/i2c.h>
#include <linux/interrupt.h>
-#include <linux/miscdevice.h>
#include <linux/module.h>
#include <linux/nfc.h>
#include <linux/gpio/consumer.h>
#include <linux/of_gpio.h>
#include <linux/of_irq.h>
#include <linux/platform_data/nxp-nci.h>
-#include <linux/unaligned/access_ok.h>
+#include <asm/unaligned.h>
#include <net/nfc/nfc.h>
@@ -86,7 +85,7 @@ static int nxp_nci_i2c_write(void *phy_id, struct sk_buff *skb)
r = i2c_master_send(client, skb->data, skb->len);
if (r < 0) {
/* Retry, chip was in standby */
- usleep_range(110000, 120000);
+ msleep(110);
r = i2c_master_send(client, skb->data, skb->len);
}
@@ -127,7 +126,7 @@ static int nxp_nci_i2c_fw_read(struct nxp_nci_i2c_phy *phy,
goto fw_read_exit;
}
- frame_len = (get_unaligned_be16(&header) & NXP_NCI_FW_FRAME_LEN_MASK) +
+ frame_len = (be16_to_cpu(header) & NXP_NCI_FW_FRAME_LEN_MASK) +
NXP_NCI_FW_CRC_LEN;
*skb = alloc_skb(NXP_NCI_FW_HDR_LEN + frame_len, GFP_KERNEL);
diff --git a/drivers/nfc/pn533/i2c.c b/drivers/nfc/pn533/i2c.c
index 1dc89248e58e..8f60ce039b0d 100644
--- a/drivers/nfc/pn533/i2c.c
+++ b/drivers/nfc/pn533/i2c.c
@@ -51,7 +51,7 @@ static int pn533_i2c_send_ack(struct pn533 *dev, gfp_t flags)
{
struct pn533_i2c_phy *phy = dev->phy;
struct i2c_client *client = phy->i2c_dev;
- u8 ack[6] = {0x00, 0x00, 0xff, 0x00, 0xff, 0x00};
+ static const u8 ack[6] = {0x00, 0x00, 0xff, 0x00, 0xff, 0x00};
/* spec 6.2.1.3: Preamble, SoPC (2), ACK Code (2), Postamble */
int rc;
@@ -206,14 +206,6 @@ static int pn533_i2c_probe(struct i2c_client *client,
phy->i2c_dev = client;
i2c_set_clientdata(client, phy);
- r = request_threaded_irq(client->irq, NULL, pn533_i2c_irq_thread_fn,
- IRQF_TRIGGER_FALLING |
- IRQF_SHARED | IRQF_ONESHOT,
- PN533_I2C_DRIVER_NAME, phy);
-
- if (r < 0)
- nfc_err(&client->dev, "Unable to register IRQ handler\n");
-
priv = pn533_register_device(PN533_DEVICE_PN532,
PN533_NO_TYPE_B_PROTOCOLS,
PN533_PROTO_REQ_ACK_RESP,
@@ -223,16 +215,32 @@ static int pn533_i2c_probe(struct i2c_client *client,
if (IS_ERR(priv)) {
r = PTR_ERR(priv);
- goto err_register;
+ return r;
}
phy->priv = priv;
+ r = request_threaded_irq(client->irq, NULL, pn533_i2c_irq_thread_fn,
+ IRQF_TRIGGER_FALLING |
+ IRQF_SHARED | IRQF_ONESHOT,
+ PN533_I2C_DRIVER_NAME, phy);
+ if (r < 0) {
+ nfc_err(&client->dev, "Unable to register IRQ handler\n");
+ goto irq_rqst_err;
+ }
+
+ r = pn533_finalize_setup(priv);
+ if (r)
+ goto fn_setup_err;
+
return 0;
-err_register:
+fn_setup_err:
free_irq(client->irq, phy);
+irq_rqst_err:
+ pn533_unregister_device(phy->priv);
+
return r;
}
@@ -242,10 +250,10 @@ static int pn533_i2c_remove(struct i2c_client *client)
dev_dbg(&client->dev, "%s\n", __func__);
- pn533_unregister_device(phy->priv);
-
free_irq(client->irq, phy);
+ pn533_unregister_device(phy->priv);
+
return 0;
}
diff --git a/drivers/nfc/pn533/pn533.c b/drivers/nfc/pn533/pn533.c
index a966c6a85ea8..65bbaa5fcdda 100644
--- a/drivers/nfc/pn533/pn533.c
+++ b/drivers/nfc/pn533/pn533.c
@@ -383,14 +383,18 @@ static void pn533_build_cmd_frame(struct pn533 *dev, u8 cmd_code,
static int pn533_send_async_complete(struct pn533 *dev)
{
struct pn533_cmd *cmd = dev->cmd;
- int status = cmd->status;
+ struct sk_buff *resp;
+ int status, rc = 0;
- struct sk_buff *req = cmd->req;
- struct sk_buff *resp = cmd->resp;
+ if (!cmd) {
+ dev_dbg(dev->dev, "%s: cmd not set\n", __func__);
+ goto done;
+ }
- int rc;
+ dev_kfree_skb(cmd->req);
- dev_kfree_skb(req);
+ status = cmd->status;
+ resp = cmd->resp;
if (status < 0) {
rc = cmd->complete_cb(dev, cmd->complete_cb_context,
@@ -399,8 +403,14 @@ static int pn533_send_async_complete(struct pn533 *dev)
goto done;
}
- skb_pull(resp, dev->ops->rx_header_len);
- skb_trim(resp, resp->len - dev->ops->rx_tail_len);
+ /* when no response is set we got interrupted */
+ if (!resp)
+ resp = ERR_PTR(-EINTR);
+
+ if (!IS_ERR(resp)) {
+ skb_pull(resp, dev->ops->rx_header_len);
+ skb_trim(resp, resp->len - dev->ops->rx_tail_len);
+ }
rc = cmd->complete_cb(dev, cmd->complete_cb_context, resp);
@@ -434,12 +444,14 @@ static int __pn533_send_async(struct pn533 *dev, u8 cmd_code,
mutex_lock(&dev->cmd_lock);
if (!dev->cmd_pending) {
+ dev->cmd = cmd;
rc = dev->phy_ops->send_frame(dev, req);
- if (rc)
+ if (rc) {
+ dev->cmd = NULL;
goto error;
+ }
dev->cmd_pending = 1;
- dev->cmd = cmd;
goto unlock;
}
@@ -511,11 +523,12 @@ static int pn533_send_cmd_direct_async(struct pn533 *dev, u8 cmd_code,
pn533_build_cmd_frame(dev, cmd_code, req);
+ dev->cmd = cmd;
rc = dev->phy_ops->send_frame(dev, req);
- if (rc < 0)
+ if (rc < 0) {
+ dev->cmd = NULL;
kfree(cmd);
- else
- dev->cmd = cmd;
+ }
return rc;
}
@@ -550,14 +563,15 @@ static void pn533_wq_cmd(struct work_struct *work)
mutex_unlock(&dev->cmd_lock);
+ dev->cmd = cmd;
rc = dev->phy_ops->send_frame(dev, cmd->req);
if (rc < 0) {
+ dev->cmd = NULL;
dev_kfree_skb(cmd->req);
kfree(cmd);
return;
}
- dev->cmd = cmd;
}
struct pn533_sync_cmd_response {
@@ -2556,6 +2570,31 @@ static int pn533_setup(struct pn533 *dev)
return 0;
}
+int pn533_finalize_setup(struct pn533 *dev)
+{
+
+ struct pn533_fw_version fw_ver;
+ int rc;
+
+ memset(&fw_ver, 0, sizeof(fw_ver));
+
+ rc = pn533_get_firmware_version(dev, &fw_ver);
+ if (rc) {
+ nfc_err(dev->dev, "Unable to get FW version\n");
+ return rc;
+ }
+
+ nfc_info(dev->dev, "NXP PN5%02X firmware ver %d.%d now attached\n",
+ fw_ver.ic, fw_ver.ver, fw_ver.rev);
+
+ rc = pn533_setup(dev);
+ if (rc)
+ return rc;
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(pn533_finalize_setup);
+
struct pn533 *pn533_register_device(u32 device_type,
u32 protocols,
enum pn533_protocol_type protocol_type,
@@ -2565,7 +2604,6 @@ struct pn533 *pn533_register_device(u32 device_type,
struct device *dev,
struct device *parent)
{
- struct pn533_fw_version fw_ver;
struct pn533 *priv;
int rc = -ENOMEM;
@@ -2608,15 +2646,6 @@ struct pn533 *pn533_register_device(u32 device_type,
INIT_LIST_HEAD(&priv->cmd_queue);
- memset(&fw_ver, 0, sizeof(fw_ver));
- rc = pn533_get_firmware_version(priv, &fw_ver);
- if (rc < 0)
- goto destroy_wq;
-
- nfc_info(dev, "NXP PN5%02X firmware ver %d.%d now attached\n",
- fw_ver.ic, fw_ver.ver, fw_ver.rev);
-
-
priv->nfc_dev = nfc_allocate_device(&pn533_nfc_ops, protocols,
priv->ops->tx_header_len +
PN533_CMD_DATAEXCH_HEAD_LEN,
@@ -2633,15 +2662,8 @@ struct pn533 *pn533_register_device(u32 device_type,
if (rc)
goto free_nfc_dev;
- rc = pn533_setup(priv);
- if (rc)
- goto unregister_nfc_dev;
-
return priv;
-unregister_nfc_dev:
- nfc_unregister_device(priv->nfc_dev);
-
free_nfc_dev:
nfc_free_device(priv->nfc_dev);
diff --git a/drivers/nfc/pn533/pn533.h b/drivers/nfc/pn533/pn533.h
index 553c7d171fd1..88d569666c51 100644
--- a/drivers/nfc/pn533/pn533.h
+++ b/drivers/nfc/pn533/pn533.h
@@ -231,6 +231,7 @@ struct pn533 *pn533_register_device(u32 device_type,
struct device *dev,
struct device *parent);
+int pn533_finalize_setup(struct pn533 *dev);
void pn533_unregister_device(struct pn533 *priv);
void pn533_recv_frame(struct pn533 *dev, struct sk_buff *skb, int status);
diff --git a/drivers/nfc/pn533/usb.c b/drivers/nfc/pn533/usb.c
index 33ed78be2750..8ed203ea21ea 100644
--- a/drivers/nfc/pn533/usb.c
+++ b/drivers/nfc/pn533/usb.c
@@ -148,11 +148,11 @@ static int pn533_submit_urb_for_ack(struct pn533_usb_phy *phy, gfp_t flags)
static int pn533_usb_send_ack(struct pn533 *dev, gfp_t flags)
{
struct pn533_usb_phy *phy = dev->phy;
- u8 ack[6] = {0x00, 0x00, 0xff, 0x00, 0xff, 0x00};
+ static const u8 ack[6] = {0x00, 0x00, 0xff, 0x00, 0xff, 0x00};
/* spec 7.1.1.3: Preamble, SoPC (2), ACK Code (2), Postamble */
int rc;
- phy->out_urb->transfer_buffer = ack;
+ phy->out_urb->transfer_buffer = (u8 *)ack;
phy->out_urb->transfer_buffer_length = sizeof(ack);
rc = usb_submit_urb(phy->out_urb, flags);
@@ -543,6 +543,10 @@ static int pn533_usb_probe(struct usb_interface *interface,
phy->priv = priv;
+ rc = pn533_finalize_setup(priv);
+ if (rc)
+ goto error;
+
usb_set_intfdata(interface, phy);
return 0;
diff --git a/drivers/nfc/pn544/i2c.c b/drivers/nfc/pn544/i2c.c
index f837c39a8017..71ac0836c9f4 100644
--- a/drivers/nfc/pn544/i2c.c
+++ b/drivers/nfc/pn544/i2c.c
@@ -21,17 +21,13 @@
#include <linux/crc-ccitt.h>
#include <linux/module.h>
#include <linux/i2c.h>
-#include <linux/gpio.h>
-#include <linux/of_gpio.h>
-#include <linux/of_irq.h>
#include <linux/acpi.h>
-#include <linux/miscdevice.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/nfc.h>
#include <linux/firmware.h>
#include <linux/gpio/consumer.h>
-#include <linux/platform_data/pn544.h>
+
#include <asm/unaligned.h>
#include <net/nfc/hci.h>
@@ -165,8 +161,9 @@ struct pn544_i2c_phy {
struct i2c_client *i2c_dev;
struct nfc_hci_dev *hdev;
- unsigned int gpio_en;
- unsigned int gpio_fw;
+ struct gpio_desc *gpiod_en;
+ struct gpio_desc *gpiod_fw;
+
unsigned int en_polarity;
u8 hw_variant;
@@ -208,19 +205,18 @@ static void pn544_hci_i2c_platform_init(struct pn544_i2c_phy *phy)
nfc_info(&phy->i2c_dev->dev, "Detecting nfc_en polarity\n");
/* Disable fw download */
- gpio_set_value_cansleep(phy->gpio_fw, 0);
+ gpiod_set_value_cansleep(phy->gpiod_fw, 0);
for (polarity = 0; polarity < 2; polarity++) {
phy->en_polarity = polarity;
retry = 3;
while (retry--) {
/* power off */
- gpio_set_value_cansleep(phy->gpio_en,
- !phy->en_polarity);
+ gpiod_set_value_cansleep(phy->gpiod_en, !phy->en_polarity);
usleep_range(10000, 15000);
/* power on */
- gpio_set_value_cansleep(phy->gpio_en, phy->en_polarity);
+ gpiod_set_value_cansleep(phy->gpiod_en, phy->en_polarity);
usleep_range(10000, 15000);
/* send reset */
@@ -239,14 +235,13 @@ static void pn544_hci_i2c_platform_init(struct pn544_i2c_phy *phy)
"Could not detect nfc_en polarity, fallback to active high\n");
out:
- gpio_set_value_cansleep(phy->gpio_en, !phy->en_polarity);
+ gpiod_set_value_cansleep(phy->gpiod_en, !phy->en_polarity);
}
static void pn544_hci_i2c_enable_mode(struct pn544_i2c_phy *phy, int run_mode)
{
- gpio_set_value_cansleep(phy->gpio_fw,
- run_mode == PN544_FW_MODE ? 1 : 0);
- gpio_set_value_cansleep(phy->gpio_en, phy->en_polarity);
+ gpiod_set_value_cansleep(phy->gpiod_fw, run_mode == PN544_FW_MODE ? 1 : 0);
+ gpiod_set_value_cansleep(phy->gpiod_en, phy->en_polarity);
usleep_range(10000, 15000);
phy->run_mode = run_mode;
@@ -269,14 +264,14 @@ static void pn544_hci_i2c_disable(void *phy_id)
{
struct pn544_i2c_phy *phy = phy_id;
- gpio_set_value_cansleep(phy->gpio_fw, 0);
- gpio_set_value_cansleep(phy->gpio_en, !phy->en_polarity);
+ gpiod_set_value_cansleep(phy->gpiod_fw, 0);
+ gpiod_set_value_cansleep(phy->gpiod_en, !phy->en_polarity);
usleep_range(10000, 15000);
- gpio_set_value_cansleep(phy->gpio_en, phy->en_polarity);
+ gpiod_set_value_cansleep(phy->gpiod_en, phy->en_polarity);
usleep_range(10000, 15000);
- gpio_set_value_cansleep(phy->gpio_en, !phy->en_polarity);
+ gpiod_set_value_cansleep(phy->gpiod_en, !phy->en_polarity);
usleep_range(10000, 15000);
phy->powered = 0;
@@ -874,106 +869,20 @@ exit_state_wait_secure_write_answer:
}
}
-static int pn544_hci_i2c_acpi_request_resources(struct i2c_client *client)
-{
- struct pn544_i2c_phy *phy = i2c_get_clientdata(client);
- struct gpio_desc *gpiod_en, *gpiod_fw;
- struct device *dev = &client->dev;
-
- /* Get EN GPIO from ACPI */
- gpiod_en = devm_gpiod_get_index(dev, PN544_GPIO_NAME_EN, 1,
- GPIOD_OUT_LOW);
- if (IS_ERR(gpiod_en)) {
- nfc_err(dev, "Unable to get EN GPIO\n");
- return -ENODEV;
- }
-
- phy->gpio_en = desc_to_gpio(gpiod_en);
-
- /* Get FW GPIO from ACPI */
- gpiod_fw = devm_gpiod_get_index(dev, PN544_GPIO_NAME_FW, 2,
- GPIOD_OUT_LOW);
- if (IS_ERR(gpiod_fw)) {
- nfc_err(dev, "Unable to get FW GPIO\n");
- return -ENODEV;
- }
-
- phy->gpio_fw = desc_to_gpio(gpiod_fw);
-
- return 0;
-}
-
-static int pn544_hci_i2c_of_request_resources(struct i2c_client *client)
-{
- struct pn544_i2c_phy *phy = i2c_get_clientdata(client);
- struct device_node *pp;
- int ret;
-
- pp = client->dev.of_node;
- if (!pp) {
- ret = -ENODEV;
- goto err_dt;
- }
-
- /* Obtention of EN GPIO from device tree */
- ret = of_get_named_gpio(pp, "enable-gpios", 0);
- if (ret < 0) {
- if (ret != -EPROBE_DEFER)
- nfc_err(&client->dev,
- "Failed to get EN gpio, error: %d\n", ret);
- goto err_dt;
- }
- phy->gpio_en = ret;
-
- /* Configuration of EN GPIO */
- ret = gpio_request(phy->gpio_en, PN544_GPIO_NAME_EN);
- if (ret) {
- nfc_err(&client->dev, "Fail EN pin\n");
- goto err_dt;
- }
- ret = gpio_direction_output(phy->gpio_en, 0);
- if (ret) {
- nfc_err(&client->dev, "Fail EN pin direction\n");
- goto err_gpio_en;
- }
-
- /* Obtention of FW GPIO from device tree */
- ret = of_get_named_gpio(pp, "firmware-gpios", 0);
- if (ret < 0) {
- if (ret != -EPROBE_DEFER)
- nfc_err(&client->dev,
- "Failed to get FW gpio, error: %d\n", ret);
- goto err_gpio_en;
- }
- phy->gpio_fw = ret;
-
- /* Configuration of FW GPIO */
- ret = gpio_request(phy->gpio_fw, PN544_GPIO_NAME_FW);
- if (ret) {
- nfc_err(&client->dev, "Fail FW pin\n");
- goto err_gpio_en;
- }
- ret = gpio_direction_output(phy->gpio_fw, 0);
- if (ret) {
- nfc_err(&client->dev, "Fail FW pin direction\n");
- goto err_gpio_fw;
- }
-
- return 0;
+static const struct acpi_gpio_params enable_gpios = { 1, 0, false };
+static const struct acpi_gpio_params firmware_gpios = { 2, 0, false };
-err_gpio_fw:
- gpio_free(phy->gpio_fw);
-err_gpio_en:
- gpio_free(phy->gpio_en);
-err_dt:
- return ret;
-}
+static const struct acpi_gpio_mapping acpi_pn544_gpios[] = {
+ { "enable-gpios", &enable_gpios, 1 },
+ { "firmware-gpios", &firmware_gpios, 1 },
+ { },
+};
static int pn544_hci_i2c_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
+ struct device *dev = &client->dev;
struct pn544_i2c_phy *phy;
- struct pn544_nfc_platform_data *pdata;
int r = 0;
dev_dbg(&client->dev, "%s\n", __func__);
@@ -995,53 +904,33 @@ static int pn544_hci_i2c_probe(struct i2c_client *client,
phy->i2c_dev = client;
i2c_set_clientdata(client, phy);
- pdata = client->dev.platform_data;
-
- /* No platform data, using device tree. */
- if (!pdata && client->dev.of_node) {
- r = pn544_hci_i2c_of_request_resources(client);
- if (r) {
- nfc_err(&client->dev, "No DT data\n");
- return r;
- }
- /* Using platform data. */
- } else if (pdata) {
-
- if (pdata->request_resources == NULL) {
- nfc_err(&client->dev, "request_resources() missing\n");
- return -EINVAL;
- }
+ r = acpi_dev_add_driver_gpios(ACPI_COMPANION(dev), acpi_pn544_gpios);
+ if (r)
+ dev_dbg(dev, "Unable to add GPIO mapping table\n");
- r = pdata->request_resources(client);
- if (r) {
- nfc_err(&client->dev,
- "Cannot get platform resources\n");
- return r;
- }
+ /* Get EN GPIO */
+ phy->gpiod_en = devm_gpiod_get(dev, "enable", GPIOD_OUT_LOW);
+ if (IS_ERR(phy->gpiod_en)) {
+ nfc_err(dev, "Unable to get EN GPIO\n");
+ return PTR_ERR(phy->gpiod_en);
+ }
- phy->gpio_en = pdata->get_gpio(NFC_GPIO_ENABLE);
- phy->gpio_fw = pdata->get_gpio(NFC_GPIO_FW_RESET);
- /* Using ACPI */
- } else if (ACPI_HANDLE(&client->dev)) {
- r = pn544_hci_i2c_acpi_request_resources(client);
- if (r) {
- nfc_err(&client->dev,
- "Cannot get ACPI data\n");
- return r;
- }
- } else {
- nfc_err(&client->dev, "No platform data\n");
- return -EINVAL;
+ /* Get FW GPIO */
+ phy->gpiod_fw = devm_gpiod_get(dev, "firmware", GPIOD_OUT_LOW);
+ if (IS_ERR(phy->gpiod_fw)) {
+ nfc_err(dev, "Unable to get FW GPIO\n");
+ return PTR_ERR(phy->gpiod_fw);
}
pn544_hci_i2c_platform_init(phy);
- r = request_threaded_irq(client->irq, NULL, pn544_hci_i2c_irq_thread_fn,
- IRQF_TRIGGER_RISING | IRQF_ONESHOT,
- PN544_HCI_I2C_DRIVER_NAME, phy);
+ r = devm_request_threaded_irq(&client->dev, client->irq, NULL,
+ pn544_hci_i2c_irq_thread_fn,
+ IRQF_TRIGGER_RISING | IRQF_ONESHOT,
+ PN544_HCI_I2C_DRIVER_NAME, phy);
if (r < 0) {
nfc_err(&client->dev, "Unable to register IRQ handler\n");
- goto err_rti;
+ return r;
}
r = pn544_hci_probe(phy, &i2c_phy_ops, LLC_SHDLC_NAME,
@@ -1049,28 +938,14 @@ static int pn544_hci_i2c_probe(struct i2c_client *client,
PN544_HCI_I2C_LLC_MAX_PAYLOAD,
pn544_hci_i2c_fw_download, &phy->hdev);
if (r < 0)
- goto err_hci;
+ return r;
return 0;
-
-err_hci:
- free_irq(client->irq, phy);
-
-err_rti:
- if (!pdata) {
- gpio_free(phy->gpio_en);
- gpio_free(phy->gpio_fw);
- } else if (pdata->free_resources) {
- pdata->free_resources();
- }
-
- return r;
}
static int pn544_hci_i2c_remove(struct i2c_client *client)
{
struct pn544_i2c_phy *phy = i2c_get_clientdata(client);
- struct pn544_nfc_platform_data *pdata = client->dev.platform_data;
dev_dbg(&client->dev, "%s\n", __func__);
@@ -1083,17 +958,7 @@ static int pn544_hci_i2c_remove(struct i2c_client *client)
if (phy->powered)
pn544_hci_i2c_disable(phy);
- free_irq(client->irq, phy);
-
- /* No platform data, GPIOs have been requested by this driver */
- if (!pdata) {
- gpio_free(phy->gpio_en);
- gpio_free(phy->gpio_fw);
- /* Using platform data */
- } else if (pdata->free_resources) {
- pdata->free_resources();
- }
-
+ acpi_dev_remove_driver_gpios(ACPI_COMPANION(&client->dev));
return 0;
}
diff --git a/drivers/nfc/port100.c b/drivers/nfc/port100.c
index 2b2330b235e6..19be93e177fe 100644
--- a/drivers/nfc/port100.c
+++ b/drivers/nfc/port100.c
@@ -21,8 +21,9 @@
#define VERSION "0.1"
-#define SONY_VENDOR_ID 0x054c
-#define RCS380_PRODUCT_ID 0x06c1
+#define SONY_VENDOR_ID 0x054c
+#define RCS380S_PRODUCT_ID 0x06c1
+#define RCS380P_PRODUCT_ID 0x06c3
#define PORT100_PROTOCOLS (NFC_PROTO_JEWEL_MASK | \
NFC_PROTO_MIFARE_MASK | \
@@ -725,23 +726,33 @@ static int port100_submit_urb_for_ack(struct port100 *dev, gfp_t flags)
static int port100_send_ack(struct port100 *dev)
{
- int rc;
+ int rc = 0;
mutex_lock(&dev->out_urb_lock);
- init_completion(&dev->cmd_cancel_done);
+ /*
+ * If prior cancel is in-flight (dev->cmd_cancel == true), we
+ * can skip to send cancel. Then this will wait the prior
+ * cancel, or merged into the next cancel rarely if next
+ * cancel was started before waiting done. In any case, this
+ * will be waked up soon or later.
+ */
+ if (!dev->cmd_cancel) {
+ reinit_completion(&dev->cmd_cancel_done);
- usb_kill_urb(dev->out_urb);
+ usb_kill_urb(dev->out_urb);
- dev->out_urb->transfer_buffer = ack_frame;
- dev->out_urb->transfer_buffer_length = sizeof(ack_frame);
- rc = usb_submit_urb(dev->out_urb, GFP_KERNEL);
+ dev->out_urb->transfer_buffer = ack_frame;
+ dev->out_urb->transfer_buffer_length = sizeof(ack_frame);
+ rc = usb_submit_urb(dev->out_urb, GFP_KERNEL);
- /* Set the cmd_cancel flag only if the URB has been successfully
- * submitted. It will be reset by the out URB completion callback
- * port100_send_complete().
- */
- dev->cmd_cancel = !rc;
+ /*
+ * Set the cmd_cancel flag only if the URB has been
+ * successfully submitted. It will be reset by the out
+ * URB completion callback port100_send_complete().
+ */
+ dev->cmd_cancel = !rc;
+ }
mutex_unlock(&dev->out_urb_lock);
@@ -928,8 +939,8 @@ static void port100_send_complete(struct urb *urb)
struct port100 *dev = urb->context;
if (dev->cmd_cancel) {
+ complete_all(&dev->cmd_cancel_done);
dev->cmd_cancel = false;
- complete(&dev->cmd_cancel_done);
}
switch (urb->status) {
@@ -1477,7 +1488,8 @@ static struct nfc_digital_ops port100_digital_ops = {
};
static const struct usb_device_id port100_table[] = {
- { USB_DEVICE(SONY_VENDOR_ID, RCS380_PRODUCT_ID), },
+ { USB_DEVICE(SONY_VENDOR_ID, RCS380S_PRODUCT_ID), },
+ { USB_DEVICE(SONY_VENDOR_ID, RCS380P_PRODUCT_ID), },
{ }
};
MODULE_DEVICE_TABLE(usb, port100_table);
@@ -1538,11 +1550,13 @@ static int port100_probe(struct usb_interface *interface,
usb_fill_bulk_urb(dev->out_urb, dev->udev,
usb_sndbulkpipe(dev->udev, out_endpoint),
NULL, 0, port100_send_complete, dev);
+ dev->out_urb->transfer_flags = URB_ZERO_PACKET;
dev->skb_headroom = PORT100_FRAME_HEADER_LEN +
PORT100_COMM_RF_HEAD_MAX_LEN;
dev->skb_tailroom = PORT100_FRAME_TAIL_LEN;
+ init_completion(&dev->cmd_cancel_done);
INIT_WORK(&dev->cmd_complete_work, port100_wq_cmd_complete);
/* The first thing to do with the Port-100 is to set the command type
diff --git a/drivers/nfc/st21nfca/core.c b/drivers/nfc/st21nfca/core.c
index dacb9166081b..50be3b788f1c 100644
--- a/drivers/nfc/st21nfca/core.c
+++ b/drivers/nfc/st21nfca/core.c
@@ -959,10 +959,8 @@ int st21nfca_hci_probe(void *phy_id, struct nfc_phy_ops *phy_ops,
unsigned long quirks = 0;
info = kzalloc(sizeof(struct st21nfca_hci_info), GFP_KERNEL);
- if (!info) {
- r = -ENOMEM;
- goto err_alloc_hdev;
- }
+ if (!info)
+ return -ENOMEM;
info->phy_ops = phy_ops;
info->phy_id = phy_id;
@@ -978,8 +976,10 @@ int st21nfca_hci_probe(void *phy_id, struct nfc_phy_ops *phy_ops,
* persistent info to discriminate 2 identical chips
*/
dev_num = find_first_zero_bit(dev_mask, ST21NFCA_NUM_DEVICES);
- if (dev_num >= ST21NFCA_NUM_DEVICES)
- return -ENODEV;
+ if (dev_num >= ST21NFCA_NUM_DEVICES) {
+ r = -ENODEV;
+ goto err_alloc_hdev;
+ }
set_bit(dev_num, dev_mask);
diff --git a/drivers/nfc/st21nfca/i2c.c b/drivers/nfc/st21nfca/i2c.c
index 5a82f553906c..02a920ca07c8 100644
--- a/drivers/nfc/st21nfca/i2c.c
+++ b/drivers/nfc/st21nfca/i2c.c
@@ -20,17 +20,15 @@
#include <linux/crc-ccitt.h>
#include <linux/module.h>
#include <linux/i2c.h>
-#include <linux/gpio.h>
#include <linux/gpio/consumer.h>
#include <linux/of_irq.h>
#include <linux/of_gpio.h>
#include <linux/acpi.h>
-#include <linux/miscdevice.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/nfc.h>
#include <linux/firmware.h>
-#include <linux/platform_data/st21nfca.h>
+
#include <asm/unaligned.h>
#include <net/nfc/hci.h>
@@ -60,6 +58,7 @@
#define IS_START_OF_FRAME(buf) (buf[0] == ST21NFCA_SOF_EOF && \
buf[1] == 0)
+#define ST21NFCA_HCI_DRIVER_NAME "st21nfca_hci"
#define ST21NFCA_HCI_I2C_DRIVER_NAME "st21nfca_hci_i2c"
#define ST21NFCA_GPIO_NAME_EN "enable"
@@ -68,9 +67,7 @@ struct st21nfca_i2c_phy {
struct i2c_client *i2c_dev;
struct nfc_hci_dev *hdev;
- unsigned int gpio_ena;
- unsigned int irq_polarity;
-
+ struct gpio_desc *gpiod_ena;
struct st21nfca_se_status se_status;
struct sk_buff *pending_skb;
@@ -151,7 +148,7 @@ static int st21nfca_hci_i2c_enable(void *phy_id)
{
struct st21nfca_i2c_phy *phy = phy_id;
- gpio_set_value(phy->gpio_ena, 1);
+ gpiod_set_value(phy->gpiod_ena, 1);
phy->powered = 1;
phy->run_mode = ST21NFCA_HCI_MODE;
@@ -164,7 +161,7 @@ static void st21nfca_hci_i2c_disable(void *phy_id)
{
struct st21nfca_i2c_phy *phy = phy_id;
- gpio_set_value(phy->gpio_ena, 0);
+ gpiod_set_value(phy->gpiod_ena, 0);
phy->powered = 0;
}
@@ -507,33 +504,14 @@ static struct nfc_phy_ops i2c_phy_ops = {
static int st21nfca_hci_i2c_acpi_request_resources(struct i2c_client *client)
{
struct st21nfca_i2c_phy *phy = i2c_get_clientdata(client);
- struct gpio_desc *gpiod_ena;
struct device *dev = &client->dev;
- u8 tmp;
/* Get EN GPIO from ACPI */
- gpiod_ena = devm_gpiod_get_index(dev, ST21NFCA_GPIO_NAME_EN, 1,
- GPIOD_OUT_LOW);
- if (!IS_ERR(gpiod_ena)) {
+ phy->gpiod_ena = devm_gpiod_get_index(dev, ST21NFCA_GPIO_NAME_EN, 1,
+ GPIOD_OUT_LOW);
+ if (IS_ERR(phy->gpiod_ena)) {
nfc_err(dev, "Unable to get ENABLE GPIO\n");
- return -ENODEV;
- }
-
- phy->gpio_ena = desc_to_gpio(gpiod_ena);
-
- phy->irq_polarity = irq_get_trigger_type(client->irq);
-
- phy->se_status.is_ese_present = false;
- phy->se_status.is_uicc_present = false;
-
- if (device_property_present(dev, "ese-present")) {
- device_property_read_u8(dev, "ese-present", &tmp);
- phy->se_status.is_ese_present = tmp;
- }
-
- if (device_property_present(dev, "uicc-present")) {
- device_property_read_u8(dev, "uicc-present", &tmp);
- phy->se_status.is_uicc_present = tmp;
+ return PTR_ERR(phy->gpiod_ena);
}
return 0;
@@ -542,70 +520,16 @@ static int st21nfca_hci_i2c_acpi_request_resources(struct i2c_client *client)
static int st21nfca_hci_i2c_of_request_resources(struct i2c_client *client)
{
struct st21nfca_i2c_phy *phy = i2c_get_clientdata(client);
- struct device_node *pp;
- int gpio;
- int r;
-
- pp = client->dev.of_node;
- if (!pp)
- return -ENODEV;
+ struct device *dev = &client->dev;
/* Get GPIO from device tree */
- gpio = of_get_named_gpio(pp, "enable-gpios", 0);
- if (gpio < 0) {
- nfc_err(&client->dev, "Failed to retrieve enable-gpios from device tree\n");
- return gpio;
- }
-
- /* GPIO request and configuration */
- r = devm_gpio_request_one(&client->dev, gpio, GPIOF_OUT_INIT_HIGH,
- ST21NFCA_GPIO_NAME_EN);
- if (r) {
- nfc_err(&client->dev, "Failed to request enable pin\n");
- return r;
+ phy->gpiod_ena = devm_gpiod_get_index(dev, ST21NFCA_GPIO_NAME_EN, 0,
+ GPIOD_OUT_HIGH);
+ if (IS_ERR(phy->gpiod_ena)) {
+ nfc_err(dev, "Failed to request enable pin\n");
+ return PTR_ERR(phy->gpiod_ena);
}
- phy->gpio_ena = gpio;
-
- phy->irq_polarity = irq_get_trigger_type(client->irq);
-
- phy->se_status.is_ese_present =
- of_property_read_bool(pp, "ese-present");
- phy->se_status.is_uicc_present =
- of_property_read_bool(pp, "uicc-present");
-
- return 0;
-}
-
-static int st21nfca_hci_i2c_request_resources(struct i2c_client *client)
-{
- struct st21nfca_nfc_platform_data *pdata;
- struct st21nfca_i2c_phy *phy = i2c_get_clientdata(client);
- int r;
-
- pdata = client->dev.platform_data;
- if (pdata == NULL) {
- nfc_err(&client->dev, "No platform data\n");
- return -EINVAL;
- }
-
- /* store for later use */
- phy->gpio_ena = pdata->gpio_ena;
- phy->irq_polarity = pdata->irq_polarity;
-
- if (phy->gpio_ena > 0) {
- r = devm_gpio_request_one(&client->dev, phy->gpio_ena,
- GPIOF_OUT_INIT_HIGH,
- ST21NFCA_GPIO_NAME_EN);
- if (r) {
- pr_err("%s : ena gpio_request failed\n", __FILE__);
- return r;
- }
- }
-
- phy->se_status.is_ese_present = pdata->is_ese_present;
- phy->se_status.is_uicc_present = pdata->is_uicc_present;
-
return 0;
}
@@ -613,7 +537,6 @@ static int st21nfca_hci_i2c_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct st21nfca_i2c_phy *phy;
- struct st21nfca_nfc_platform_data *pdata;
int r;
dev_dbg(&client->dev, "%s\n", __func__);
@@ -639,19 +562,12 @@ static int st21nfca_hci_i2c_probe(struct i2c_client *client,
mutex_init(&phy->phy_lock);
i2c_set_clientdata(client, phy);
- pdata = client->dev.platform_data;
- if (!pdata && client->dev.of_node) {
+ if (client->dev.of_node) {
r = st21nfca_hci_i2c_of_request_resources(client);
if (r) {
nfc_err(&client->dev, "No platform data\n");
return r;
}
- } else if (pdata) {
- r = st21nfca_hci_i2c_request_resources(client);
- if (r) {
- nfc_err(&client->dev, "Cannot get platform resources\n");
- return r;
- }
} else if (ACPI_HANDLE(&client->dev)) {
r = st21nfca_hci_i2c_acpi_request_resources(client);
if (r) {
@@ -663,6 +579,11 @@ static int st21nfca_hci_i2c_probe(struct i2c_client *client,
return -ENODEV;
}
+ phy->se_status.is_ese_present =
+ device_property_read_bool(&client->dev, "ese-present");
+ phy->se_status.is_uicc_present =
+ device_property_read_bool(&client->dev, "uicc-present");
+
r = st21nfca_hci_platform_init(phy);
if (r < 0) {
nfc_err(&client->dev, "Unable to reboot st21nfca\n");
@@ -671,7 +592,7 @@ static int st21nfca_hci_i2c_probe(struct i2c_client *client,
r = devm_request_threaded_irq(&client->dev, client->irq, NULL,
st21nfca_hci_irq_thread_fn,
- phy->irq_polarity | IRQF_ONESHOT,
+ IRQF_ONESHOT,
ST21NFCA_HCI_DRIVER_NAME, phy);
if (r < 0) {
nfc_err(&client->dev, "Unable to register IRQ handler\n");
diff --git a/drivers/nfc/trf7970a.c b/drivers/nfc/trf7970a.c
index 26c9dbbccb0c..2d1c8ca6e679 100644
--- a/drivers/nfc/trf7970a.c
+++ b/drivers/nfc/trf7970a.c
@@ -124,6 +124,9 @@
NFC_PROTO_ISO15693_MASK | NFC_PROTO_NFC_DEP_MASK)
#define TRF7970A_AUTOSUSPEND_DELAY 30000 /* 30 seconds */
+#define TRF7970A_13MHZ_CLOCK_FREQUENCY 13560000
+#define TRF7970A_27MHZ_CLOCK_FREQUENCY 27120000
+
#define TRF7970A_RX_SKB_ALLOC_SIZE 256
@@ -441,6 +444,7 @@ struct trf7970a {
u8 iso_ctrl_tech;
u8 modulator_sys_clk_ctrl;
u8 special_fcn_reg1;
+ u8 io_ctrl;
unsigned int guard_time;
int technology;
int framing;
@@ -1048,6 +1052,11 @@ static int trf7970a_init(struct trf7970a *trf)
if (ret)
goto err_out;
+ ret = trf7970a_write(trf, TRF7970A_REG_IO_CTRL,
+ trf->io_ctrl | TRF7970A_REG_IO_CTRL_VRS(0x1));
+ if (ret)
+ goto err_out;
+
ret = trf7970a_write(trf, TRF7970A_NFC_TARGET_LEVEL, 0);
if (ret)
goto err_out;
@@ -1056,12 +1065,11 @@ static int trf7970a_init(struct trf7970a *trf)
trf->chip_status_ctrl &= ~TRF7970A_CHIP_STATUS_RF_ON;
- ret = trf7970a_write(trf, TRF7970A_MODULATOR_SYS_CLK_CTRL, 0);
+ ret = trf7970a_write(trf, TRF7970A_MODULATOR_SYS_CLK_CTRL,
+ trf->modulator_sys_clk_ctrl);
if (ret)
goto err_out;
- trf->modulator_sys_clk_ctrl = 0;
-
ret = trf7970a_write(trf, TRF7970A_ADJUTABLE_FIFO_IRQ_LEVELS,
TRF7970A_ADJUTABLE_FIFO_IRQ_LEVELS_WLH_96 |
TRF7970A_ADJUTABLE_FIFO_IRQ_LEVELS_WLL_32);
@@ -1181,27 +1189,37 @@ static int trf7970a_in_config_rf_tech(struct trf7970a *trf, int tech)
switch (tech) {
case NFC_DIGITAL_RF_TECH_106A:
trf->iso_ctrl_tech = TRF7970A_ISO_CTRL_14443A_106;
- trf->modulator_sys_clk_ctrl = TRF7970A_MODULATOR_DEPTH_OOK;
+ trf->modulator_sys_clk_ctrl =
+ (trf->modulator_sys_clk_ctrl & 0xf8) |
+ TRF7970A_MODULATOR_DEPTH_OOK;
trf->guard_time = TRF7970A_GUARD_TIME_NFCA;
break;
case NFC_DIGITAL_RF_TECH_106B:
trf->iso_ctrl_tech = TRF7970A_ISO_CTRL_14443B_106;
- trf->modulator_sys_clk_ctrl = TRF7970A_MODULATOR_DEPTH_ASK10;
+ trf->modulator_sys_clk_ctrl =
+ (trf->modulator_sys_clk_ctrl & 0xf8) |
+ TRF7970A_MODULATOR_DEPTH_ASK10;
trf->guard_time = TRF7970A_GUARD_TIME_NFCB;
break;
case NFC_DIGITAL_RF_TECH_212F:
trf->iso_ctrl_tech = TRF7970A_ISO_CTRL_FELICA_212;
- trf->modulator_sys_clk_ctrl = TRF7970A_MODULATOR_DEPTH_ASK10;
+ trf->modulator_sys_clk_ctrl =
+ (trf->modulator_sys_clk_ctrl & 0xf8) |
+ TRF7970A_MODULATOR_DEPTH_ASK10;
trf->guard_time = TRF7970A_GUARD_TIME_NFCF;
break;
case NFC_DIGITAL_RF_TECH_424F:
trf->iso_ctrl_tech = TRF7970A_ISO_CTRL_FELICA_424;
- trf->modulator_sys_clk_ctrl = TRF7970A_MODULATOR_DEPTH_ASK10;
+ trf->modulator_sys_clk_ctrl =
+ (trf->modulator_sys_clk_ctrl & 0xf8) |
+ TRF7970A_MODULATOR_DEPTH_ASK10;
trf->guard_time = TRF7970A_GUARD_TIME_NFCF;
break;
case NFC_DIGITAL_RF_TECH_ISO15693:
trf->iso_ctrl_tech = TRF7970A_ISO_CTRL_15693_SGL_1OF4_2648;
- trf->modulator_sys_clk_ctrl = TRF7970A_MODULATOR_DEPTH_OOK;
+ trf->modulator_sys_clk_ctrl =
+ (trf->modulator_sys_clk_ctrl & 0xf8) |
+ TRF7970A_MODULATOR_DEPTH_OOK;
trf->guard_time = TRF7970A_GUARD_TIME_15693;
break;
default:
@@ -1571,17 +1589,23 @@ static int trf7970a_tg_config_rf_tech(struct trf7970a *trf, int tech)
trf->iso_ctrl_tech = TRF7970A_ISO_CTRL_NFC_NFC_CE_MODE |
TRF7970A_ISO_CTRL_NFC_CE |
TRF7970A_ISO_CTRL_NFC_CE_14443A;
- trf->modulator_sys_clk_ctrl = TRF7970A_MODULATOR_DEPTH_OOK;
+ trf->modulator_sys_clk_ctrl =
+ (trf->modulator_sys_clk_ctrl & 0xf8) |
+ TRF7970A_MODULATOR_DEPTH_OOK;
break;
case NFC_DIGITAL_RF_TECH_212F:
trf->iso_ctrl_tech = TRF7970A_ISO_CTRL_NFC_NFC_CE_MODE |
TRF7970A_ISO_CTRL_NFC_NFCF_212;
- trf->modulator_sys_clk_ctrl = TRF7970A_MODULATOR_DEPTH_ASK10;
+ trf->modulator_sys_clk_ctrl =
+ (trf->modulator_sys_clk_ctrl & 0xf8) |
+ TRF7970A_MODULATOR_DEPTH_ASK10;
break;
case NFC_DIGITAL_RF_TECH_424F:
trf->iso_ctrl_tech = TRF7970A_ISO_CTRL_NFC_NFC_CE_MODE |
TRF7970A_ISO_CTRL_NFC_NFCF_424;
- trf->modulator_sys_clk_ctrl = TRF7970A_MODULATOR_DEPTH_ASK10;
+ trf->modulator_sys_clk_ctrl =
+ (trf->modulator_sys_clk_ctrl & 0xf8) |
+ TRF7970A_MODULATOR_DEPTH_ASK10;
break;
default:
dev_dbg(trf->dev, "Unsupported rf technology: %d\n", tech);
@@ -1749,7 +1773,7 @@ static int _trf7970a_tg_listen(struct nfc_digital_dev *ddev, u16 timeout,
goto out_err;
ret = trf7970a_write(trf, TRF7970A_REG_IO_CTRL,
- TRF7970A_REG_IO_CTRL_VRS(0x1));
+ trf->io_ctrl | TRF7970A_REG_IO_CTRL_VRS(0x1));
if (ret)
goto out_err;
@@ -1885,8 +1909,10 @@ static int trf7970a_power_up(struct trf7970a *trf)
usleep_range(5000, 6000);
if (!(trf->quirks & TRF7970A_QUIRK_EN2_MUST_STAY_LOW)) {
- gpio_set_value(trf->en2_gpio, 1);
- usleep_range(1000, 2000);
+ if (gpio_is_valid(trf->en2_gpio)) {
+ gpio_set_value(trf->en2_gpio, 1);
+ usleep_range(1000, 2000);
+ }
}
gpio_set_value(trf->en_gpio, 1);
@@ -1914,7 +1940,8 @@ static int trf7970a_power_down(struct trf7970a *trf)
}
gpio_set_value(trf->en_gpio, 0);
- gpio_set_value(trf->en2_gpio, 0);
+ if (gpio_is_valid(trf->en2_gpio))
+ gpio_set_value(trf->en2_gpio, 0);
ret = regulator_disable(trf->regulator);
if (ret)
@@ -1987,6 +2014,7 @@ static int trf7970a_probe(struct spi_device *spi)
struct device_node *np = spi->dev.of_node;
struct trf7970a *trf;
int uvolts, autosuspend_delay, ret;
+ u32 clk_freq = TRF7970A_13MHZ_CLOCK_FREQUENCY;
if (!np) {
dev_err(&spi->dev, "No Device Tree entry\n");
@@ -2032,15 +2060,23 @@ static int trf7970a_probe(struct spi_device *spi)
trf->en2_gpio = of_get_named_gpio(np, "ti,enable-gpios", 1);
if (!gpio_is_valid(trf->en2_gpio)) {
- dev_err(trf->dev, "No EN2 GPIO property\n");
- return trf->en2_gpio;
+ dev_info(trf->dev, "No EN2 GPIO property\n");
+ } else {
+ ret = devm_gpio_request_one(trf->dev, trf->en2_gpio,
+ GPIOF_DIR_OUT | GPIOF_INIT_LOW, "trf7970a EN2");
+ if (ret) {
+ dev_err(trf->dev, "Can't request EN2 GPIO: %d\n", ret);
+ return ret;
+ }
}
- ret = devm_gpio_request_one(trf->dev, trf->en2_gpio,
- GPIOF_DIR_OUT | GPIOF_INIT_LOW, "trf7970a EN2");
- if (ret) {
- dev_err(trf->dev, "Can't request EN2 GPIO: %d\n", ret);
- return ret;
+ of_property_read_u32(np, "clock-frequency", &clk_freq);
+ if ((clk_freq != TRF7970A_27MHZ_CLOCK_FREQUENCY) ||
+ (clk_freq != TRF7970A_13MHZ_CLOCK_FREQUENCY)) {
+ dev_err(trf->dev,
+ "clock-frequency (%u Hz) unsupported\n",
+ clk_freq);
+ return -EINVAL;
}
if (of_property_read_bool(np, "en2-rf-quirk"))
@@ -2077,6 +2113,24 @@ static int trf7970a_probe(struct spi_device *spi)
if (uvolts > 4000000)
trf->chip_status_ctrl = TRF7970A_CHIP_STATUS_VRS5_3;
+ trf->regulator = devm_regulator_get(&spi->dev, "vdd-io");
+ if (IS_ERR(trf->regulator)) {
+ ret = PTR_ERR(trf->regulator);
+ dev_err(trf->dev, "Can't get VDD_IO regulator: %d\n", ret);
+ goto err_destroy_lock;
+ }
+
+ ret = regulator_enable(trf->regulator);
+ if (ret) {
+ dev_err(trf->dev, "Can't enable VDD_IO: %d\n", ret);
+ goto err_destroy_lock;
+ }
+
+ if (regulator_get_voltage(trf->regulator) == 1800000) {
+ trf->io_ctrl = TRF7970A_REG_IO_CTRL_IO_LOW;
+ dev_dbg(trf->dev, "trf7970a config vdd_io to 1.8V\n");
+ }
+
trf->ddev = nfc_digital_allocate_device(&trf7970a_nfc_ops,
TRF7970A_SUPPORTED_PROTOCOLS,
NFC_DIGITAL_DRV_CAPS_IN_CRC |
diff --git a/include/linux/platform_data/pn544.h b/include/linux/platform_data/pn544.h
deleted file mode 100644
index 5ce1ab983f44..000000000000
--- a/include/linux/platform_data/pn544.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Driver include for the PN544 NFC chip.
- *
- * Copyright (C) Nokia Corporation
- *
- * Author: Jari Vanhala <ext-jari.vanhala@nokia.com>
- * Contact: Matti Aaltoenn <matti.j.aaltonen@nokia.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef _PN544_H_
-#define _PN544_H_
-
-#include <linux/i2c.h>
-
-enum {
- NFC_GPIO_ENABLE,
- NFC_GPIO_FW_RESET,
- NFC_GPIO_IRQ
-};
-
-/* board config */
-struct pn544_nfc_platform_data {
- int (*request_resources) (struct i2c_client *client);
- void (*free_resources) (void);
- void (*enable) (int fw);
- int (*test) (void);
- void (*disable) (void);
- int (*get_gpio)(int type);
-};
-
-#endif /* _PN544_H_ */
diff --git a/include/linux/platform_data/st21nfca.h b/include/linux/platform_data/st21nfca.h
deleted file mode 100644
index cc2bdafb0c69..000000000000
--- a/include/linux/platform_data/st21nfca.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Driver include for the ST21NFCA NFC chip.
- *
- * Copyright (C) 2014 STMicroelectronics SAS. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef _ST21NFCA_HCI_H_
-#define _ST21NFCA_HCI_H_
-
-#include <linux/i2c.h>
-
-#define ST21NFCA_HCI_DRIVER_NAME "st21nfca_hci"
-
-struct st21nfca_nfc_platform_data {
- unsigned int gpio_ena;
- unsigned int irq_polarity;
- bool is_ese_present;
- bool is_uicc_present;
-};
-
-#endif /* _ST21NFCA_HCI_H_ */
diff --git a/include/net/nfc/nfc.h b/include/net/nfc/nfc.h
index 1a3de8b34ad2..bbdc73a3239d 100644
--- a/include/net/nfc/nfc.h
+++ b/include/net/nfc/nfc.h
@@ -27,6 +27,7 @@
#include <linux/device.h>
#include <linux/skbuff.h>
+#define nfc_dbg(dev, fmt, ...) dev_dbg((dev), "NFC: " fmt, ##__VA_ARGS__)
#define nfc_info(dev, fmt, ...) dev_info((dev), "NFC: " fmt, ##__VA_ARGS__)
#define nfc_err(dev, fmt, ...) dev_err((dev), "NFC: " fmt, ##__VA_ARGS__)
diff --git a/net/nfc/netlink.c b/net/nfc/netlink.c
index 529443acd3bc..6b0850e63e09 100644
--- a/net/nfc/netlink.c
+++ b/net/nfc/netlink.c
@@ -304,6 +304,17 @@ free_msg:
return -EMSGSIZE;
}
+static int nfc_genl_setup_device_added(struct nfc_dev *dev, struct sk_buff *msg)
+{
+ if (nla_put_string(msg, NFC_ATTR_DEVICE_NAME, nfc_device_name(dev)) ||
+ nla_put_u32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx) ||
+ nla_put_u32(msg, NFC_ATTR_PROTOCOLS, dev->supported_protocols) ||
+ nla_put_u8(msg, NFC_ATTR_DEVICE_POWERED, dev->dev_up) ||
+ nla_put_u8(msg, NFC_ATTR_RF_MODE, dev->rf_mode))
+ return -1;
+ return 0;
+}
+
int nfc_genl_device_added(struct nfc_dev *dev)
{
struct sk_buff *msg;
@@ -318,10 +329,7 @@ int nfc_genl_device_added(struct nfc_dev *dev)
if (!hdr)
goto free_msg;
- if (nla_put_string(msg, NFC_ATTR_DEVICE_NAME, nfc_device_name(dev)) ||
- nla_put_u32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx) ||
- nla_put_u32(msg, NFC_ATTR_PROTOCOLS, dev->supported_protocols) ||
- nla_put_u8(msg, NFC_ATTR_DEVICE_POWERED, dev->dev_up))
+ if (nfc_genl_setup_device_added(dev, msg))
goto nla_put_failure;
genlmsg_end(msg, hdr);
@@ -597,11 +605,7 @@ static int nfc_genl_send_device(struct sk_buff *msg, struct nfc_dev *dev,
if (cb)
genl_dump_check_consistent(cb, hdr, &nfc_genl_family);
- if (nla_put_string(msg, NFC_ATTR_DEVICE_NAME, nfc_device_name(dev)) ||
- nla_put_u32(msg, NFC_ATTR_DEVICE_INDEX, dev->idx) ||
- nla_put_u32(msg, NFC_ATTR_PROTOCOLS, dev->supported_protocols) ||
- nla_put_u8(msg, NFC_ATTR_DEVICE_POWERED, dev->dev_up) ||
- nla_put_u8(msg, NFC_ATTR_RF_MODE, dev->rf_mode))
+ if (nfc_genl_setup_device_added(dev, msg))
goto nla_put_failure;
genlmsg_end(msg, hdr);
@@ -919,7 +923,7 @@ static int nfc_genl_activate_target(struct sk_buff *skb, struct genl_info *info)
rc = nfc_activate_target(dev, target_idx, protocol);
nfc_put_device(dev);
- return 0;
+ return rc;
}
static int nfc_genl_dep_link_up(struct sk_buff *skb, struct genl_info *info)