Commit 69e3948a authored by David S. Miller's avatar David S. Miller

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: default avatarDavid S. Miller <davem@davemloft.net>
parents ea8ffc08 4ea20639
...@@ -5,8 +5,8 @@ Required properties: ...@@ -5,8 +5,8 @@ Required properties:
- spi-max-frequency: Maximum SPI frequency (<= 2000000). - spi-max-frequency: Maximum SPI frequency (<= 2000000).
- interrupt-parent: phandle of parent interrupt handler. - interrupt-parent: phandle of parent interrupt handler.
- interrupts: A single interrupt specifier. - interrupts: A single interrupt specifier.
- ti,enable-gpios: Two GPIO entries used for 'EN' and 'EN2' pins on the - ti,enable-gpios: One or two GPIO entries used for 'EN' and 'EN2' pins on the
TRF7970A. TRF7970A. EN2 is optional.
- vin-supply: Regulator for supply voltage to VIN pin - vin-supply: Regulator for supply voltage to VIN pin
Optional SoC Specific Properties: Optional SoC Specific Properties:
...@@ -21,6 +21,8 @@ Optional SoC Specific Properties: ...@@ -21,6 +21,8 @@ Optional SoC Specific Properties:
- t5t-rmb-extra-byte-quirk: Specify that the trf7970a has the erratum - t5t-rmb-extra-byte-quirk: Specify that the trf7970a has the erratum
where an extra byte is returned by Read Multiple Block commands issued where an extra byte is returned by Read Multiple Block commands issued
to Type 5 tags. 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): Example (for ARM-based BeagleBone with TRF7970A on SPI1):
...@@ -39,10 +41,12 @@ 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>; <&gpio2 5 GPIO_ACTIVE_LOW>;
vin-supply = <&ldo3_reg>; vin-supply = <&ldo3_reg>;
vin-voltage-override = <5000000>; vin-voltage-override = <5000000>;
vdd-io-supply = <&ldo2_reg>;
autosuspend-delay = <30000>; autosuspend-delay = <30000>;
irq-status-read-quirk; irq-status-read-quirk;
en2-rf-quirk; en2-rf-quirk;
t5t-rmb-extra-byte-quirk; t5t-rmb-extra-byte-quirk;
clock-frequency = <27120000>;
status = "okay"; status = "okay";
}; };
}; };
...@@ -8876,8 +8876,6 @@ S: Supported ...@@ -8876,8 +8876,6 @@ S: Supported
F: drivers/net/ethernet/qlogic/netxen/ F: drivers/net/ethernet/qlogic/netxen/
NFC SUBSYSTEM 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> M: Samuel Ortiz <sameo@linux.intel.com>
L: linux-wireless@vger.kernel.org L: linux-wireless@vger.kernel.org
L: linux-nfc@lists.01.org (subscribers-only) L: linux-nfc@lists.01.org (subscribers-only)
......
...@@ -5,17 +5,6 @@ ...@@ -5,17 +5,6 @@
menu "Near Field Communication (NFC) devices" menu "Near Field Communication (NFC) devices"
depends on NFC 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 config NFC_TRF7970A
tristate "Texas Instruments TRF7970a NFC driver" tristate "Texas Instruments TRF7970a NFC driver"
depends on SPI && NFC_DIGITAL depends on SPI && NFC_DIGITAL
......
...@@ -6,7 +6,6 @@ obj-$(CONFIG_NFC_FDP) += fdp/ ...@@ -6,7 +6,6 @@ obj-$(CONFIG_NFC_FDP) += fdp/
obj-$(CONFIG_NFC_PN544) += pn544/ obj-$(CONFIG_NFC_PN544) += pn544/
obj-$(CONFIG_NFC_MICROREAD) += microread/ obj-$(CONFIG_NFC_MICROREAD) += microread/
obj-$(CONFIG_NFC_PN533) += pn533/ obj-$(CONFIG_NFC_PN533) += pn533/
obj-$(CONFIG_NFC_WILINK) += nfcwilink.o
obj-$(CONFIG_NFC_MEI_PHY) += mei_phy.o obj-$(CONFIG_NFC_MEI_PHY) += mei_phy.o
obj-$(CONFIG_NFC_SIM) += nfcsim.o obj-$(CONFIG_NFC_SIM) += nfcsim.o
obj-$(CONFIG_NFC_PORT100) += port100.o obj-$(CONFIG_NFC_PORT100) += port100.o
......
...@@ -210,14 +210,14 @@ static irqreturn_t fdp_nci_i2c_irq_thread_fn(int irq, void *phy_id) ...@@ -210,14 +210,14 @@ static irqreturn_t fdp_nci_i2c_irq_thread_fn(int irq, void *phy_id)
struct sk_buff *skb; struct sk_buff *skb;
int r; int r;
client = phy->i2c_dev;
dev_dbg(&client->dev, "%s\n", __func__);
if (!phy || irq != phy->i2c_dev->irq) { if (!phy || irq != phy->i2c_dev->irq) {
WARN_ON_ONCE(1); WARN_ON_ONCE(1);
return IRQ_NONE; return IRQ_NONE;
} }
client = phy->i2c_dev;
dev_dbg(&client->dev, "%s\n", __func__);
r = fdp_nci_i2c_read(phy, &skb); r = fdp_nci_i2c_read(phy, &skb);
if (r == -EREMOTEIO) if (r == -EREMOTEIO)
......
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
*/ */
#include <linux/module.h> #include <linux/module.h>
#include <linux/unaligned/access_ok.h> #include <asm/unaligned.h>
#include <linux/firmware.h> #include <linux/firmware.h>
#include <linux/nfc.h> #include <linux/nfc.h>
#include <net/nfc/nci.h> #include <net/nfc/nci.h>
...@@ -281,12 +281,11 @@ static int process_state_fw_dnld(struct nfcmrvl_private *priv, ...@@ -281,12 +281,11 @@ static int process_state_fw_dnld(struct nfcmrvl_private *priv,
return -EINVAL; return -EINVAL;
} }
skb_pull(skb, 1); skb_pull(skb, 1);
memcpy(&len, skb->data, 2); len = get_unaligned_le16(skb->data);
skb_pull(skb, 2); skb_pull(skb, 2);
comp_len = get_unaligned_le16(skb->data);
memcpy(&comp_len, skb->data, 2); memcpy(&comp_len, skb->data, 2);
skb_pull(skb, 2); skb_pull(skb, 2);
len = get_unaligned_le16(&len);
comp_len = get_unaligned_le16(&comp_len);
if (((~len) & 0xFFFF) != comp_len) { if (((~len) & 0xFFFF) != comp_len) {
nfc_err(priv->dev, "bad len complement: %x %x %x", nfc_err(priv->dev, "bad len complement: %x %x %x",
len, comp_len, (~len & 0xFFFF)); len, comp_len, (~len & 0xFFFF));
......
...@@ -26,7 +26,6 @@ ...@@ -26,7 +26,6 @@
#include <net/nfc/nci.h> #include <net/nfc/nci.h>
#include <net/nfc/nci_core.h> #include <net/nfc/nci_core.h>
#include <linux/spi/spi.h> #include <linux/spi/spi.h>
#include <linux/gpio.h>
#include "nfcmrvl.h" #include "nfcmrvl.h"
#define SPI_WAIT_HANDSHAKE 1 #define SPI_WAIT_HANDSHAKE 1
...@@ -96,10 +95,9 @@ static int nfcmrvl_spi_nci_send(struct nfcmrvl_private *priv, ...@@ -96,10 +95,9 @@ static int nfcmrvl_spi_nci_send(struct nfcmrvl_private *priv,
/* Send the SPI packet */ /* Send the SPI packet */
err = nci_spi_send(drv_data->nci_spi, &drv_data->handshake_completion, err = nci_spi_send(drv_data->nci_spi, &drv_data->handshake_completion,
skb); skb);
if (err != 0) { if (err)
nfc_err(priv->dev, "spi_send failed %d", err); nfc_err(priv->dev, "spi_send failed %d", err);
kfree_skb(skb);
}
return err; return err;
} }
......
This diff is collapsed.
...@@ -24,7 +24,7 @@ ...@@ -24,7 +24,7 @@
#include <linux/completion.h> #include <linux/completion.h>
#include <linux/firmware.h> #include <linux/firmware.h>
#include <linux/nfc.h> #include <linux/nfc.h>
#include <linux/unaligned/access_ok.h> #include <asm/unaligned.h>
#include "nxp-nci.h" #include "nxp-nci.h"
......
...@@ -29,14 +29,13 @@ ...@@ -29,14 +29,13 @@
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/miscdevice.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/nfc.h> #include <linux/nfc.h>
#include <linux/gpio/consumer.h> #include <linux/gpio/consumer.h>
#include <linux/of_gpio.h> #include <linux/of_gpio.h>
#include <linux/of_irq.h> #include <linux/of_irq.h>
#include <linux/platform_data/nxp-nci.h> #include <linux/platform_data/nxp-nci.h>
#include <linux/unaligned/access_ok.h> #include <asm/unaligned.h>
#include <net/nfc/nfc.h> #include <net/nfc/nfc.h>
...@@ -86,7 +85,7 @@ static int nxp_nci_i2c_write(void *phy_id, struct sk_buff *skb) ...@@ -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); r = i2c_master_send(client, skb->data, skb->len);
if (r < 0) { if (r < 0) {
/* Retry, chip was in standby */ /* Retry, chip was in standby */
usleep_range(110000, 120000); msleep(110);
r = i2c_master_send(client, skb->data, skb->len); 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, ...@@ -127,7 +126,7 @@ static int nxp_nci_i2c_fw_read(struct nxp_nci_i2c_phy *phy,
goto fw_read_exit; 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; NXP_NCI_FW_CRC_LEN;
*skb = alloc_skb(NXP_NCI_FW_HDR_LEN + frame_len, GFP_KERNEL); *skb = alloc_skb(NXP_NCI_FW_HDR_LEN + frame_len, GFP_KERNEL);
......
...@@ -51,7 +51,7 @@ static int pn533_i2c_send_ack(struct pn533 *dev, gfp_t flags) ...@@ -51,7 +51,7 @@ static int pn533_i2c_send_ack(struct pn533 *dev, gfp_t flags)
{ {
struct pn533_i2c_phy *phy = dev->phy; struct pn533_i2c_phy *phy = dev->phy;
struct i2c_client *client = phy->i2c_dev; 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 */ /* spec 6.2.1.3: Preamble, SoPC (2), ACK Code (2), Postamble */
int rc; int rc;
...@@ -206,14 +206,6 @@ static int pn533_i2c_probe(struct i2c_client *client, ...@@ -206,14 +206,6 @@ static int pn533_i2c_probe(struct i2c_client *client,
phy->i2c_dev = client; phy->i2c_dev = client;
i2c_set_clientdata(client, phy); 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, priv = pn533_register_device(PN533_DEVICE_PN532,
PN533_NO_TYPE_B_PROTOCOLS, PN533_NO_TYPE_B_PROTOCOLS,
PN533_PROTO_REQ_ACK_RESP, PN533_PROTO_REQ_ACK_RESP,
...@@ -223,16 +215,32 @@ static int pn533_i2c_probe(struct i2c_client *client, ...@@ -223,16 +215,32 @@ static int pn533_i2c_probe(struct i2c_client *client,
if (IS_ERR(priv)) { if (IS_ERR(priv)) {
r = PTR_ERR(priv); r = PTR_ERR(priv);
goto err_register; return r;
} }
phy->priv = priv; 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; return 0;
err_register: fn_setup_err:
free_irq(client->irq, phy); free_irq(client->irq, phy);
irq_rqst_err:
pn533_unregister_device(phy->priv);
return r; return r;
} }
...@@ -242,10 +250,10 @@ static int pn533_i2c_remove(struct i2c_client *client) ...@@ -242,10 +250,10 @@ static int pn533_i2c_remove(struct i2c_client *client)
dev_dbg(&client->dev, "%s\n", __func__); dev_dbg(&client->dev, "%s\n", __func__);
pn533_unregister_device(phy->priv);
free_irq(client->irq, phy); free_irq(client->irq, phy);
pn533_unregister_device(phy->priv);
return 0; return 0;
} }
......
...@@ -383,14 +383,18 @@ static void pn533_build_cmd_frame(struct pn533 *dev, u8 cmd_code, ...@@ -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) static int pn533_send_async_complete(struct pn533 *dev)
{ {
struct pn533_cmd *cmd = dev->cmd; struct pn533_cmd *cmd = dev->cmd;
int status = cmd->status; struct sk_buff *resp;
int status, rc = 0;
struct sk_buff *req = cmd->req; if (!cmd) {
struct sk_buff *resp = cmd->resp; 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) { if (status < 0) {
rc = cmd->complete_cb(dev, cmd->complete_cb_context, rc = cmd->complete_cb(dev, cmd->complete_cb_context,
...@@ -399,8 +403,14 @@ static int pn533_send_async_complete(struct pn533 *dev) ...@@ -399,8 +403,14 @@ static int pn533_send_async_complete(struct pn533 *dev)
goto done; goto done;
} }
skb_pull(resp, dev->ops->rx_header_len); /* when no response is set we got interrupted */
skb_trim(resp, resp->len - dev->ops->rx_tail_len); 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); 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, ...@@ -434,12 +444,14 @@ static int __pn533_send_async(struct pn533 *dev, u8 cmd_code,
mutex_lock(&dev->cmd_lock); mutex_lock(&dev->cmd_lock);
if (!dev->cmd_pending) { if (!dev->cmd_pending) {
dev->cmd = cmd;
rc = dev->phy_ops->send_frame(dev, req); rc = dev->phy_ops->send_frame(dev, req);
if (rc) if (rc) {
dev->cmd = NULL;
goto error; goto error;
}
dev->cmd_pending = 1; dev->cmd_pending = 1;
dev->cmd = cmd;
goto unlock; goto unlock;
} }
...@@ -511,11 +523,12 @@ static int pn533_send_cmd_direct_async(struct pn533 *dev, u8 cmd_code, ...@@ -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); pn533_build_cmd_frame(dev, cmd_code, req);
dev->cmd = cmd;
rc = dev->phy_ops->send_frame(dev, req); rc = dev->phy_ops->send_frame(dev, req);
if (rc < 0) if (rc < 0) {
dev->cmd = NULL;
kfree(cmd); kfree(cmd);
else }
dev->cmd = cmd;
return rc; return rc;
} }
...@@ -550,14 +563,15 @@ static void pn533_wq_cmd(struct work_struct *work) ...@@ -550,14 +563,15 @@ static void pn533_wq_cmd(struct work_struct *work)
mutex_unlock(&dev->cmd_lock); mutex_unlock(&dev->cmd_lock);
dev->cmd = cmd;
rc = dev->phy_ops->send_frame(dev, cmd->req); rc = dev->phy_ops->send_frame(dev, cmd->req);
if (rc < 0) { if (rc < 0) {
dev->cmd = NULL;
dev_kfree_skb(cmd->req); dev_kfree_skb(cmd->req);
kfree(cmd); kfree(cmd);
return; return;
} }
dev->cmd = cmd;
} }
struct pn533_sync_cmd_response { struct pn533_sync_cmd_response {
...@@ -2556,6 +2570,31 @@ static int pn533_setup(struct pn533 *dev) ...@@ -2556,6 +2570,31 @@ static int pn533_setup(struct pn533 *dev)
return 0; 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, struct pn533 *pn533_register_device(u32 device_type,
u32 protocols, u32 protocols,
enum pn533_protocol_type protocol_type, enum pn533_protocol_type protocol_type,
...@@ -2565,7 +2604,6 @@ struct pn533 *pn533_register_device(u32 device_type, ...@@ -2565,7 +2604,6 @@ struct pn533 *pn533_register_device(u32 device_type,
struct device *dev, struct device *dev,
struct device *parent) struct device *parent)
{ {
struct pn533_fw_version fw_ver;
struct pn533 *priv; struct pn533 *priv;
int rc = -ENOMEM; int rc = -ENOMEM;
...@@ -2608,15 +2646,6 @@ struct pn533 *pn533_register_device(u32 device_type, ...@@ -2608,15 +2646,6 @@ struct pn533 *pn533_register_device(u32 device_type,
INIT_LIST_HEAD(&priv->cmd_queue); 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->nfc_dev = nfc_allocate_device(&pn533_nfc_ops, protocols,
priv->ops->tx_header_len + priv->ops->tx_header_len +
PN533_CMD_DATAEXCH_HEAD_LEN, PN533_CMD_DATAEXCH_HEAD_LEN,
...@@ -2633,15 +2662,8 @@ struct pn533 *pn533_register_device(u32 device_type, ...@@ -2633,15 +2662,8 @@ struct pn533 *pn533_register_device(u32 device_type,
if (rc) if (rc)
goto free_nfc_dev; goto free_nfc_dev;
rc = pn533_setup(priv);
if (rc)
goto unregister_nfc_dev;
return priv; return priv;
unregister_nfc_dev:
nfc_unregister_device(priv->nfc_dev);
free_nfc_dev: free_nfc_dev:
nfc_free_device(priv->nfc_dev); nfc_free_device(priv->nfc_dev);
......
...@@ -231,6 +231,7 @@ struct pn533 *pn533_register_device(u32 device_type, ...@@ -231,6 +231,7 @@ struct pn533 *pn533_register_device(u32 device_type,
struct device *dev, struct device *dev,
struct device *parent); struct device *parent);
int pn533_finalize_setup(struct pn533 *dev);
void pn533_unregister_device(struct pn533 *priv); void pn533_unregister_device(struct pn533 *priv);
void pn533_recv_frame(struct pn533 *dev, struct sk_buff *skb, int status); void pn533_recv_frame(struct pn533 *dev, struct sk_buff *skb, int status);
......
...@@ -148,11 +148,11 @@ static int pn533_submit_urb_for_ack(struct pn533_usb_phy *phy, gfp_t flags) ...@@ -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) static int pn533_usb_send_ack(struct pn533 *dev, gfp_t flags)
{ {
struct pn533_usb_phy *phy = dev->phy; 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 */ /* spec 7.1.1.3: Preamble, SoPC (2), ACK Code (2), Postamble */
int rc; int rc;
phy->out_urb->transfer_buffer = ack; phy->out_urb->transfer_buffer = (u8 *)ack;
phy->out_urb->transfer_buffer_length = sizeof(ack); phy->out_urb->transfer_buffer_length = sizeof(ack);
rc = usb_submit_urb(phy->out_urb, flags); rc = usb_submit_urb(phy->out_urb, flags);
...@@ -543,6 +543,10 @@ static int pn533_usb_probe(struct usb_interface *interface, ...@@ -543,6 +543,10 @@ static int pn533_usb_probe(struct usb_interface *interface,
phy->priv = priv; phy->priv = priv;
rc = pn533_finalize_setup(priv);
if (rc)
goto error;
usb_set_intfdata(interface, phy); usb_set_intfdata(interface, phy);
return 0; return 0;
......
...@@ -21,17 +21,13 @@ ...@@ -21,17 +21,13 @@
#include <linux/crc-ccitt.h> #include <linux/crc-ccitt.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/i2c.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/acpi.h>
#include <linux/miscdevice.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/nfc.h> #include <linux/nfc.h>
#include <linux/firmware.h> #include <linux/firmware.h>
#include <linux/gpio/consumer.h> #include <linux/gpio/consumer.h>
#include <linux/platform_data/pn544.h>
#include <asm/unaligned.h> #include <asm/unaligned.h>
#include <net/nfc/hci.h> #include <net/nfc/hci.h>
...@@ -165,8 +161,9 @@ struct pn544_i2c_phy { ...@@ -165,8 +161,9 @@ struct pn544_i2c_phy {
struct i2c_client *i2c_dev; struct i2c_client *i2c_dev;
struct nfc_hci_dev *hdev; struct nfc_hci_dev *hdev;
unsigned int gpio_en; struct gpio_desc *gpiod_en;
unsigned int gpio_fw; struct gpio_desc *gpiod_fw;
unsigned int en_polarity; unsigned int en_polarity;
u8 hw_variant; u8 hw_variant;
...@@ -208,19 +205,18 @@ static void pn544_hci_i2c_platform_init(struct pn544_i2c_phy *phy) ...@@ -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"); nfc_info(&phy->i2c_dev->dev, "Detecting nfc_en polarity\n");
/* Disable fw download */ /* 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++) { for (polarity = 0; polarity < 2; polarity++) {
phy->en_polarity = polarity; phy->en_polarity = polarity;
retry = 3; retry = 3;
while (retry--) { while (retry--) {
/* power off */ /* power off */
gpio_set_value_cansleep(phy->gpio_en, gpiod_set_value_cansleep(phy->gpiod_en, !phy->en_polarity);
!phy->en_polarity);
usleep_range(10000, 15000); usleep_range(10000, 15000);
/* power on */ /* 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); usleep_range(10000, 15000);
/* send reset */ /* send reset */
...@@ -239,14 +235,13 @@ static void pn544_hci_i2c_platform_init(struct pn544_i2c_phy *phy) ...@@ -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"); "Could not detect nfc_en polarity, fallback to active high\n");
out: 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) static void pn544_hci_i2c_enable_mode(struct pn544_i2c_phy *phy, int run_mode)
{ {
gpio_set_value_cansleep(phy->gpio_fw, gpiod_set_value_cansleep(phy->gpiod_fw, run_mode == PN544_FW_MODE ? 1 : 0);
run_mode == PN544_FW_MODE ? 1 : 0); gpiod_set_value_cansleep(phy->gpiod_en, phy->en_polarity);
gpio_set_value_cansleep(phy->gpio_en, phy->en_polarity);
usleep_range(10000, 15000); usleep_range(10000, 15000);
phy->run_mode = run_mode; phy->run_mode = run_mode;
...@@ -269,14 +264,14 @@ static void pn544_hci_i2c_disable(void *phy_id) ...@@ -269,14 +264,14 @@ static void pn544_hci_i2c_disable(void *phy_id)
{ {
struct pn544_i2c_phy *phy = phy_id; struct pn544_i2c_phy *phy = phy_id;
gpio_set_value_cansleep(phy->gpio_fw, 0); gpiod_set_value_cansleep(phy->gpiod_fw, 0);
gpio_set_value_cansleep(phy->gpio_en, !phy->en_polarity); gpiod_set_value_cansleep(phy->gpiod_en, !phy->en_polarity);
usleep_range(10000, 15000); 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); 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); usleep_range(10000, 15000);
phy->powered = 0; phy->powered = 0;
...@@ -874,106 +869,20 @@ static void pn544_hci_i2c_fw_work(struct work_struct *work) ...@@ -874,106 +869,20 @@ static void pn544_hci_i2c_fw_work(struct work_struct *work)
} }
} }
static int pn544_hci_i2c_acpi_request_resources(struct i2c_client *client) static const struct acpi_gpio_params enable_gpios = { 1, 0, false };
{ static const struct acpi_gpio_params firmware_gpios = { 2, 0, false };
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;
err_gpio_fw: static const struct acpi_gpio_mapping acpi_pn544_gpios[] = {
gpio_free(phy->gpio_fw); { "enable-gpios", &enable_gpios, 1 },
err_gpio_en: { "firmware-gpios", &firmware_gpios, 1 },
gpio_free(phy->gpio_en); { },
err_dt: };
return ret;
}
static int pn544_hci_i2c_probe(struct i2c_client *client, static int pn544_hci_i2c_probe(struct i2c_client *client,
const struct i2c_device_id *id) const struct i2c_device_id *id)
{ {
struct device *dev = &client->dev;
struct pn544_i2c_phy *phy; struct pn544_i2c_phy *phy;
struct pn544_nfc_platform_data *pdata;
int r = 0; int r = 0;
dev_dbg(&client->dev, "%s\n", __func__); dev_dbg(&client->dev, "%s\n", __func__);
...@@ -995,53 +904,33 @@ static int pn544_hci_i2c_probe(struct i2c_client *client, ...@@ -995,53 +904,33 @@ static int pn544_hci_i2c_probe(struct i2c_client *client,
phy->i2c_dev = client; phy->i2c_dev = client;
i2c_set_clientdata(client, phy); i2c_set_clientdata(client, phy);
pdata = client->dev.platform_data; r = acpi_dev_add_driver_gpios(ACPI_COMPANION(dev), acpi_pn544_gpios);
if (r)
/* No platform data, using device tree. */ dev_dbg(dev, "Unable to add GPIO mapping table\n");
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 = pdata->request_resources(client); /* Get EN GPIO */
if (r) { phy->gpiod_en = devm_gpiod_get(dev, "enable", GPIOD_OUT_LOW);
nfc_err(&client->dev, if (IS_ERR(phy->gpiod_en)) {
"Cannot get platform resources\n"); nfc_err(dev, "Unable to get EN GPIO\n");
return r; return PTR_ERR(phy->gpiod_en);
} }
phy->gpio_en = pdata->get_gpio(NFC_GPIO_ENABLE); /* Get FW GPIO */
phy->gpio_fw = pdata->get_gpio(NFC_GPIO_FW_RESET); phy->gpiod_fw = devm_gpiod_get(dev, "firmware", GPIOD_OUT_LOW);
/* Using ACPI */ if (IS_ERR(phy->gpiod_fw)) {
} else if (ACPI_HANDLE(&client->dev)) { nfc_err(dev, "Unable to get FW GPIO\n");
r = pn544_hci_i2c_acpi_request_resources(client); return PTR_ERR(phy->gpiod_fw);
if (r) {
nfc_err(&client->dev,
"Cannot get ACPI data\n");
return r;
}
} else {
nfc_err(&client->dev, "No platform data\n");
return -EINVAL;
} }
pn544_hci_i2c_platform_init(phy); pn544_hci_i2c_platform_init(phy);
r = request_threaded_irq(client->irq, NULL, pn544_hci_i2c_irq_thread_fn, r = devm_request_threaded_irq(&client->dev, client->irq, NULL,
IRQF_TRIGGER_RISING | IRQF_ONESHOT, pn544_hci_i2c_irq_thread_fn,
PN544_HCI_I2C_DRIVER_NAME, phy); IRQF_TRIGGER_RISING | IRQF_ONESHOT,
PN544_HCI_I2C_DRIVER_NAME, phy);
if (r < 0) { if (r < 0) {
nfc_err(&client->dev, "Unable to register IRQ handler\n"); 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, 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, ...@@ -1049,28 +938,14 @@ static int pn544_hci_i2c_probe(struct i2c_client *client,
PN544_HCI_I2C_LLC_MAX_PAYLOAD, PN544_HCI_I2C_LLC_MAX_PAYLOAD,
pn544_hci_i2c_fw_download, &phy->hdev); pn544_hci_i2c_fw_download, &phy->hdev);
if (r < 0) if (r < 0)
goto err_hci; return r;
return 0; 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) static int pn544_hci_i2c_remove(struct i2c_client *client)
{ {
struct pn544_i2c_phy *phy = i2c_get_clientdata(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__); dev_dbg(&client->dev, "%s\n", __func__);
...@@ -1083,17 +958,7 @@ static int pn544_hci_i2c_remove(struct i2c_client *client) ...@@ -1083,17 +958,7 @@ static int pn544_hci_i2c_remove(struct i2c_client *client)
if (phy->powered) if (phy->powered)
pn544_hci_i2c_disable(phy); pn544_hci_i2c_disable(phy);
free_irq(client->irq, phy); acpi_dev_remove_driver_gpios(ACPI_COMPANION(&client->dev));
/* 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();
}
return 0; return 0;
} }
......
...@@ -21,8 +21,9 @@ ...@@ -21,8 +21,9 @@
#define VERSION "0.1" #define VERSION "0.1"
#define SONY_VENDOR_ID 0x054c #define SONY_VENDOR_ID 0x054c
#define RCS380_PRODUCT_ID 0x06c1 #define RCS380S_PRODUCT_ID 0x06c1
#define RCS380P_PRODUCT_ID 0x06c3
#define PORT100_PROTOCOLS (NFC_PROTO_JEWEL_MASK | \ #define PORT100_PROTOCOLS (NFC_PROTO_JEWEL_MASK | \
NFC_PROTO_MIFARE_MASK | \ NFC_PROTO_MIFARE_MASK | \
...@@ -725,23 +726,33 @@ static int port100_submit_urb_for_ack(struct port100 *dev, gfp_t flags) ...@@ -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) static int port100_send_ack(struct port100 *dev)
{ {
int rc; int rc = 0;
mutex_lock(&dev->out_urb_lock); 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 = ack_frame;
dev->out_urb->transfer_buffer_length = sizeof(ack_frame); dev->out_urb->transfer_buffer_length = sizeof(ack_frame);
rc = usb_submit_urb(dev->out_urb, GFP_KERNEL); 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 * Set the cmd_cancel flag only if the URB has been
* port100_send_complete(). * successfully submitted. It will be reset by the out
*/ * URB completion callback port100_send_complete().
dev->cmd_cancel = !rc; */
dev->cmd_cancel = !rc;
}
mutex_unlock(&dev->out_urb_lock); mutex_unlock(&dev->out_urb_lock);
...@@ -928,8 +939,8 @@ static void port100_send_complete(struct urb *urb) ...@@ -928,8 +939,8 @@ static void port100_send_complete(struct urb *urb)
struct port100 *dev = urb->context; struct port100 *dev = urb->context;
if (dev->cmd_cancel) { if (dev->cmd_cancel) {
complete_all(&dev->cmd_cancel_done);
dev->cmd_cancel = false; dev->cmd_cancel = false;
complete(&dev->cmd_cancel_done);
} }
switch (urb->status) { switch (urb->status) {
...@@ -1477,7 +1488,8 @@ static struct nfc_digital_ops port100_digital_ops = { ...@@ -1477,7 +1488,8 @@ static struct nfc_digital_ops port100_digital_ops = {
}; };
static const struct usb_device_id port100_table[] = { 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); MODULE_DEVICE_TABLE(usb, port100_table);
...@@ -1538,11 +1550,13 @@ static int port100_probe(struct usb_interface *interface, ...@@ -1538,11 +1550,13 @@ static int port100_probe(struct usb_interface *interface,
usb_fill_bulk_urb(dev->out_urb, dev->udev, usb_fill_bulk_urb(dev->out_urb, dev->udev,
usb_sndbulkpipe(dev->udev, out_endpoint), usb_sndbulkpipe(dev->udev, out_endpoint),
NULL, 0, port100_send_complete, dev); NULL, 0, port100_send_complete, dev);
dev->out_urb->transfer_flags = URB_ZERO_PACKET;
dev->skb_headroom = PORT100_FRAME_HEADER_LEN + dev->skb_headroom = PORT100_FRAME_HEADER_LEN +
PORT100_COMM_RF_HEAD_MAX_LEN; PORT100_COMM_RF_HEAD_MAX_LEN;
dev->skb_tailroom = PORT100_FRAME_TAIL_LEN; dev->skb_tailroom = PORT100_FRAME_TAIL_LEN;
init_completion(&dev->cmd_cancel_done);
INIT_WORK(&dev->cmd_complete_work, port100_wq_cmd_complete); 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 /* The first thing to do with the Port-100 is to set the command type
......
...@@ -959,10 +959,8 @@ int st21nfca_hci_probe(void *phy_id, struct nfc_phy_ops *phy_ops, ...@@ -959,10 +959,8 @@ int st21nfca_hci_probe(void *phy_id, struct nfc_phy_ops *phy_ops,
unsigned long quirks = 0; unsigned long quirks = 0;
info = kzalloc(sizeof(struct st21nfca_hci_info), GFP_KERNEL); info = kzalloc(sizeof(struct st21nfca_hci_info), GFP_KERNEL);
if (!info) { if (!info)
r = -ENOMEM; return -ENOMEM;
goto err_alloc_hdev;
}
info->phy_ops = phy_ops; info->phy_ops = phy_ops;
info->phy_id = phy_id; info->phy_id = phy_id;
...@@ -978,8 +976,10 @@ int st21nfca_hci_probe(void *phy_id, struct nfc_phy_ops *phy_ops, ...@@ -978,8 +976,10 @@ int st21nfca_hci_probe(void *phy_id, struct nfc_phy_ops *phy_ops,
* persistent info to discriminate 2 identical chips * persistent info to discriminate 2 identical chips
*/ */
dev_num = find_first_zero_bit(dev_mask, ST21NFCA_NUM_DEVICES); dev_num = find_first_zero_bit(dev_mask, ST21NFCA_NUM_DEVICES);
if (dev_num >= ST21NFCA_NUM_DEVICES) if (dev_num >= ST21NFCA_NUM_DEVICES) {
return -ENODEV; r = -ENODEV;
goto err_alloc_hdev;
}
set_bit(dev_num, dev_mask); set_bit(dev_num, dev_mask);
......
...@@ -20,17 +20,15 @@ ...@@ -20,17 +20,15 @@
#include <linux/crc-ccitt.h> #include <linux/crc-ccitt.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/gpio.h>
#include <linux/gpio/consumer.h> #include <linux/gpio/consumer.h>
#include <linux/of_irq.h> #include <linux/of_irq.h>
#include <linux/of_gpio.h> #include <linux/of_gpio.h>
#include <linux/acpi.h> #include <linux/acpi.h>
#include <linux/miscdevice.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/nfc.h> #include <linux/nfc.h>
#include <linux/firmware.h> #include <linux/firmware.h>
#include <linux/platform_data/st21nfca.h>
#include <asm/unaligned.h> #include <asm/unaligned.h>
#include <net/nfc/hci.h> #include <net/nfc/hci.h>
...@@ -60,6 +58,7 @@ ...@@ -60,6 +58,7 @@
#define IS_START_OF_FRAME(buf) (buf[0] == ST21NFCA_SOF_EOF && \ #define IS_START_OF_FRAME(buf) (buf[0] == ST21NFCA_SOF_EOF && \
buf[1] == 0) buf[1] == 0)
#define ST21NFCA_HCI_DRIVER_NAME "st21nfca_hci"
#define ST21NFCA_HCI_I2C_DRIVER_NAME "st21nfca_hci_i2c" #define ST21NFCA_HCI_I2C_DRIVER_NAME "st21nfca_hci_i2c"
#define ST21NFCA_GPIO_NAME_EN "enable" #define ST21NFCA_GPIO_NAME_EN "enable"
...@@ -68,9 +67,7 @@ struct st21nfca_i2c_phy { ...@@ -68,9 +67,7 @@ struct st21nfca_i2c_phy {
struct i2c_client *i2c_dev; struct i2c_client *i2c_dev;
struct nfc_hci_dev *hdev; struct nfc_hci_dev *hdev;
unsigned int gpio_ena; struct gpio_desc *gpiod_ena;
unsigned int irq_polarity;
struct st21nfca_se_status se_status; struct st21nfca_se_status se_status;
struct sk_buff *pending_skb; struct sk_buff *pending_skb;
...@@ -151,7 +148,7 @@ static int st21nfca_hci_i2c_enable(void *phy_id) ...@@ -151,7 +148,7 @@ static int st21nfca_hci_i2c_enable(void *phy_id)
{ {
struct st21nfca_i2c_phy *phy = 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->powered = 1;
phy->run_mode = ST21NFCA_HCI_MODE; phy->run_mode = ST21NFCA_HCI_MODE;
...@@ -164,7 +161,7 @@ static void st21nfca_hci_i2c_disable(void *phy_id) ...@@ -164,7 +161,7 @@ static void st21nfca_hci_i2c_disable(void *phy_id)
{ {
struct st21nfca_i2c_phy *phy = 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; phy->powered = 0;
} }
...@@ -507,33 +504,14 @@ static struct nfc_phy_ops i2c_phy_ops = { ...@@ -507,33 +504,14 @@ static struct nfc_phy_ops i2c_phy_ops = {
static int st21nfca_hci_i2c_acpi_request_resources(struct i2c_client *client) static int st21nfca_hci_i2c_acpi_request_resources(struct i2c_client *client)
{ {
struct st21nfca_i2c_phy *phy = i2c_get_clientdata(client); struct st21nfca_i2c_phy *phy = i2c_get_clientdata(client);
struct gpio_desc *gpiod_ena;
struct device *dev = &client->dev; struct device *dev = &client->dev;
u8 tmp;
/* Get EN GPIO from ACPI */ /* Get EN GPIO from ACPI */
gpiod_ena = devm_gpiod_get_index(dev, ST21NFCA_GPIO_NAME_EN, 1, phy->gpiod_ena = devm_gpiod_get_index(dev, ST21NFCA_GPIO_NAME_EN, 1,
GPIOD_OUT_LOW); GPIOD_OUT_LOW);
if (!IS_ERR(gpiod_ena)) { if (IS_ERR(phy->gpiod_ena)) {
nfc_err(dev, "Unable to get ENABLE GPIO\n"); nfc_err(dev, "Unable to get ENABLE GPIO\n");
return -ENODEV; return PTR_ERR(phy->gpiod_ena);
}
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 0; return 0;
...@@ -542,70 +520,16 @@ static int st21nfca_hci_i2c_acpi_request_resources(struct i2c_client *client) ...@@ -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) static int st21nfca_hci_i2c_of_request_resources(struct i2c_client *client)
{ {
struct st21nfca_i2c_phy *phy = i2c_get_clientdata(client); struct st21nfca_i2c_phy *phy = i2c_get_clientdata(client);
struct device_node *pp; struct device *dev = &client->dev;
int gpio;
int r;
pp = client->dev.of_node;
if (!pp)
return -ENODEV;
/* Get GPIO from device tree */ /* Get GPIO from device tree */
gpio = of_get_named_gpio(pp, "enable-gpios", 0); phy->gpiod_ena = devm_gpiod_get_index(dev, ST21NFCA_GPIO_NAME_EN, 0,
if (gpio < 0) { GPIOD_OUT_HIGH);
nfc_err(&client->dev, "Failed to retrieve enable-gpios from device tree\n"); if (IS_ERR(phy->gpiod_ena)) {
return gpio; nfc_err(dev, "Failed to request enable pin\n");
} return PTR_ERR(phy->gpiod_ena);
/* 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->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; return 0;
} }
...@@ -613,7 +537,6 @@ static int st21nfca_hci_i2c_probe(struct i2c_client *client, ...@@ -613,7 +537,6 @@ static int st21nfca_hci_i2c_probe(struct i2c_client *client,
const struct i2c_device_id *id) const struct i2c_device_id *id)
{ {
struct st21nfca_i2c_phy *phy; struct st21nfca_i2c_phy *phy;
struct st21nfca_nfc_platform_data *pdata;
int r; int r;
dev_dbg(&client->dev, "%s\n", __func__); dev_dbg(&client->dev, "%s\n", __func__);
...@@ -639,19 +562,12 @@ static int st21nfca_hci_i2c_probe(struct i2c_client *client, ...@@ -639,19 +562,12 @@ static int st21nfca_hci_i2c_probe(struct i2c_client *client,
mutex_init(&phy->phy_lock); mutex_init(&phy->phy_lock);
i2c_set_clientdata(client, phy); i2c_set_clientdata(client, phy);
pdata = client->dev.platform_data; if (client->dev.of_node) {
if (!pdata && client->dev.of_node) {
r = st21nfca_hci_i2c_of_request_resources(client); r = st21nfca_hci_i2c_of_request_resources(client);
if (r) { if (r) {
nfc_err(&client->dev, "No platform data\n"); nfc_err(&client->dev, "No platform data\n");
return r; 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)) { } else if (ACPI_HANDLE(&client->dev)) {
r = st21nfca_hci_i2c_acpi_request_resources(client); r = st21nfca_hci_i2c_acpi_request_resources(client);
if (r) { if (r) {
...@@ -663,6 +579,11 @@ static int st21nfca_hci_i2c_probe(struct i2c_client *client, ...@@ -663,6 +579,11 @@ static int st21nfca_hci_i2c_probe(struct i2c_client *client,
return -ENODEV; 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); r = st21nfca_hci_platform_init(phy);
if (r < 0) { if (r < 0) {
nfc_err(&client->dev, "Unable to reboot st21nfca\n"); nfc_err(&client->dev, "Unable to reboot st21nfca\n");
...@@ -671,7 +592,7 @@ static int st21nfca_hci_i2c_probe(struct i2c_client *client, ...@@ -671,7 +592,7 @@ static int st21nfca_hci_i2c_probe(struct i2c_client *client,
r = devm_request_threaded_irq(&client->dev, client->irq, NULL, r = devm_request_threaded_irq(&client->dev, client->irq, NULL,
st21nfca_hci_irq_thread_fn, st21nfca_hci_irq_thread_fn,
phy->irq_polarity | IRQF_ONESHOT, IRQF_ONESHOT,
ST21NFCA_HCI_DRIVER_NAME, phy); ST21NFCA_HCI_DRIVER_NAME, phy);
if (r < 0) { if (r < 0) {
nfc_err(&client->dev, "Unable to register IRQ handler\n"); nfc_err(&client->dev, "Unable to register IRQ handler\n");
......
...@@ -124,6 +124,9 @@ ...@@ -124,6 +124,9 @@
NFC_PROTO_ISO15693_MASK | NFC_PROTO_NFC_DEP_MASK) NFC_PROTO_ISO15693_MASK | NFC_PROTO_NFC_DEP_MASK)
#define TRF7970A_AUTOSUSPEND_DELAY 30000 /* 30 seconds */ #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 #define TRF7970A_RX_SKB_ALLOC_SIZE 256
...@@ -441,6 +444,7 @@ struct trf7970a { ...@@ -441,6 +444,7 @@ struct trf7970a {
u8 iso_ctrl_tech; u8 iso_ctrl_tech;
u8 modulator_sys_clk_ctrl; u8 modulator_sys_clk_ctrl;
u8 special_fcn_reg1; u8 special_fcn_reg1;
u8 io_ctrl;
unsigned int guard_time; unsigned int guard_time;
int technology; int technology;
int framing; int framing;
...@@ -1048,6 +1052,11 @@ static int trf7970a_init(struct trf7970a *trf) ...@@ -1048,6 +1052,11 @@ static int trf7970a_init(struct trf7970a *trf)
if (ret) if (ret)
goto err_out; 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); ret = trf7970a_write(trf, TRF7970A_NFC_TARGET_LEVEL, 0);
if (ret) if (ret)
goto err_out; goto err_out;
...@@ -1056,12 +1065,11 @@ static int trf7970a_init(struct trf7970a *trf) ...@@ -1056,12 +1065,11 @@ static int trf7970a_init(struct trf7970a *trf)
trf->chip_status_ctrl &= ~TRF7970A_CHIP_STATUS_RF_ON; 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) if (ret)
goto err_out; goto err_out;
trf->modulator_sys_clk_ctrl = 0;
ret = trf7970a_write(trf, TRF7970A_ADJUTABLE_FIFO_IRQ_LEVELS, ret = trf7970a_write(trf, TRF7970A_ADJUTABLE_FIFO_IRQ_LEVELS,
TRF7970A_ADJUTABLE_FIFO_IRQ_LEVELS_WLH_96 | TRF7970A_ADJUTABLE_FIFO_IRQ_LEVELS_WLH_96 |
TRF7970A_ADJUTABLE_FIFO_IRQ_LEVELS_WLL_32); TRF7970A_ADJUTABLE_FIFO_IRQ_LEVELS_WLL_32);
...@@ -1181,27 +1189,37 @@ static int trf7970a_in_config_rf_tech(struct trf7970a *trf, int tech) ...@@ -1181,27 +1189,37 @@ static int trf7970a_in_config_rf_tech(struct trf7970a *trf, int tech)
switch (tech) { switch (tech) {
case NFC_DIGITAL_RF_TECH_106A: case NFC_DIGITAL_RF_TECH_106A:
trf->iso_ctrl_tech = TRF7970A_ISO_CTRL_14443A_106; 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; trf->guard_time = TRF7970A_GUARD_TIME_NFCA;
break; break;
case NFC_DIGITAL_RF_TECH_106B: case NFC_DIGITAL_RF_TECH_106B:
trf->iso_ctrl_tech = TRF7970A_ISO_CTRL_14443B_106; 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; trf->guard_time = TRF7970A_GUARD_TIME_NFCB;
break; break;
case NFC_DIGITAL_RF_TECH_212F: case NFC_DIGITAL_RF_TECH_212F:
trf->iso_ctrl_tech = TRF7970A_ISO_CTRL_FELICA_212; 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; trf->guard_time = TRF7970A_GUARD_TIME_NFCF;
break; break;
case NFC_DIGITAL_RF_TECH_424F: case NFC_DIGITAL_RF_TECH_424F:
trf->iso_ctrl_tech = TRF7970A_ISO_CTRL_FELICA_424; 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; trf->guard_time = TRF7970A_GUARD_TIME_NFCF;
break; break;
case NFC_DIGITAL_RF_TECH_ISO15693: case NFC_DIGITAL_RF_TECH_ISO15693:
trf->iso_ctrl_tech = TRF7970A_ISO_CTRL_15693_SGL_1OF4_2648; 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; trf->guard_time = TRF7970A_GUARD_TIME_15693;
break; break;
default: default:
...@@ -1571,17 +1589,23 @@ static int trf7970a_tg_config_rf_tech(struct trf7970a *trf, int tech) ...@@ -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 | trf->iso_ctrl_tech = TRF7970A_ISO_CTRL_NFC_NFC_CE_MODE |
TRF7970A_ISO_CTRL_NFC_CE | TRF7970A_ISO_CTRL_NFC_CE |
TRF7970A_ISO_CTRL_NFC_CE_14443A; 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; break;
case NFC_DIGITAL_RF_TECH_212F: case NFC_DIGITAL_RF_TECH_212F:
trf->iso_ctrl_tech = TRF7970A_ISO_CTRL_NFC_NFC_CE_MODE | trf->iso_ctrl_tech = TRF7970A_ISO_CTRL_NFC_NFC_CE_MODE |
TRF7970A_ISO_CTRL_NFC_NFCF_212; 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; break;
case NFC_DIGITAL_RF_TECH_424F: case NFC_DIGITAL_RF_TECH_424F:
trf->iso_ctrl_tech = TRF7970A_ISO_CTRL_NFC_NFC_CE_MODE | trf->iso_ctrl_tech = TRF7970A_ISO_CTRL_NFC_NFC_CE_MODE |
TRF7970A_ISO_CTRL_NFC_NFCF_424; 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; break;
default: default:
dev_dbg(trf->dev, "Unsupported rf technology: %d\n", tech); 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, ...@@ -1749,7 +1773,7 @@ static int _trf7970a_tg_listen(struct nfc_digital_dev *ddev, u16 timeout,
goto out_err; goto out_err;
ret = trf7970a_write(trf, TRF7970A_REG_IO_CTRL, 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) if (ret)
goto out_err; goto out_err;
...@@ -1885,8 +1909,10 @@ static int trf7970a_power_up(struct trf7970a *trf) ...@@ -1885,8 +1909,10 @@ static int trf7970a_power_up(struct trf7970a *trf)
usleep_range(5000, 6000); usleep_range(5000, 6000);
if (!(trf->quirks & TRF7970A_QUIRK_EN2_MUST_STAY_LOW)) { if (!(trf->quirks & TRF7970A_QUIRK_EN2_MUST_STAY_LOW)) {
gpio_set_value(trf->en2_gpio, 1); if (gpio_is_valid(trf->en2_gpio)) {
usleep_range(1000, 2000); gpio_set_value(trf->en2_gpio, 1);
usleep_range(1000, 2000);
}
} }
gpio_set_value(trf->en_gpio, 1); gpio_set_value(trf->en_gpio, 1);
...@@ -1914,7 +1940,8 @@ static int trf7970a_power_down(struct trf7970a *trf) ...@@ -1914,7 +1940,8 @@ static int trf7970a_power_down(struct trf7970a *trf)
} }
gpio_set_value(trf->en_gpio, 0); 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); ret = regulator_disable(trf->regulator);
if (ret) if (ret)
...@@ -1987,6 +2014,7 @@ static int trf7970a_probe(struct spi_device *spi) ...@@ -1987,6 +2014,7 @@ static int trf7970a_probe(struct spi_device *spi)
struct device_node *np = spi->dev.of_node; struct device_node *np = spi->dev.of_node;
struct trf7970a *trf; struct trf7970a *trf;
int uvolts, autosuspend_delay, ret; int uvolts, autosuspend_delay, ret;
u32 clk_freq = TRF7970A_13MHZ_CLOCK_FREQUENCY;
if (!np) { if (!np) {
dev_err(&spi->dev, "No Device Tree entry\n"); dev_err(&spi->dev, "No Device Tree entry\n");
...@@ -2032,15 +2060,23 @@ static int trf7970a_probe(struct spi_device *spi) ...@@ -2032,15 +2060,23 @@ static int trf7970a_probe(struct spi_device *spi)
trf->en2_gpio = of_get_named_gpio(np, "ti,enable-gpios", 1); trf->en2_gpio = of_get_named_gpio(np, "ti,enable-gpios", 1);
if (!gpio_is_valid(trf->en2_gpio)) { if (!gpio_is_valid(trf->en2_gpio)) {
dev_err(trf->dev, "No EN2 GPIO property\n"); dev_info(trf->dev, "No EN2 GPIO property\n");
return trf->en2_gpio; } 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, of_property_read_u32(np, "clock-frequency", &clk_freq);
GPIOF_DIR_OUT | GPIOF_INIT_LOW, "trf7970a EN2"); if ((clk_freq != TRF7970A_27MHZ_CLOCK_FREQUENCY) ||
if (ret) { (clk_freq != TRF7970A_13MHZ_CLOCK_FREQUENCY)) {
dev_err(trf->dev, "Can't request EN2 GPIO: %d\n", ret); dev_err(trf->dev,
return ret; "clock-frequency (%u Hz) unsupported\n",
clk_freq);
return -EINVAL;
} }
if (of_property_read_bool(np, "en2-rf-quirk")) if (of_property_read_bool(np, "en2-rf-quirk"))
...@@ -2077,6 +2113,24 @@ static int trf7970a_probe(struct spi_device *spi) ...@@ -2077,6 +2113,24 @@ static int trf7970a_probe(struct spi_device *spi)
if (uvolts > 4000000) if (uvolts > 4000000)
trf->chip_status_ctrl = TRF7970A_CHIP_STATUS_VRS5_3; 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, trf->ddev = nfc_digital_allocate_device(&trf7970a_nfc_ops,
TRF7970A_SUPPORTED_PROTOCOLS, TRF7970A_SUPPORTED_PROTOCOLS,
NFC_DIGITAL_DRV_CAPS_IN_CRC | NFC_DIGITAL_DRV_CAPS_IN_CRC |
......
/*
* 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_ */
/*
* 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_ */
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include <linux/device.h> #include <linux/device.h>
#include <linux/skbuff.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_info(dev, fmt, ...) dev_info((dev), "NFC: " fmt, ##__VA_ARGS__)
#define nfc_err(dev, fmt, ...) dev_err((dev), "NFC: " fmt, ##__VA_ARGS__) #define nfc_err(dev, fmt, ...) dev_err((dev), "NFC: " fmt, ##__VA_ARGS__)
......
...@@ -304,6 +304,17 @@ int nfc_genl_tm_deactivated(struct nfc_dev *dev) ...@@ -304,6 +304,17 @@ int nfc_genl_tm_deactivated(struct nfc_dev *dev)
return -EMSGSIZE; 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) int nfc_genl_device_added(struct nfc_dev *dev)
{ {
struct sk_buff *msg; struct sk_buff *msg;
...@@ -318,10 +329,7 @@ int nfc_genl_device_added(struct nfc_dev *dev) ...@@ -318,10 +329,7 @@ int nfc_genl_device_added(struct nfc_dev *dev)
if (!hdr) if (!hdr)
goto free_msg; goto free_msg;
if (nla_put_string(msg, NFC_ATTR_DEVICE_NAME, nfc_device_name(dev)) || if (nfc_genl_setup_device_added(dev, msg))
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))
goto nla_put_failure; goto nla_put_failure;
genlmsg_end(msg, hdr); genlmsg_end(msg, hdr);
...@@ -597,11 +605,7 @@ static int nfc_genl_send_device(struct sk_buff *msg, struct nfc_dev *dev, ...@@ -597,11 +605,7 @@ static int nfc_genl_send_device(struct sk_buff *msg, struct nfc_dev *dev,
if (cb) if (cb)
genl_dump_check_consistent(cb, hdr, &nfc_genl_family); genl_dump_check_consistent(cb, hdr, &nfc_genl_family);
if (nla_put_string(msg, NFC_ATTR_DEVICE_NAME, nfc_device_name(dev)) || if (nfc_genl_setup_device_added(dev, msg))
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))
goto nla_put_failure; goto nla_put_failure;
genlmsg_end(msg, hdr); genlmsg_end(msg, hdr);
...@@ -919,7 +923,7 @@ static int nfc_genl_activate_target(struct sk_buff *skb, struct genl_info *info) ...@@ -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); rc = nfc_activate_target(dev, target_idx, protocol);
nfc_put_device(dev); nfc_put_device(dev);
return 0; return rc;
} }
static int nfc_genl_dep_link_up(struct sk_buff *skb, struct genl_info *info) static int nfc_genl_dep_link_up(struct sk_buff *skb, struct genl_info *info)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment