mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-08-18 02:22:47 -07:00
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>
This commit is contained in:
commit
69e3948aaa
23 files changed
+291
-1065
No files matched your search
@@ -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";
|
||||
};
|
||||
};
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -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"
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
+21
-13
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
+52
-30
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
+43
-178
@@ -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;
|
||||
static const struct acpi_gpio_params enable_gpios = { 1, 0, false };
|
||||
static const struct acpi_gpio_params firmware_gpios = { 2, 0, false };
|
||||
|
||||
/* 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:
|
||||
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;
|
||||
r = acpi_dev_add_driver_gpios(ACPI_COMPANION(dev), acpi_pn544_gpios);
|
||||
if (r)
|
||||
dev_dbg(dev, "Unable to add GPIO mapping table\n");
|
||||
|
||||
/* 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) {
|
||||
/* 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);
|
||||
}
|
||||
|
||||
if (pdata->request_resources == NULL) {
|
||||
nfc_err(&client->dev, "request_resources() missing\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
r = pdata->request_resources(client);
|
||||
if (r) {
|
||||
nfc_err(&client->dev,
|
||||
"Cannot get platform resources\n");
|
||||
return r;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
+31
-17
@@ -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);
|
||||
|
||||
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);
|
||||
|
||||
/* 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().
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
dev->cmd_cancel = !rc;
|
||||
if (!dev->cmd_cancel) {
|
||||
reinit_completion(&dev->cmd_cancel_done);
|
||||
|
||||
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);
|
||||
|
||||
/*
|
||||
* 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
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
+22
-101
@@ -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;
|
||||
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);
|
||||
}
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
|
||||
+76
-22
@@ -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 |
|
||||
|
||||
@@ -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_ */
|
||||
Loaded 20 of 23 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user