All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/9] Marvell NFC drivers for i2c and spi
@ 2015-09-28 12:33 Vincent Cuissard
       [not found] ` <1443443594-14353-1-git-send-email-cuissard-eYqpPyKDWXRBDgjK7y7TUQ@public.gmane.org>
  0 siblings, 1 reply; 26+ messages in thread
From: Vincent Cuissard @ 2015-09-28 12:33 UTC (permalink / raw)
  To: linux-nfc-hn68Rpc1hR1g9hUCZPvPmw
  Cc: devicetree-u79uwXL29TY76Z2rM5mHXA, Vincent Cuissard

Hi,

Please find patches that enable Marvell NFC controlled over i2c
and spi. This patchset includes also firmware download support and
few enhancements.

V2 update: Add module license in spi driver, update makefile

Br,

Vincent Cuissard (9):
  NFC: nfcmrvl: remove unneeded version defines
  NFC: NCI: export nci_send_frame function
  NFC: nfcmrvl: add firmware download support
  NFC: nfcmrvl: allow low level drivers to configure head/tail room
  NFC: nfcmrvl: add i2c driver
  NFC: NCI: move generic spi driver to a module
  NFC: NCI: allow spi driver to choose transfer clock
  NFC: nfcmrvl: add spi driver
  NFC: nfcmrvl: update device tree bindings for Marvell NFC

 .../devicetree/bindings/net/nfc/nfcmrvl.txt        |  61 ++-
 drivers/nfc/nfcmrvl/Kconfig                        |  22 +
 drivers/nfc/nfcmrvl/Makefile                       |   8 +-
 drivers/nfc/nfcmrvl/fw_dnld.c                      | 561 +++++++++++++++++++++
 drivers/nfc/nfcmrvl/fw_dnld.h                      | 105 ++++
 drivers/nfc/nfcmrvl/i2c.c                          | 302 +++++++++++
 drivers/nfc/nfcmrvl/main.c                         |  64 ++-
 drivers/nfc/nfcmrvl/nfcmrvl.h                      |  22 +-
 drivers/nfc/nfcmrvl/spi.c                          | 242 +++++++++
 drivers/nfc/nfcmrvl/uart.c                         |  16 +-
 drivers/nfc/nfcmrvl/usb.c                          |   7 +-
 include/linux/platform_data/nfcmrvl.h              |  11 +
 include/net/nfc/nci.h                              |   1 +
 include/net/nfc/nci_core.h                         |   5 +
 net/nfc/nci/Kconfig                                |   2 +-
 net/nfc/nci/Makefile                               |   3 +-
 net/nfc/nci/core.c                                 |   3 +-
 net/nfc/nci/spi.c                                  |  11 +-
 18 files changed, 1408 insertions(+), 38 deletions(-)
 create mode 100644 drivers/nfc/nfcmrvl/fw_dnld.c
 create mode 100644 drivers/nfc/nfcmrvl/fw_dnld.h
 create mode 100644 drivers/nfc/nfcmrvl/i2c.c
 create mode 100644 drivers/nfc/nfcmrvl/spi.c

--
2.2.0.33.gc18b867
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH v2 1/9] NFC: nfcmrvl: remove unneeded version defines
       [not found] ` <1443443594-14353-1-git-send-email-cuissard-eYqpPyKDWXRBDgjK7y7TUQ@public.gmane.org>
@ 2015-09-28 12:33   ` Vincent Cuissard
  2015-09-28 12:33   ` [PATCH v2 2/9] NFC: NCI: export nci_send_frame function Vincent Cuissard
                     ` (7 subsequent siblings)
  8 siblings, 0 replies; 26+ messages in thread
From: Vincent Cuissard @ 2015-09-28 12:33 UTC (permalink / raw)
  To: linux-nfc-hn68Rpc1hR1g9hUCZPvPmw
  Cc: devicetree-u79uwXL29TY76Z2rM5mHXA, Vincent Cuissard

Signed-off-by: Vincent Cuissard <cuissard-eYqpPyKDWXRBDgjK7y7TUQ@public.gmane.org>
---
 drivers/nfc/nfcmrvl/main.c | 7 ++-----
 drivers/nfc/nfcmrvl/usb.c  | 5 +----
 2 files changed, 3 insertions(+), 9 deletions(-)

diff --git a/drivers/nfc/nfcmrvl/main.c b/drivers/nfc/nfcmrvl/main.c
index 4a8866d..77e292f 100644
--- a/drivers/nfc/nfcmrvl/main.c
+++ b/drivers/nfc/nfcmrvl/main.c
@@ -1,7 +1,7 @@
 /*
  * Marvell NFC driver: major functions
  *
- * Copyright (C) 2014, Marvell International Ltd.
+ * Copyright (C) 2014-2015 Marvell International Ltd.
  *
  * This software file (the "File") is distributed by Marvell International
  * Ltd. under the terms of the GNU General Public License Version 2, June 1991
@@ -25,8 +25,6 @@
 #include <net/nfc/nci_core.h>
 #include "nfcmrvl.h"
 
-#define VERSION "1.0"
-
 static int nfcmrvl_nci_open(struct nci_dev *ndev)
 {
 	struct nfcmrvl_private *priv = nci_get_drvdata(ndev);
@@ -252,6 +250,5 @@ int nfcmrvl_parse_dt(struct device_node *node,
 EXPORT_SYMBOL_GPL(nfcmrvl_parse_dt);
 
 MODULE_AUTHOR("Marvell International Ltd.");
-MODULE_DESCRIPTION("Marvell NFC driver ver " VERSION);
-MODULE_VERSION(VERSION);
+MODULE_DESCRIPTION("Marvell NFC driver");
 MODULE_LICENSE("GPL v2");
diff --git a/drivers/nfc/nfcmrvl/usb.c b/drivers/nfc/nfcmrvl/usb.c
index 7d1fe43..5e624d1 100644
--- a/drivers/nfc/nfcmrvl/usb.c
+++ b/drivers/nfc/nfcmrvl/usb.c
@@ -23,8 +23,6 @@
 #include <net/nfc/nci_core.h>
 #include "nfcmrvl.h"
 
-#define VERSION "1.0"
-
 static struct usb_device_id nfcmrvl_table[] = {
 	{ USB_DEVICE_AND_INTERFACE_INFO(0x1286, 0x2046,
 					USB_CLASS_VENDOR_SPEC, 4, 1) },
@@ -469,6 +467,5 @@ static struct usb_driver nfcmrvl_usb_driver = {
 module_usb_driver(nfcmrvl_usb_driver);
 
 MODULE_AUTHOR("Marvell International Ltd.");
-MODULE_DESCRIPTION("Marvell NFC-over-USB driver ver " VERSION);
-MODULE_VERSION(VERSION);
+MODULE_DESCRIPTION("Marvell NFC-over-USB driver");
 MODULE_LICENSE("GPL v2");
-- 
2.2.0.33.gc18b867

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH v2 2/9] NFC: NCI: export nci_send_frame function
       [not found] ` <1443443594-14353-1-git-send-email-cuissard-eYqpPyKDWXRBDgjK7y7TUQ@public.gmane.org>
  2015-09-28 12:33   ` [PATCH v2 1/9] NFC: nfcmrvl: remove unneeded version defines Vincent Cuissard
@ 2015-09-28 12:33   ` Vincent Cuissard
       [not found]     ` <1443443594-14353-3-git-send-email-cuissard-eYqpPyKDWXRBDgjK7y7TUQ@public.gmane.org>
  2015-09-28 12:33   ` [PATCH v2 3/9] NFC: nfcmrvl: add firmware download support Vincent Cuissard
                     ` (6 subsequent siblings)
  8 siblings, 1 reply; 26+ messages in thread
From: Vincent Cuissard @ 2015-09-28 12:33 UTC (permalink / raw)
  To: linux-nfc-hn68Rpc1hR1g9hUCZPvPmw
  Cc: devicetree-u79uwXL29TY76Z2rM5mHXA, Vincent Cuissard

Export nci_send_frame symbol to allow drivers to use it.
This is needed for example if NCI is used during firmware
download phase.

Signed-off-by: Vincent Cuissard <cuissard-eYqpPyKDWXRBDgjK7y7TUQ@public.gmane.org>
---
 include/net/nfc/nci_core.h | 1 +
 net/nfc/nci/core.c         | 3 ++-
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/include/net/nfc/nci_core.h b/include/net/nfc/nci_core.h
index d0d0f1e..f0bb5e7 100644
--- a/include/net/nfc/nci_core.h
+++ b/include/net/nfc/nci_core.h
@@ -282,6 +282,7 @@ int nci_core_reset(struct nci_dev *ndev);
 int nci_core_init(struct nci_dev *ndev);
 
 int nci_recv_frame(struct nci_dev *ndev, struct sk_buff *skb);
+int nci_send_frame(struct nci_dev *ndev, struct sk_buff *skb);
 int nci_set_config(struct nci_dev *ndev, __u8 id, size_t len, __u8 *val);
 
 int nci_nfcee_discover(struct nci_dev *ndev, u8 action);
diff --git a/net/nfc/nci/core.c b/net/nfc/nci/core.c
index 943889b..5feed7e 100644
--- a/net/nfc/nci/core.c
+++ b/net/nfc/nci/core.c
@@ -1177,7 +1177,7 @@ int nci_recv_frame(struct nci_dev *ndev, struct sk_buff *skb)
 }
 EXPORT_SYMBOL(nci_recv_frame);
 
-static int nci_send_frame(struct nci_dev *ndev, struct sk_buff *skb)
+int nci_send_frame(struct nci_dev *ndev, struct sk_buff *skb)
 {
 	pr_debug("len %d\n", skb->len);
 
@@ -1195,6 +1195,7 @@ static int nci_send_frame(struct nci_dev *ndev, struct sk_buff *skb)
 
 	return ndev->ops->send(ndev, skb);
 }
+EXPORT_SYMBOL(nci_send_frame);
 
 /* Send NCI command */
 int nci_send_cmd(struct nci_dev *ndev, __u16 opcode, __u8 plen, void *payload)
-- 
2.2.0.33.gc18b867

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH v2 3/9] NFC: nfcmrvl: add firmware download support
       [not found] ` <1443443594-14353-1-git-send-email-cuissard-eYqpPyKDWXRBDgjK7y7TUQ@public.gmane.org>
  2015-09-28 12:33   ` [PATCH v2 1/9] NFC: nfcmrvl: remove unneeded version defines Vincent Cuissard
  2015-09-28 12:33   ` [PATCH v2 2/9] NFC: NCI: export nci_send_frame function Vincent Cuissard
@ 2015-09-28 12:33   ` Vincent Cuissard
       [not found]     ` <1443443594-14353-4-git-send-email-cuissard-eYqpPyKDWXRBDgjK7y7TUQ@public.gmane.org>
  2015-09-28 12:33   ` [PATCH v2 4/9] NFC: nfcmrvl: allow low level drivers to configure head/tail room Vincent Cuissard
                     ` (5 subsequent siblings)
  8 siblings, 1 reply; 26+ messages in thread
From: Vincent Cuissard @ 2015-09-28 12:33 UTC (permalink / raw)
  To: linux-nfc-hn68Rpc1hR1g9hUCZPvPmw
  Cc: devicetree-u79uwXL29TY76Z2rM5mHXA, Vincent Cuissard

Implement firmware download protocol for Marvell NFC controllers.
This protocol is based on NCI frames that's why parts of its implementation
use some NCI generic functions.

Signed-off-by: Vincent Cuissard <cuissard-eYqpPyKDWXRBDgjK7y7TUQ@public.gmane.org>
---
 drivers/nfc/nfcmrvl/Makefile  |   2 +-
 drivers/nfc/nfcmrvl/fw_dnld.c | 561 ++++++++++++++++++++++++++++++++++++++++++
 drivers/nfc/nfcmrvl/fw_dnld.h | 105 ++++++++
 drivers/nfc/nfcmrvl/main.c    |  42 +++-
 drivers/nfc/nfcmrvl/nfcmrvl.h |  21 +-
 drivers/nfc/nfcmrvl/uart.c    |  12 +
 drivers/nfc/nfcmrvl/usb.c     |   2 +
 7 files changed, 730 insertions(+), 15 deletions(-)
 create mode 100644 drivers/nfc/nfcmrvl/fw_dnld.c
 create mode 100644 drivers/nfc/nfcmrvl/fw_dnld.h

diff --git a/drivers/nfc/nfcmrvl/Makefile b/drivers/nfc/nfcmrvl/Makefile
index 7751962..4554ee8 100644
--- a/drivers/nfc/nfcmrvl/Makefile
+++ b/drivers/nfc/nfcmrvl/Makefile
@@ -2,7 +2,7 @@
 # Makefile for NFCMRVL NCI based NFC driver
 #
 
-nfcmrvl-y += main.o
+nfcmrvl-y += main.o fw_dnld.o
 obj-$(CONFIG_NFC_MRVL) += nfcmrvl.o
 
 nfcmrvl_usb-y += usb.o
diff --git a/drivers/nfc/nfcmrvl/fw_dnld.c b/drivers/nfc/nfcmrvl/fw_dnld.c
new file mode 100644
index 0000000..ac42cbe
--- /dev/null
+++ b/drivers/nfc/nfcmrvl/fw_dnld.c
@@ -0,0 +1,561 @@
+/*
+ * Marvell NFC driver: Firmware downloader
+ *
+ * Copyright (C) 2015, Marvell International Ltd.
+ *
+ * This software file (the "File") is distributed by Marvell International
+ * Ltd. under the terms of the GNU General Public License Version 2, June 1991
+ * (the "License").  You may use, redistribute and/or modify this File in
+ * accordance with the terms and conditions of the License, a copy of which
+ * is available on the worldwide web at
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+ *
+ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
+ * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about
+ * this warranty disclaimer.
+ */
+
+#include <linux/module.h>
+#include <linux/unaligned/access_ok.h>
+#include <linux/firmware.h>
+#include <linux/nfc.h>
+#include <net/nfc/nci.h>
+#include <net/nfc/nci_core.h>
+#include "nfcmrvl.h"
+
+#define FW_DNLD_TIMEOUT			15000
+
+#define NCI_OP_CORE_CONN_CREATE_CMD	nci_opcode_pack(NCI_GID_CORE, 0x04)
+#define NCI_OP_CORE_CONN_CLOSE_CMD	nci_opcode_pack(NCI_GID_CORE, 0x05)
+#define NCI_OP_PROPRIETARY_BOOT_CMD	nci_opcode_pack(NCI_GID_PROPRIETARY, \
+							NCI_OP_BOOT_CMD)
+
+/* FW download states */
+
+enum {
+	STATE_RESET = 0,
+	STATE_INIT,
+	STATE_SET_REF_CLOCK,
+	STATE_SET_HI_CONFIG,
+	STATE_OPEN_LC,
+	STATE_FW_DNLD,
+	STATE_CLOSE_LC,
+	STATE_BOOT
+};
+
+enum {
+	SUBSTATE_WAIT_COMMAND = 0,
+	SUBSTATE_WAIT_ACK_CREDIT,
+	SUBSTATE_WAIT_NACK_CREDIT,
+	SUBSTATE_WAIT_DATA_CREDIT,
+};
+
+/*
+** Patterns for responses
+*/
+
+static const uint8_t nci_pattern_core_reset_ntf[] = {
+	0x60, 0x00, 0x02, 0xA0, 0x01
+};
+
+static const uint8_t nci_pattern_core_init_rsp[] = {
+	0x40, 0x01, 0x11
+};
+
+static const uint8_t nci_pattern_core_set_config_rsp[] = {
+	0x40, 0x02, 0x02, 0x00, 0x00
+};
+
+static const uint8_t nci_pattern_core_conn_create_rsp[] = {
+	0x40, 0x04, 0x04, 0x00
+};
+
+static const uint8_t nci_pattern_core_conn_close_rsp[] = {
+	0x40, 0x05, 0x01, 0x00
+};
+
+static const uint8_t nci_pattern_core_conn_credits_ntf[] = {
+	0x60, 0x06, 0x03, 0x01, NCI_CORE_LC_CONNID_PROP_FW_DL, 0x01
+};
+
+static const uint8_t nci_pattern_proprietary_boot_rsp[] = {
+	0x4F, 0x3A, 0x01, 0x00
+};
+
+static int send_cmd(struct nci_dev *ndev, __u16 opcode, __u8 plen,
+		    void *payload)
+{
+	struct nci_ctrl_hdr *hdr;
+	struct sk_buff *skb;
+
+	skb = nci_skb_alloc(ndev, (NCI_CTRL_HDR_SIZE + plen), GFP_KERNEL);
+	if (!skb) {
+		pr_err("no memory for command\n");
+		return -ENOMEM;
+	}
+
+	hdr = (struct nci_ctrl_hdr *) skb_put(skb, NCI_CTRL_HDR_SIZE);
+	hdr->gid = nci_opcode_gid(opcode);
+	hdr->oid = nci_opcode_oid(opcode);
+	hdr->plen = plen;
+
+	nci_mt_set((__u8 *)hdr, NCI_MT_CMD_PKT);
+	nci_pbf_set((__u8 *)hdr, NCI_PBF_LAST);
+
+	if (plen)
+		memcpy(skb_put(skb, plen), payload, plen);
+
+	return nci_send_frame(ndev, skb);
+}
+
+static struct sk_buff *alloc_lc_skb(struct nfcmrvl_private *priv, uint8_t plen)
+{
+	struct sk_buff *skb;
+	struct nci_data_hdr *hdr;
+
+	skb = nci_skb_alloc(priv->ndev, (NCI_DATA_HDR_SIZE + plen), GFP_KERNEL);
+	if (!skb) {
+		pr_err("no memory for data\n");
+		return NULL;
+	}
+
+	hdr = (struct nci_data_hdr *) skb_put(skb, NCI_DATA_HDR_SIZE);
+	hdr->conn_id = NCI_CORE_LC_CONNID_PROP_FW_DL;
+	hdr->rfu = 0;
+	hdr->plen = plen;
+
+	nci_mt_set((__u8 *)hdr, NCI_MT_DATA_PKT);
+	nci_pbf_set((__u8 *)hdr, NCI_PBF_LAST);
+
+	return skb;
+}
+
+static void fw_dnld_over(struct nfcmrvl_private *priv, u32 error)
+{
+	if (priv->fw_dnld.fw) {
+		release_firmware(priv->fw_dnld.fw);
+		priv->fw_dnld.fw = NULL;
+		priv->fw_dnld.header = NULL;
+		priv->fw_dnld.binary_config = NULL;
+	}
+
+	del_timer_sync(&priv->fw_dnld.timer);
+
+	nfc_info(priv->dev, "FW loading over (%d)]\n", error);
+
+	if (error != 0) {
+		/* failed, halt the chip to avoid power consumption */
+		nfcmrvl_chip_halt(priv);
+	}
+
+	nfc_fw_download_done(priv->ndev->nfc_dev, priv->fw_dnld.name, error);
+}
+
+static void fw_dnld_timeout(unsigned long arg)
+{
+	struct nfcmrvl_private *priv = (struct nfcmrvl_private *) arg;
+
+	nfc_err(priv->dev, "FW loading timeout");
+	priv->fw_dnld.state = STATE_RESET;
+	fw_dnld_over(priv, -ETIMEDOUT);
+}
+
+static int process_state_reset(struct nfcmrvl_private *priv,
+			       struct sk_buff *skb)
+{
+	if (sizeof(nci_pattern_core_reset_ntf) != skb->len ||
+	    memcmp(skb->data, nci_pattern_core_reset_ntf,
+		   sizeof(nci_pattern_core_reset_ntf)))
+		return -EINVAL;
+
+	nfc_info(priv->dev, "BootROM reset, start fw download\n");
+
+	/* Start FW download state machine */
+	priv->fw_dnld.state = STATE_INIT;
+	send_cmd(priv->ndev, NCI_OP_CORE_INIT_CMD, 0, NULL);
+
+	return 0;
+}
+
+static int process_state_init(struct nfcmrvl_private *priv, struct sk_buff *skb)
+{
+	struct nci_core_set_config_cmd cmd;
+
+	if (sizeof(nci_pattern_core_init_rsp) >= skb->len ||
+	    memcmp(skb->data, nci_pattern_core_init_rsp,
+		   sizeof(nci_pattern_core_init_rsp)))
+		return -EINVAL;
+
+	cmd.num_params = 1;
+	cmd.param.id = NFCMRVL_PROP_REF_CLOCK;
+	cmd.param.len = 4;
+	memcpy(cmd.param.val, &priv->fw_dnld.header->ref_clock, 4);
+
+	send_cmd(priv->ndev, NCI_OP_CORE_SET_CONFIG_CMD, 3 + cmd.param.len,
+		 &cmd);
+
+	priv->fw_dnld.state = STATE_SET_REF_CLOCK;
+	return 0;
+}
+
+static void create_lc(struct nfcmrvl_private *priv)
+{
+	uint8_t param[2] = { NCI_CORE_LC_PROP_FW_DL, 0x0 };
+
+	priv->fw_dnld.state = STATE_OPEN_LC;
+	send_cmd(priv->ndev, NCI_OP_CORE_CONN_CREATE_CMD, 2, param);
+}
+
+static int process_state_set_ref_clock(struct nfcmrvl_private *priv,
+				       struct sk_buff *skb)
+{
+	struct nci_core_set_config_cmd cmd;
+
+	if (sizeof(nci_pattern_core_set_config_rsp) != skb->len ||
+	    memcmp(skb->data, nci_pattern_core_set_config_rsp, skb->len))
+		return -EINVAL;
+
+	cmd.num_params = 1;
+	cmd.param.id = NFCMRVL_PROP_SET_HI_CONFIG;
+
+	switch (priv->phy) {
+	case NFCMRVL_PHY_UART:
+		cmd.param.len = 5;
+		memcpy(cmd.param.val,
+		       &priv->fw_dnld.binary_config->uart.baudrate,
+		       4);
+		cmd.param.val[4] =
+			priv->fw_dnld.binary_config->uart.flow_control;
+		break;
+	case NFCMRVL_PHY_I2C:
+		cmd.param.len = 5;
+		memcpy(cmd.param.val,
+		       &priv->fw_dnld.binary_config->i2c.clk,
+		       4);
+		cmd.param.val[4] = 0;
+		break;
+	case NFCMRVL_PHY_SPI:
+		cmd.param.len = 5;
+		memcpy(cmd.param.val,
+		       &priv->fw_dnld.binary_config->spi.clk,
+		       4);
+		cmd.param.val[4] = 0;
+		break;
+	default:
+		create_lc(priv);
+		return 0;
+	}
+
+	priv->fw_dnld.state = STATE_SET_HI_CONFIG;
+	send_cmd(priv->ndev, NCI_OP_CORE_SET_CONFIG_CMD, 3 + cmd.param.len,
+		 &cmd);
+	return 0;
+}
+
+static int process_state_set_hi_config(struct nfcmrvl_private *priv,
+				       struct sk_buff *skb)
+{
+	if (sizeof(nci_pattern_core_set_config_rsp) != skb->len ||
+	    memcmp(skb->data, nci_pattern_core_set_config_rsp, skb->len))
+		return -EINVAL;
+
+	create_lc(priv);
+	return 0;
+}
+
+static int process_state_open_lc(struct nfcmrvl_private *priv,
+				 struct sk_buff *skb)
+{
+	if (sizeof(nci_pattern_core_conn_create_rsp) >= skb->len ||
+	    memcmp(skb->data, nci_pattern_core_conn_create_rsp,
+		   sizeof(nci_pattern_core_conn_create_rsp)))
+		return -EINVAL;
+
+	priv->fw_dnld.state = STATE_FW_DNLD;
+	priv->fw_dnld.substate = SUBSTATE_WAIT_COMMAND;
+	priv->fw_dnld.offset = priv->fw_dnld.binary_config->offset;
+	return 0;
+}
+
+static int process_state_fw_dnld(struct nfcmrvl_private *priv,
+				 struct sk_buff *skb)
+{
+	uint16_t len;
+	uint16_t comp_len;
+	struct sk_buff *out_skb;
+
+	switch (priv->fw_dnld.substate) {
+	case SUBSTATE_WAIT_COMMAND:
+		/* Remove NCI HDR */
+		skb_pull(skb, 3);
+		if (skb->data[0] != HELPER_CMD_PACKET_FORMAT || skb->len != 5) {
+			nfc_err(priv->dev, "bad command");
+			return -EINVAL;
+		}
+		skb_pull(skb, 1);
+		memcpy(&len, skb->data, 2);
+		skb_pull(skb, 2);
+		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));
+			out_skb = alloc_lc_skb(priv, 1);
+			if (!out_skb)
+				return -ENOMEM;
+			*skb_put(out_skb, 1) = 0xBF;
+			nci_send_frame(priv->ndev, out_skb);
+			priv->fw_dnld.substate = SUBSTATE_WAIT_NACK_CREDIT;
+			return 0;
+		}
+		priv->fw_dnld.chunk_len = len;
+		out_skb = alloc_lc_skb(priv, 1);
+		if (!out_skb)
+			return -ENOMEM;
+		*skb_put(out_skb, 1) = HELPER_ACK_PACKET_FORMAT;
+		nci_send_frame(priv->ndev, out_skb);
+		priv->fw_dnld.substate = SUBSTATE_WAIT_ACK_CREDIT;
+		break;
+
+	case SUBSTATE_WAIT_ACK_CREDIT:
+		if (sizeof(nci_pattern_core_conn_credits_ntf) != skb->len ||
+		    memcmp(nci_pattern_core_conn_credits_ntf, skb->data,
+			   skb->len)) {
+			nfc_err(priv->dev, "bad packet: waiting for credit");
+			return -EINVAL;
+		}
+		if (priv->fw_dnld.chunk_len == 0) {
+			/* FW Loading is done */
+			uint8_t conn_id = NCI_CORE_LC_CONNID_PROP_FW_DL;
+
+			priv->fw_dnld.state = STATE_CLOSE_LC;
+			send_cmd(priv->ndev, NCI_OP_CORE_CONN_CLOSE_CMD,
+				 1, &conn_id);
+		} else {
+			out_skb = alloc_lc_skb(priv, priv->fw_dnld.chunk_len);
+			if (!out_skb)
+				return -ENOMEM;
+			memcpy(skb_put(out_skb, priv->fw_dnld.chunk_len),
+			       ((uint8_t *)priv->fw_dnld.fw->data) +
+			       priv->fw_dnld.offset,
+			       priv->fw_dnld.chunk_len);
+			nci_send_frame(priv->ndev, out_skb);
+			priv->fw_dnld.substate = SUBSTATE_WAIT_DATA_CREDIT;
+		}
+		break;
+
+	case SUBSTATE_WAIT_DATA_CREDIT:
+		if (sizeof(nci_pattern_core_conn_credits_ntf) != skb->len ||
+		    memcmp(nci_pattern_core_conn_credits_ntf, skb->data,
+			    skb->len)) {
+			nfc_err(priv->dev, "bad packet: waiting for credit");
+			return -EINVAL;
+		}
+		priv->fw_dnld.offset += priv->fw_dnld.chunk_len;
+		priv->fw_dnld.chunk_len = 0;
+		priv->fw_dnld.substate = SUBSTATE_WAIT_COMMAND;
+		break;
+
+	case SUBSTATE_WAIT_NACK_CREDIT:
+		if (sizeof(nci_pattern_core_conn_credits_ntf) != skb->len ||
+		    memcmp(nci_pattern_core_conn_credits_ntf, skb->data,
+			    skb->len)) {
+			nfc_err(priv->dev, "bad packet: waiting for credit");
+			return -EINVAL;
+		}
+		priv->fw_dnld.substate = SUBSTATE_WAIT_COMMAND;
+		break;
+	}
+	return 0;
+}
+
+static int process_state_close_lc(struct nfcmrvl_private *priv,
+				  struct sk_buff *skb)
+{
+	if (sizeof(nci_pattern_core_conn_close_rsp) != skb->len ||
+	    memcmp(skb->data, nci_pattern_core_conn_close_rsp, skb->len))
+		return -EINVAL;
+
+	priv->fw_dnld.state = STATE_BOOT;
+	send_cmd(priv->ndev, NCI_OP_PROPRIETARY_BOOT_CMD, 0, NULL);
+	return 0;
+}
+
+static int process_state_boot(struct nfcmrvl_private *priv, struct sk_buff *skb)
+{
+	if (sizeof(nci_pattern_proprietary_boot_rsp) != skb->len ||
+	    memcmp(skb->data, nci_pattern_proprietary_boot_rsp, skb->len))
+		return -EINVAL;
+
+	/*
+	 * Update HI config to use the right configuration for the next
+	 * data exchanges.
+	 */
+	priv->if_ops->nci_update_config(priv,
+					&priv->fw_dnld.binary_config->config);
+
+	if (priv->fw_dnld.binary_config == &priv->fw_dnld.header->helper) {
+		/*
+		 * This is the case where an helper was needed and we have
+		 * uploaded it. Now we have to wait the next RESET NTF to start
+		 * FW download.
+		 */
+		priv->fw_dnld.state = STATE_RESET;
+		priv->fw_dnld.binary_config = &priv->fw_dnld.header->firmware;
+		nfc_info(priv->dev, "FW loading: helper loaded");
+	} else {
+		nfc_info(priv->dev, "FW loading: firmware loaded");
+		fw_dnld_over(priv, 0);
+	}
+	return 0;
+}
+
+static void fw_dnld_rx_work(struct work_struct *work)
+{
+	int ret;
+	struct sk_buff *skb;
+	struct nfcmrvl_fw_dnld *fw_dnld = container_of(work,
+						       struct nfcmrvl_fw_dnld,
+						       rx_work);
+	struct nfcmrvl_private *priv = container_of(fw_dnld,
+						    struct nfcmrvl_private,
+						    fw_dnld);
+
+	while ((skb = skb_dequeue(&fw_dnld->rx_q))) {
+		nfc_send_to_raw_sock(priv->ndev->nfc_dev, skb,
+				     RAW_PAYLOAD_NCI, NFC_DIRECTION_RX);
+		switch (fw_dnld->state) {
+		case STATE_RESET:
+			ret = process_state_reset(priv, skb);
+			break;
+		case STATE_INIT:
+			ret = process_state_init(priv, skb);
+			break;
+		case STATE_SET_REF_CLOCK:
+			ret = process_state_set_ref_clock(priv, skb);
+			break;
+		case STATE_SET_HI_CONFIG:
+			ret = process_state_set_hi_config(priv, skb);
+			break;
+		case STATE_OPEN_LC:
+			ret = process_state_open_lc(priv, skb);
+			break;
+		case STATE_FW_DNLD:
+			ret = process_state_fw_dnld(priv, skb);
+			break;
+		case STATE_CLOSE_LC:
+			ret = process_state_close_lc(priv, skb);
+			break;
+		case STATE_BOOT:
+			ret = process_state_boot(priv, skb);
+			break;
+		default:
+			ret = -EFAULT;
+		}
+
+		kfree_skb(skb);
+
+		if (ret != 0) {
+			nfc_err(priv->dev, "FW loading error");
+			fw_dnld_over(priv, ret);
+			break;
+		}
+	}
+}
+
+int	nfcmrvl_fw_dnld_init(struct nfcmrvl_private *priv)
+{
+	char name[32];
+
+	INIT_WORK(&priv->fw_dnld.rx_work, fw_dnld_rx_work);
+	snprintf(name, sizeof(name), "%s_nfcmrvl_fw_dnld_rx_wq",
+		 dev_name(priv->dev));
+	priv->fw_dnld.rx_wq = create_singlethread_workqueue(name);
+	if (!priv->fw_dnld.rx_wq)
+		return -ENOMEM;
+	skb_queue_head_init(&priv->fw_dnld.rx_q);
+	return 0;
+}
+
+void	nfcmrvl_fw_dnld_deinit(struct nfcmrvl_private *priv)
+{
+	destroy_workqueue(priv->fw_dnld.rx_wq);
+}
+
+void	nfcmrvl_fw_dnld_recv_frame(struct nfcmrvl_private *priv,
+				   struct sk_buff *skb)
+{
+	skb_queue_tail(&priv->fw_dnld.rx_q, skb);
+	queue_work(priv->fw_dnld.rx_wq, &priv->fw_dnld.rx_work);
+}
+
+void nfcmrvl_fw_dnld_abort(struct nfcmrvl_private *priv)
+{
+	fw_dnld_over(priv, -EHOSTDOWN);
+}
+
+int nfcmrvl_fw_dnld_start(struct nci_dev *ndev, const char *firmware_name)
+{
+	struct nfcmrvl_private *priv = nci_get_drvdata(ndev);
+	struct nfcmrvl_fw_dnld *fw_dnld = &priv->fw_dnld;
+
+	if (!priv->support_fw_dnld)
+		return -ENOTSUPP;
+
+	if (!firmware_name || !firmware_name[0])
+		return -EINVAL;
+
+	strcpy(fw_dnld->name, firmware_name);
+
+	/*
+	 * Retrieve FW binary file and parse it to initialize FW download
+	 * state machine.
+	 */
+
+	/* Retrieve FW binary */
+	if (request_firmware(&fw_dnld->fw, firmware_name, priv->dev) < 0) {
+		nfc_err(priv->dev, "failed to retrieve FW %s", firmware_name);
+		return -ENOENT;
+	}
+
+	fw_dnld->header = (const struct nfcmrvl_fw *) priv->fw_dnld.fw->data;
+
+	if (fw_dnld->header->magic != NFCMRVL_FW_MAGIC ||
+	    fw_dnld->header->phy != priv->phy) {
+		nfc_err(priv->dev, "bad firmware binary %s magic=0x%x phy=%d",
+			firmware_name, fw_dnld->header->magic,
+			fw_dnld->header->phy);
+		release_firmware(fw_dnld->fw);
+		fw_dnld->header = NULL;
+		return -EINVAL;
+	}
+
+	if (fw_dnld->header->helper.offset != 0) {
+		nfc_info(priv->dev, "loading helper");
+		fw_dnld->binary_config = &fw_dnld->header->helper;
+	} else {
+		nfc_info(priv->dev, "loading firmware");
+		fw_dnld->binary_config = &fw_dnld->header->firmware;
+	}
+
+	/* Configure a timer for timeout */
+	setup_timer(&priv->fw_dnld.timer, fw_dnld_timeout,
+		    (unsigned long) priv);
+	mod_timer(&priv->fw_dnld.timer,
+		  jiffies + msecs_to_jiffies(FW_DNLD_TIMEOUT));
+
+	/* Ronfigure HI to be sure that it is the bootrom values */
+	priv->if_ops->nci_update_config(priv,
+					&fw_dnld->header->bootrom.config);
+
+	/* First, reset the chip */
+	priv->fw_dnld.state = STATE_RESET;
+	nfcmrvl_chip_reset(priv);
+
+	/* Now wait for CORE_RESET_NTF or timeout */
+
+	return 0;
+}
diff --git a/drivers/nfc/nfcmrvl/fw_dnld.h b/drivers/nfc/nfcmrvl/fw_dnld.h
new file mode 100644
index 0000000..a63e777
--- /dev/null
+++ b/drivers/nfc/nfcmrvl/fw_dnld.h
@@ -0,0 +1,105 @@
+/**
+ * Marvell NFC driver: Firmware downloader
+ *
+ * Copyright (C) 2015, Marvell International Ltd.
+ *
+ * This software file (the "File") is distributed by Marvell International
+ * Ltd. under the terms of the GNU General Public License Version 2, June 1991
+ * (the "License").  You may use, redistribute and/or modify this File in
+ * accordance with the terms and conditions of the License, a copy of which
+ * is available on the worldwide web at
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+ *
+ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
+ * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about
+ * this warranty disclaimer.
+ **/
+
+#ifndef __NFCMRVL_FW_DNLD_H__
+#define __NFCMRVL_FW_DNLD_H__
+
+#include <linux/workqueue.h>
+
+#define NFCMRVL_FW_MAGIC		0x88888888
+
+#define NCI_OP_BOOT_CMD			0x3A
+
+#define NCI_CORE_LC_PROP_FW_DL		0xFD
+#define NCI_CORE_LC_CONNID_PROP_FW_DL	0x02
+
+#define HELPER_CMD_ENTRY_POINT		0x04
+#define HELPER_CMD_PACKET_FORMAT	0xA5
+#define HELPER_ACK_PACKET_FORMAT	0x5A
+#define HELPER_RETRY_REQUESTED		(1 << 15)
+
+struct nfcmrvl_private;
+
+enum nfcmrvl_phy {
+	NFCMRVL_PHY_USB		= 0,
+	NFCMRVL_PHY_UART	= 1,
+	NFCMRVL_PHY_I2C		= 2,
+	NFCMRVL_PHY_SPI		= 3,
+};
+
+struct nfcmrvl_fw_uart_config {
+	uint8_t flow_control;
+	uint32_t baudrate;
+} __packed;
+
+struct nfcmrvl_fw_i2c_config {
+	uint32_t clk;
+} __packed;
+
+struct nfcmrvl_fw_spi_config {
+	uint32_t clk;
+} __packed;
+
+struct nfcmrvl_fw_binary_config {
+	uint32_t offset;
+	union {
+		void *config;
+		struct nfcmrvl_fw_uart_config uart;
+		struct nfcmrvl_fw_i2c_config i2c;
+		struct nfcmrvl_fw_spi_config spi;
+		uint8_t reserved[64];
+	};
+} __packed;
+
+struct nfcmrvl_fw {
+	uint32_t magic;
+	uint32_t ref_clock;
+	enum nfcmrvl_phy phy;
+	struct nfcmrvl_fw_binary_config bootrom;
+	struct nfcmrvl_fw_binary_config helper;
+	struct nfcmrvl_fw_binary_config firmware;
+	uint8_t reserved[64];
+} __packed;
+
+struct nfcmrvl_fw_dnld {
+	char name[NFC_FIRMWARE_NAME_MAXSIZE + 1];
+	const struct firmware *fw;
+
+	const struct nfcmrvl_fw *header;
+	const struct nfcmrvl_fw_binary_config *binary_config;
+
+	int state;
+	int substate;
+	int offset;
+	int chunk_len;
+
+	struct workqueue_struct	*rx_wq;
+	struct work_struct rx_work;
+	struct sk_buff_head rx_q;
+
+	struct timer_list timer;
+};
+
+int nfcmrvl_fw_dnld_init(struct nfcmrvl_private *priv);
+void nfcmrvl_fw_dnld_deinit(struct nfcmrvl_private *priv);
+void nfcmrvl_fw_dnld_abort(struct nfcmrvl_private *priv);
+int nfcmrvl_fw_dnld_start(struct nci_dev *ndev, const char *firmware_name);
+void nfcmrvl_fw_dnld_recv_frame(struct nfcmrvl_private *priv,
+				struct sk_buff *skb);
+
+#endif
diff --git a/drivers/nfc/nfcmrvl/main.c b/drivers/nfc/nfcmrvl/main.c
index 77e292f..6fb23cc 100644
--- a/drivers/nfc/nfcmrvl/main.c
+++ b/drivers/nfc/nfcmrvl/main.c
@@ -61,9 +61,6 @@ static int nfcmrvl_nci_send(struct nci_dev *ndev, struct sk_buff *skb)
 
 	skb->dev = (void *)ndev;
 
-	if (!test_bit(NFCMRVL_NCI_RUNNING, &priv->flags))
-		return -EBUSY;
-
 	if (priv->config.hci_muxed) {
 		unsigned char *hdr;
 		unsigned char len = skb->len;
@@ -86,11 +83,18 @@ static int nfcmrvl_nci_setup(struct nci_dev *ndev)
 	return 0;
 }
 
+static int nfcmrvl_nci_fw_download(struct nci_dev *ndev,
+				   const char *firmware_name)
+{
+	return nfcmrvl_fw_dnld_start(ndev, firmware_name);
+}
+
 static struct nci_ops nfcmrvl_nci_ops = {
 	.open = nfcmrvl_nci_open,
 	.close = nfcmrvl_nci_close,
 	.send = nfcmrvl_nci_send,
 	.setup = nfcmrvl_nci_setup,
+	.fw_download = nfcmrvl_nci_fw_download,
 };
 
 struct nfcmrvl_private *nfcmrvl_nci_register_dev(void *drv_data,
@@ -143,18 +147,26 @@ struct nfcmrvl_private *nfcmrvl_nci_register_dev(void *drv_data,
 
 	nci_set_drvdata(priv->ndev, priv);
 
-	nfcmrvl_chip_reset(priv);
-
 	rc = nci_register_device(priv->ndev);
 	if (rc) {
 		nfc_err(dev, "nci_register_device failed %d\n", rc);
-		nci_free_device(priv->ndev);
-		goto error;
+		goto error_free_dev;
+	}
+
+	/* Ensure that controller is powered off */
+	nfcmrvl_chip_halt(priv);
+
+	rc = nfcmrvl_fw_dnld_init(priv);
+	if (rc) {
+		nfc_err(dev, "failed to initialize FW download %d\n", rc);
+		goto error_free_dev;
 	}
 
 	nfc_info(dev, "registered with nci successfully\n");
 	return priv;
 
+error_free_dev:
+	nci_free_device(priv->ndev);
 error:
 	kfree(priv);
 	return ERR_PTR(rc);
@@ -165,6 +177,11 @@ void nfcmrvl_nci_unregister_dev(struct nfcmrvl_private *priv)
 {
 	struct nci_dev *ndev = priv->ndev;
 
+	if (priv->ndev->nfc_dev->fw_download_in_progress)
+		nfcmrvl_fw_dnld_abort(priv);
+
+	nfcmrvl_fw_dnld_deinit(priv);
+
 	nci_unregister_device(ndev);
 	nci_free_device(ndev);
 	kfree(priv);
@@ -185,6 +202,11 @@ int nfcmrvl_nci_recv_frame(struct nfcmrvl_private *priv, struct sk_buff *skb)
 		}
 	}
 
+	if (priv->ndev->nfc_dev->fw_download_in_progress) {
+		nfcmrvl_fw_dnld_recv_frame(priv, skb);
+		return 0;
+	}
+
 	if (test_bit(NFCMRVL_NCI_RUNNING, &priv->flags))
 		nci_recv_frame(priv->ndev, skb);
 	else {
@@ -213,6 +235,12 @@ void nfcmrvl_chip_reset(struct nfcmrvl_private *priv)
 		nfc_info(priv->dev, "no reset available on this interface\n");
 }
 
+void nfcmrvl_chip_halt(struct nfcmrvl_private *priv)
+{
+	if (priv->config.reset_n_io)
+		gpio_set_value(priv->config.reset_n_io, 0);
+}
+
 #ifdef CONFIG_OF
 
 int nfcmrvl_parse_dt(struct device_node *node,
diff --git a/drivers/nfc/nfcmrvl/nfcmrvl.h b/drivers/nfc/nfcmrvl/nfcmrvl.h
index e5a7e54..773309c 100644
--- a/drivers/nfc/nfcmrvl/nfcmrvl.h
+++ b/drivers/nfc/nfcmrvl/nfcmrvl.h
@@ -1,7 +1,7 @@
 /**
  * Marvell NFC driver
  *
- * Copyright (C) 2014, Marvell International Ltd.
+ * Copyright (C) 2014-2015, Marvell International Ltd.
  *
  * This software file (the "File") is distributed by Marvell International
  * Ltd. under the terms of the GNU General Public License Version 2, June 1991
@@ -20,6 +20,7 @@
 #define _NFCMRVL_H_
 
 #include <linux/platform_data/nfcmrvl.h>
+#include "fw_dnld.h"
 
 /* Define private flags: */
 #define NFCMRVL_NCI_RUNNING			1
@@ -37,6 +38,8 @@
 */
 
 #define NFCMRVL_PB_BAIL_OUT			0x11
+#define NFCMRVL_PROP_REF_CLOCK			0xF0
+#define NFCMRVL_PROP_SET_HI_CONFIG		0xF1
 
 /*
 ** HCI defines
@@ -49,12 +52,6 @@
 #define NFCMRVL_HCI_OGF				0x81
 #define NFCMRVL_HCI_OCF				0xFE
 
-enum nfcmrvl_phy {
-	NFCMRVL_PHY_USB		= 0,
-	NFCMRVL_PHY_UART	= 1,
-};
-
-
 struct nfcmrvl_private {
 
 	unsigned long flags;
@@ -62,8 +59,15 @@ struct nfcmrvl_private {
 	/* Platform configuration */
 	struct nfcmrvl_platform_data config;
 
+	/* Parent dev */
 	struct nci_dev *ndev;
 
+	/* FW download context */
+	struct nfcmrvl_fw_dnld fw_dnld;
+
+	/* FW download support */
+	bool support_fw_dnld;
+
 	/*
 	** PHY related information
 	*/
@@ -82,6 +86,8 @@ struct nfcmrvl_if_ops {
 	int (*nci_open) (struct nfcmrvl_private *priv);
 	int (*nci_close) (struct nfcmrvl_private *priv);
 	int (*nci_send) (struct nfcmrvl_private *priv, struct sk_buff *skb);
+	void (*nci_update_config)(struct nfcmrvl_private *priv,
+				  const void *param);
 };
 
 void nfcmrvl_nci_unregister_dev(struct nfcmrvl_private *priv);
@@ -93,6 +99,7 @@ struct nfcmrvl_private *nfcmrvl_nci_register_dev(void *drv_data,
 
 
 void nfcmrvl_chip_reset(struct nfcmrvl_private *priv);
+void nfcmrvl_chip_halt(struct nfcmrvl_private *priv);
 
 int nfcmrvl_parse_dt(struct device_node *node,
 		     struct nfcmrvl_platform_data *pdata);
diff --git a/drivers/nfc/nfcmrvl/uart.c b/drivers/nfc/nfcmrvl/uart.c
index 61442d6..8355824 100644
--- a/drivers/nfc/nfcmrvl/uart.c
+++ b/drivers/nfc/nfcmrvl/uart.c
@@ -50,10 +50,21 @@ static int nfcmrvl_uart_nci_send(struct nfcmrvl_private *priv,
 	return nu->ops.send(nu, skb);
 }
 
+static void nfcmrvl_uart_nci_update_config(struct nfcmrvl_private *priv,
+					   const void *param)
+{
+	struct nci_uart *nu = priv->drv_data;
+	const struct nfcmrvl_fw_uart_config *config = param;
+
+	nci_uart_set_config(nu, le32_to_cpu(config->baudrate),
+			    config->flow_control);
+}
+
 static struct nfcmrvl_if_ops uart_ops = {
 	.nci_open = nfcmrvl_uart_nci_open,
 	.nci_close = nfcmrvl_uart_nci_close,
 	.nci_send = nfcmrvl_uart_nci_send,
+	.nci_update_config = nfcmrvl_uart_nci_update_config
 };
 
 #ifdef CONFIG_OF
@@ -132,6 +143,7 @@ static int nfcmrvl_nci_uart_open(struct nci_uart *nu)
 		return PTR_ERR(priv);
 
 	priv->phy = NFCMRVL_PHY_UART;
+	priv->support_fw_dnld = true;
 
 	nu->drv_data = priv;
 	nu->ndev = priv->ndev;
diff --git a/drivers/nfc/nfcmrvl/usb.c b/drivers/nfc/nfcmrvl/usb.c
index 5e624d1..b276174 100644
--- a/drivers/nfc/nfcmrvl/usb.c
+++ b/drivers/nfc/nfcmrvl/usb.c
@@ -347,6 +347,8 @@ static int nfcmrvl_probe(struct usb_interface *intf,
 
 	drv_data->priv = priv;
 	drv_data->priv->phy = NFCMRVL_PHY_USB;
+	drv_data->priv->support_fw_dnld = false;
+
 	priv->dev = &drv_data->udev->dev;
 
 	usb_set_intfdata(intf, drv_data);
-- 
2.2.0.33.gc18b867

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH v2 4/9] NFC: nfcmrvl: allow low level drivers to configure head/tail room
       [not found] ` <1443443594-14353-1-git-send-email-cuissard-eYqpPyKDWXRBDgjK7y7TUQ@public.gmane.org>
                     ` (2 preceding siblings ...)
  2015-09-28 12:33   ` [PATCH v2 3/9] NFC: nfcmrvl: add firmware download support Vincent Cuissard
@ 2015-09-28 12:33   ` Vincent Cuissard
       [not found]     ` <1443443594-14353-5-git-send-email-cuissard-eYqpPyKDWXRBDgjK7y7TUQ@public.gmane.org>
  2015-09-28 12:33   ` [PATCH v2 5/9] NFC: nfcmrvl: add i2c driver Vincent Cuissard
                     ` (4 subsequent siblings)
  8 siblings, 1 reply; 26+ messages in thread
From: Vincent Cuissard @ 2015-09-28 12:33 UTC (permalink / raw)
  To: linux-nfc-hn68Rpc1hR1g9hUCZPvPmw
  Cc: devicetree-u79uwXL29TY76Z2rM5mHXA, Vincent Cuissard

Low-level drivers may need to add some data before and/or after NCI packet.

Signed-off-by: Vincent Cuissard <cuissard-eYqpPyKDWXRBDgjK7y7TUQ@public.gmane.org>
---
 drivers/nfc/nfcmrvl/main.c            | 6 +++---
 drivers/nfc/nfcmrvl/uart.c            | 2 ++
 include/linux/platform_data/nfcmrvl.h | 3 +++
 3 files changed, 8 insertions(+), 3 deletions(-)

diff --git a/drivers/nfc/nfcmrvl/main.c b/drivers/nfc/nfcmrvl/main.c
index 6fb23cc..bd8db3d 100644
--- a/drivers/nfc/nfcmrvl/main.c
+++ b/drivers/nfc/nfcmrvl/main.c
@@ -104,7 +104,7 @@ struct nfcmrvl_private *nfcmrvl_nci_register_dev(void *drv_data,
 {
 	struct nfcmrvl_private *priv;
 	int rc;
-	int headroom = 0;
+	int headroom = pdata->phy_headroom;
 	u32 protocols;
 
 	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
@@ -127,7 +127,7 @@ struct nfcmrvl_private *nfcmrvl_nci_register_dev(void *drv_data,
 	}
 
 	if (priv->config.hci_muxed)
-		headroom = NFCMRVL_HCI_EVENT_HEADER_SIZE;
+		headroom += NFCMRVL_HCI_EVENT_HEADER_SIZE;
 
 	protocols = NFC_PROTO_JEWEL_MASK
 		| NFC_PROTO_MIFARE_MASK
@@ -138,7 +138,7 @@ struct nfcmrvl_private *nfcmrvl_nci_register_dev(void *drv_data,
 		| NFC_PROTO_NFC_DEP_MASK;
 
 	priv->ndev = nci_allocate_device(&nfcmrvl_nci_ops, protocols,
-					 headroom, 0);
+					 headroom, priv->config.phy_tailroom);
 	if (!priv->ndev) {
 		nfc_err(dev, "nci_allocate_device failed\n");
 		rc = -ENOMEM;
diff --git a/drivers/nfc/nfcmrvl/uart.c b/drivers/nfc/nfcmrvl/uart.c
index 8355824..b851334 100644
--- a/drivers/nfc/nfcmrvl/uart.c
+++ b/drivers/nfc/nfcmrvl/uart.c
@@ -138,6 +138,8 @@ static int nfcmrvl_nci_uart_open(struct nci_uart *nu)
 		pdata = &config;
 	}
 
+	pdata->phy_headroom = pdata->phy_tailroom = 0;
+
 	priv = nfcmrvl_nci_register_dev(nu, &uart_ops, nu->tty->dev, pdata);
 	if (IS_ERR(priv))
 		return PTR_ERR(priv);
diff --git a/include/linux/platform_data/nfcmrvl.h b/include/linux/platform_data/nfcmrvl.h
index ac91707..6f6ba27 100644
--- a/include/linux/platform_data/nfcmrvl.h
+++ b/include/linux/platform_data/nfcmrvl.h
@@ -26,6 +26,9 @@ struct nfcmrvl_platform_data {
 	unsigned int reset_n_io;
 	/* Tell if transport is muxed in HCI one */
 	unsigned int hci_muxed;
+	/* Tell generic driver that the PHY requires some headroom space */
+	unsigned int phy_headroom;
+	unsigned int phy_tailroom;
 
 	/*
 	 * UART specific
-- 
2.2.0.33.gc18b867

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH v2 5/9] NFC: nfcmrvl: add i2c driver
       [not found] ` <1443443594-14353-1-git-send-email-cuissard-eYqpPyKDWXRBDgjK7y7TUQ@public.gmane.org>
                     ` (3 preceding siblings ...)
  2015-09-28 12:33   ` [PATCH v2 4/9] NFC: nfcmrvl: allow low level drivers to configure head/tail room Vincent Cuissard
@ 2015-09-28 12:33   ` Vincent Cuissard
       [not found]     ` <1443443594-14353-6-git-send-email-cuissard-eYqpPyKDWXRBDgjK7y7TUQ@public.gmane.org>
  2015-09-28 12:33   ` [PATCH v2 6/9] NFC: NCI: move generic spi driver to a module Vincent Cuissard
                     ` (3 subsequent siblings)
  8 siblings, 1 reply; 26+ messages in thread
From: Vincent Cuissard @ 2015-09-28 12:33 UTC (permalink / raw)
  To: linux-nfc-hn68Rpc1hR1g9hUCZPvPmw
  Cc: devicetree-u79uwXL29TY76Z2rM5mHXA, Vincent Cuissard

This driver adds the support of I2C-based Marvell NFC controller.

Signed-off-by: Vincent Cuissard <cuissard-eYqpPyKDWXRBDgjK7y7TUQ@public.gmane.org>
---
 .../devicetree/bindings/net/nfc/nfcmrvl.txt        |  34 ++-
 drivers/nfc/nfcmrvl/Kconfig                        |  12 +
 drivers/nfc/nfcmrvl/Makefile                       |   3 +
 drivers/nfc/nfcmrvl/i2c.c                          | 302 +++++++++++++++++++++
 drivers/nfc/nfcmrvl/main.c                         |   9 +-
 drivers/nfc/nfcmrvl/nfcmrvl.h                      |   1 +
 include/linux/platform_data/nfcmrvl.h              |   8 +
 include/net/nfc/nci.h                              |   1 +
 8 files changed, 365 insertions(+), 5 deletions(-)
 create mode 100644 drivers/nfc/nfcmrvl/i2c.c

diff --git a/Documentation/devicetree/bindings/net/nfc/nfcmrvl.txt b/Documentation/devicetree/bindings/net/nfc/nfcmrvl.txt
index 7c4a0cc..0fa20cc 100644
--- a/Documentation/devicetree/bindings/net/nfc/nfcmrvl.txt
+++ b/Documentation/devicetree/bindings/net/nfc/nfcmrvl.txt
@@ -1,7 +1,9 @@
 * Marvell International Ltd. NCI NFC Controller
 
 Required properties:
-- compatible: Should be "mrvl,nfc-uart".
+- compatible: Should be:
+  - "mrvl,nfc-uart" for UART devices
+  - "mrvl,nfc-i2c" for I2C devices
 
 Optional SoC specific properties:
 - pinctrl-names: Contains only one value - "default".
@@ -13,6 +15,12 @@ Optional UART-based chip specific properties:
 - flow-control: Specifies that the chip is using RTS/CTS.
 - break-control: Specifies that the chip needs specific break management.
 
+Optional I2C-based chip specific properties:
+- i2c-int-falling: Specifies that the chip read event shall be trigged on
+  		   falling edge.
+- i2c-int-rising: Specifies that the chip read event shall be trigged on
+  		  rising edge.
+
 Example (for ARM-based BeagleBoard Black with 88W8887 on UART5):
 
 &uart5 {
@@ -27,3 +35,27 @@ Example (for ARM-based BeagleBoard Black with 88W8887 on UART5):
 		flow-control;
         }
 };
+
+
+Example (for ARM-based BeagleBoard Black with 88W8887 on I2C1):
+
+&i2c1 {
+	status = "okay";
+	clock-frequency = <400000>;
+
+	nfcmrvli2c0: i2c@1 {
+		compatible = "mrvl,nfc-i2c";
+
+		reg = <0x8>;
+
+		/* I2C INT configuration */
+		interrupt-parent = <&gpio3>;
+		interrupts = <21 0>;
+
+		/* I2C INT trigger configuration */
+		i2c-int-rising;
+
+		/* Reset IO */
+		reset-n-io = <&gpio3 19 0>;
+	};
+};
diff --git a/drivers/nfc/nfcmrvl/Kconfig b/drivers/nfc/nfcmrvl/Kconfig
index 796be24..77b4725 100644
--- a/drivers/nfc/nfcmrvl/Kconfig
+++ b/drivers/nfc/nfcmrvl/Kconfig
@@ -32,3 +32,15 @@ config NFC_MRVL_UART
 
 	  Say Y here to compile support for Marvell NFC-over-UART driver
 	  into the kernel or say M to compile it as module.
+
+config NFC_MRVL_I2C
+	tristate "Marvell NFC-over-I2C driver"
+	depends on NFC_MRVL && I2C
+	help
+	  Marvell NFC-over-I2C driver.
+
+	  This driver provides support for Marvell NFC-over-I2C devices.
+
+	  Say Y here to compile support for Marvell NFC-over-I2C driver
+	  into the kernel or say M to compile it as module.
+
diff --git a/drivers/nfc/nfcmrvl/Makefile b/drivers/nfc/nfcmrvl/Makefile
index 4554ee8..895866a 100644
--- a/drivers/nfc/nfcmrvl/Makefile
+++ b/drivers/nfc/nfcmrvl/Makefile
@@ -10,3 +10,6 @@ obj-$(CONFIG_NFC_MRVL_USB) += nfcmrvl_usb.o
 
 nfcmrvl_uart-y += uart.o
 obj-$(CONFIG_NFC_MRVL_UART) += nfcmrvl_uart.o
+
+nfcmrvl_i2c-y += i2c.o
+obj-$(CONFIG_NFC_MRVL_I2C) += nfcmrvl_i2c.o
diff --git a/drivers/nfc/nfcmrvl/i2c.c b/drivers/nfc/nfcmrvl/i2c.c
new file mode 100644
index 0000000..b48c3ee
--- /dev/null
+++ b/drivers/nfc/nfcmrvl/i2c.c
@@ -0,0 +1,302 @@
+/**
+ * Marvell NFC-over-I2C driver: I2C interface related functions
+ *
+ * Copyright (C) 2015, Marvell International Ltd.
+ *
+ * This software file (the "File") is distributed by Marvell International
+ * Ltd. under the terms of the GNU General Public License Version 2, June 1991
+ * (the "License").  You may use, redistribute and/or modify this File in
+ * accordance with the terms and conditions of the License, a copy of which
+ * is available on the worldwide web at
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+ *
+ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
+ * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about
+ * this warranty disclaimer.
+ **/
+
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/i2c.h>
+#include <linux/pm_runtime.h>
+#include <linux/nfc.h>
+#include <linux/gpio.h>
+#include <linux/delay.h>
+#include <linux/of_irq.h>
+#include <linux/of_gpio.h>
+#include <net/nfc/nci.h>
+#include <net/nfc/nci_core.h>
+#include "nfcmrvl.h"
+
+struct nfcmrvl_i2c_drv_data {
+	unsigned long flags;
+	struct device *dev;
+	struct i2c_client *i2c;
+	struct nfcmrvl_private *priv;
+};
+
+static int nfcmrvl_i2c_read(struct nfcmrvl_i2c_drv_data *drv_data,
+			    struct sk_buff **skb)
+{
+	int ret;
+	struct nci_ctrl_hdr nci_hdr;
+
+	/* Read NCI header to know the payload size */
+	ret = i2c_master_recv(drv_data->i2c, (u8 *)&nci_hdr, NCI_CTRL_HDR_SIZE);
+	if (ret != NCI_CTRL_HDR_SIZE) {
+		nfc_err(&drv_data->i2c->dev, "cannot read NCI header\n");
+		return -EBADMSG;
+	}
+
+	if (nci_hdr.plen > NCI_MAX_PAYLOAD_SIZE) {
+		nfc_err(&drv_data->i2c->dev, "invalid packet payload size\n");
+		return -EBADMSG;
+	}
+
+	*skb = nci_skb_alloc(drv_data->priv->ndev,
+			     nci_hdr.plen + NCI_CTRL_HDR_SIZE, GFP_KERNEL);
+	if (!*skb)
+		return -ENOMEM;
+
+	/* Copy NCI header into the SKB */
+	memcpy(skb_put(*skb, NCI_CTRL_HDR_SIZE), &nci_hdr, NCI_CTRL_HDR_SIZE);
+
+	/* Read the NCI payload */
+	ret = i2c_master_recv(drv_data->i2c, skb_put(*skb, nci_hdr.plen),
+			      nci_hdr.plen);
+	if (ret != nci_hdr.plen) {
+		nfc_err(&drv_data->i2c->dev,
+			"Invalid frame payload length: %u (expected %u)\n",
+			ret, nci_hdr.plen);
+		kfree_skb(*skb);
+		return -EBADMSG;
+	}
+
+	return 0;
+}
+
+static irqreturn_t nfcmrvl_i2c_int_irq_thread_fn(int irq, void *drv_data_ptr)
+{
+	struct nfcmrvl_i2c_drv_data *drv_data = drv_data_ptr;
+	struct sk_buff *skb = NULL;
+	int ret;
+
+	if (!drv_data->priv)
+		return IRQ_HANDLED;
+
+	if (test_bit(NFCMRVL_PHY_ERROR, &drv_data->priv->flags))
+		return IRQ_HANDLED;
+
+	ret = nfcmrvl_i2c_read(drv_data, &skb);
+
+	switch (ret) {
+	case -EREMOTEIO:
+		set_bit(NFCMRVL_PHY_ERROR, &drv_data->priv->flags);
+		break;
+	case -ENOMEM:
+	case -EBADMSG:
+		nfc_err(&drv_data->i2c->dev, "read failed %d\n", ret);
+		break;
+	default:
+		if (nfcmrvl_nci_recv_frame(drv_data->priv, skb) < 0)
+			nfc_err(&drv_data->i2c->dev, "corrupted RX packet\n");
+		break;
+	}
+	return IRQ_HANDLED;
+}
+
+static int nfcmrvl_i2c_nci_open(struct nfcmrvl_private *priv)
+{
+	struct nfcmrvl_i2c_drv_data *drv_data = priv->drv_data;
+
+	if (!drv_data)
+		return -ENODEV;
+
+	return 0;
+}
+
+static int nfcmrvl_i2c_nci_close(struct nfcmrvl_private *priv)
+{
+	return 0;
+}
+
+static int nfcmrvl_i2c_nci_send(struct nfcmrvl_private *priv,
+				struct sk_buff *skb)
+{
+	struct nfcmrvl_i2c_drv_data *drv_data = priv->drv_data;
+	int ret;
+
+	if (test_bit(NFCMRVL_PHY_ERROR, &priv->flags))
+		return -EREMOTEIO;
+
+	ret = i2c_master_send(drv_data->i2c, skb->data, skb->len);
+
+	/* Retry if chip was in standby */
+	if (ret == -EREMOTEIO) {
+		nfc_info(drv_data->dev, "chip may sleep, retry\n");
+		usleep_range(6000, 10000);
+		ret = i2c_master_send(drv_data->i2c, skb->data, skb->len);
+	}
+
+	if (ret >= 0) {
+		if (ret != skb->len) {
+			nfc_err(drv_data->dev,
+				"Invalid length sent: %u (expected %u)\n",
+				ret, skb->len);
+			ret = -EREMOTEIO;
+		} else
+			ret = 0;
+		kfree_skb(skb);
+	}
+
+	return ret;
+}
+
+static void nfcmrvl_i2c_nci_update_config(struct nfcmrvl_private *priv,
+					  const void *param)
+{
+}
+
+static struct nfcmrvl_if_ops i2c_ops = {
+	.nci_open = nfcmrvl_i2c_nci_open,
+	.nci_close = nfcmrvl_i2c_nci_close,
+	.nci_send = nfcmrvl_i2c_nci_send,
+	.nci_update_config = nfcmrvl_i2c_nci_update_config,
+};
+
+
+#ifdef CONFIG_OF
+
+static int nfcmrvl_i2c_parse_dt(struct device_node *node,
+				struct nfcmrvl_platform_data *pdata)
+{
+	int ret;
+
+	ret = nfcmrvl_parse_dt(node, pdata);
+	if (ret < 0) {
+		pr_err("Failed to get generic entries\n");
+		return ret;
+	}
+
+	if (of_find_property(node, "i2c-int-falling", NULL))
+		pdata->irq_polarity = IRQF_TRIGGER_FALLING;
+	else
+		pdata->irq_polarity = IRQF_TRIGGER_RISING;
+
+	ret = irq_of_parse_and_map(node, 0);
+	if (ret < 0) {
+		pr_err("Unable to get irq, error: %d\n", ret);
+		return ret;
+	}
+	pdata->irq = ret;
+
+	return 0;
+}
+
+#else
+
+static int nfcmrvl_i2c_parse_dt(struct device_node *node,
+				struct nfcmrvl_platform_data *pdata)
+{
+	return -ENODEV;
+}
+
+#endif
+
+static int nfcmrvl_i2c_probe(struct i2c_client *client,
+			     const struct i2c_device_id *id)
+{
+	struct nfcmrvl_i2c_drv_data *drv_data;
+	struct nfcmrvl_platform_data *pdata;
+	struct nfcmrvl_platform_data config;
+	int ret;
+
+	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+		nfc_err(&client->dev, "Need I2C_FUNC_I2C\n");
+		return -ENODEV;
+	}
+
+	drv_data = devm_kzalloc(&client->dev, sizeof(*drv_data), GFP_KERNEL);
+	if (!drv_data)
+		return -ENOMEM;
+
+	drv_data->i2c = client;
+	drv_data->dev = &client->dev;
+	drv_data->priv = NULL;
+
+	i2c_set_clientdata(client, drv_data);
+
+	pdata = client->dev.platform_data;
+
+	if (!pdata && client->dev.of_node)
+		if (nfcmrvl_i2c_parse_dt(client->dev.of_node, &config) == 0)
+			pdata = &config;
+
+	if (!pdata)
+		return -EINVAL;
+
+	pdata->phy_headroom = pdata->phy_tailroom = 0;
+
+	/* Request the read IRQ */
+	ret = devm_request_threaded_irq(&drv_data->i2c->dev, pdata->irq,
+					NULL, nfcmrvl_i2c_int_irq_thread_fn,
+					pdata->irq_polarity | IRQF_ONESHOT,
+					"nfcmrvl_i2c_int", drv_data);
+	if (ret < 0) {
+		nfc_err(&drv_data->i2c->dev,
+			"Unable to register IRQ handler\n");
+		return ret;
+	}
+
+	drv_data->priv = nfcmrvl_nci_register_dev(drv_data, &i2c_ops,
+						  &drv_data->i2c->dev, pdata);
+
+	if (IS_ERR(drv_data->priv))
+		return PTR_ERR(drv_data->priv);
+
+	drv_data->priv->phy = NFCMRVL_PHY_I2C;
+	drv_data->priv->support_fw_dnld = true;
+
+
+	return 0;
+}
+
+static int nfcmrvl_i2c_remove(struct i2c_client *client)
+{
+	struct nfcmrvl_i2c_drv_data *drv_data = i2c_get_clientdata(client);
+
+	nfcmrvl_nci_unregister_dev(drv_data->priv);
+
+	return 0;
+}
+
+
+static const struct of_device_id of_nfcmrvl_i2c_match[] = {
+	{ .compatible = "mrvl,nfc-i2c", },
+	{},
+};
+MODULE_DEVICE_TABLE(of, of_nfcmrvl_i2c_match);
+
+static struct i2c_device_id nfcmrvl_i2c_id_table[] = {
+	{ "nfcmrvl_i2c", 0 },
+	{}
+};
+MODULE_DEVICE_TABLE(i2c, nfcmrvl_i2c_id_table);
+
+static struct i2c_driver nfcmrvl_i2c_driver = {
+	.probe = nfcmrvl_i2c_probe,
+	.id_table = nfcmrvl_i2c_id_table,
+	.remove = nfcmrvl_i2c_remove,
+	.driver = {
+		.name		= "nfcmrvl_i2c",
+		.owner		= THIS_MODULE,
+		.of_match_table	= of_match_ptr(of_nfcmrvl_i2c_match),
+	},
+};
+
+module_i2c_driver(nfcmrvl_i2c_driver);
+
+MODULE_AUTHOR("Marvell International Ltd.");
+MODULE_DESCRIPTION("Marvell NFC-over-I2C driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/nfc/nfcmrvl/main.c b/drivers/nfc/nfcmrvl/main.c
index bd8db3d..1104fa3 100644
--- a/drivers/nfc/nfcmrvl/main.c
+++ b/drivers/nfc/nfcmrvl/main.c
@@ -33,6 +33,9 @@ static int nfcmrvl_nci_open(struct nci_dev *ndev)
 	if (test_and_set_bit(NFCMRVL_NCI_RUNNING, &priv->flags))
 		return 0;
 
+	/* Reset possible fault of previous session */
+	clear_bit(NFCMRVL_PHY_ERROR, &priv->flags);
+
 	err = priv->if_ops->nci_open(priv);
 
 	if (err)
@@ -221,10 +224,8 @@ EXPORT_SYMBOL_GPL(nfcmrvl_nci_recv_frame);
 
 void nfcmrvl_chip_reset(struct nfcmrvl_private *priv)
 {
-	/*
-	 * This function does not take care if someone is using the device.
-	 * To be improved.
-	 */
+	/* Reset possible fault of previous session */
+	clear_bit(NFCMRVL_PHY_ERROR, &priv->flags);
 
 	if (priv->config.reset_n_io) {
 		nfc_info(priv->dev, "reset the chip\n");
diff --git a/drivers/nfc/nfcmrvl/nfcmrvl.h b/drivers/nfc/nfcmrvl/nfcmrvl.h
index 773309c..303edb9 100644
--- a/drivers/nfc/nfcmrvl/nfcmrvl.h
+++ b/drivers/nfc/nfcmrvl/nfcmrvl.h
@@ -24,6 +24,7 @@
 
 /* Define private flags: */
 #define NFCMRVL_NCI_RUNNING			1
+#define NFCMRVL_PHY_ERROR			2
 
 #define NFCMRVL_EXT_COEX_ID			0xE0
 #define NFCMRVL_NOT_ALLOWED_ID			0xE1
diff --git a/include/linux/platform_data/nfcmrvl.h b/include/linux/platform_data/nfcmrvl.h
index 6f6ba27..2279488 100644
--- a/include/linux/platform_data/nfcmrvl.h
+++ b/include/linux/platform_data/nfcmrvl.h
@@ -38,6 +38,14 @@ struct nfcmrvl_platform_data {
 	unsigned int flow_control;
 	/* Tell if firmware supports break control for power management */
 	unsigned int break_control;
+
+
+	/*
+	 * I2C specific
+	 */
+
+	unsigned int irq;
+	unsigned int irq_polarity;
 };
 
 #endif /* _NFCMRVL_PTF_H_ */
diff --git a/include/net/nfc/nci.h b/include/net/nfc/nci.h
index 75d2e18..0fbc647 100644
--- a/include/net/nfc/nci.h
+++ b/include/net/nfc/nci.h
@@ -35,6 +35,7 @@
 #define NCI_MAX_NUM_RF_CONFIGS					10
 #define NCI_MAX_NUM_CONN					10
 #define NCI_MAX_PARAM_LEN					251
+#define NCI_MAX_PAYLOAD_SIZE					255
 #define NCI_MAX_PACKET_SIZE					258
 
 /* NCI Status Codes */
-- 
2.2.0.33.gc18b867

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH v2 6/9] NFC: NCI: move generic spi driver to a module
       [not found] ` <1443443594-14353-1-git-send-email-cuissard-eYqpPyKDWXRBDgjK7y7TUQ@public.gmane.org>
                     ` (4 preceding siblings ...)
  2015-09-28 12:33   ` [PATCH v2 5/9] NFC: nfcmrvl: add i2c driver Vincent Cuissard
@ 2015-09-28 12:33   ` Vincent Cuissard
  2015-09-28 12:33   ` [PATCH v2 7/9] NFC: NCI: allow spi driver to choose transfer clock Vincent Cuissard
                     ` (2 subsequent siblings)
  8 siblings, 0 replies; 26+ messages in thread
From: Vincent Cuissard @ 2015-09-28 12:33 UTC (permalink / raw)
  To: linux-nfc-hn68Rpc1hR1g9hUCZPvPmw
  Cc: devicetree-u79uwXL29TY76Z2rM5mHXA, Vincent Cuissard

SPI driver should be a module.

Signed-off-by: Vincent Cuissard <cuissard-eYqpPyKDWXRBDgjK7y7TUQ@public.gmane.org>
---
 net/nfc/nci/Kconfig  | 2 +-
 net/nfc/nci/Makefile | 3 ++-
 net/nfc/nci/spi.c    | 4 ++++
 3 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/net/nfc/nci/Kconfig b/net/nfc/nci/Kconfig
index 901c1dd..85d4819 100644
--- a/net/nfc/nci/Kconfig
+++ b/net/nfc/nci/Kconfig
@@ -12,7 +12,7 @@ config NFC_NCI
 config NFC_NCI_SPI
 	depends on NFC_NCI && SPI
 	select CRC_CCITT
-	bool "NCI over SPI protocol support"
+	tristate "NCI over SPI protocol support"
 	default n
 	help
 	  NCI (NFC Controller Interface) is a communication protocol between
diff --git a/net/nfc/nci/Makefile b/net/nfc/nci/Makefile
index b4b85b8..0ca31d9 100644
--- a/net/nfc/nci/Makefile
+++ b/net/nfc/nci/Makefile
@@ -6,7 +6,8 @@ obj-$(CONFIG_NFC_NCI) += nci.o
 
 nci-objs := core.o data.o lib.o ntf.o rsp.o hci.o
 
-nci-$(CONFIG_NFC_NCI_SPI) += spi.o
+nci_spi-y += spi.o
+obj-$(CONFIG_NFC_NCI_SPI) += nci_spi.o
 
 nci_uart-y += uart.o
 obj-$(CONFIG_NFC_NCI_UART) += nci_uart.o
diff --git a/net/nfc/nci/spi.c b/net/nfc/nci/spi.c
index ec250e7..25153d0 100644
--- a/net/nfc/nci/spi.c
+++ b/net/nfc/nci/spi.c
@@ -18,6 +18,8 @@
 
 #define pr_fmt(fmt) "nci_spi: %s: " fmt, __func__
 
+#include <linux/module.h>
+
 #include <linux/export.h>
 #include <linux/spi/spi.h>
 #include <linux/crc-ccitt.h>
@@ -320,3 +322,5 @@ done:
 	return skb;
 }
 EXPORT_SYMBOL_GPL(nci_spi_read);
+
+MODULE_LICENSE("GPL");
-- 
2.2.0.33.gc18b867

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH v2 7/9] NFC: NCI: allow spi driver to choose transfer clock
       [not found] ` <1443443594-14353-1-git-send-email-cuissard-eYqpPyKDWXRBDgjK7y7TUQ@public.gmane.org>
                     ` (5 preceding siblings ...)
  2015-09-28 12:33   ` [PATCH v2 6/9] NFC: NCI: move generic spi driver to a module Vincent Cuissard
@ 2015-09-28 12:33   ` Vincent Cuissard
  2015-09-28 12:33   ` [PATCH v2 8/9] NFC: nfcmrvl: add spi driver Vincent Cuissard
  2015-09-28 12:33   ` [PATCH v2 9/9] NFC: nfcmrvl: update device tree bindings for Marvell NFC Vincent Cuissard
  8 siblings, 0 replies; 26+ messages in thread
From: Vincent Cuissard @ 2015-09-28 12:33 UTC (permalink / raw)
  To: linux-nfc-hn68Rpc1hR1g9hUCZPvPmw
  Cc: devicetree-u79uwXL29TY76Z2rM5mHXA, Vincent Cuissard

In some cases low level drivers might want to update the SPI transfer clock
(e.g. during firmware download).

This patch adds this support. Without any modification the driver will use the
default SPI clock (from pdata or device tree).

Signed-off-by: Vincent Cuissard <cuissard-eYqpPyKDWXRBDgjK7y7TUQ@public.gmane.org>
---
 include/net/nfc/nci_core.h | 4 ++++
 net/nfc/nci/spi.c          | 7 ++++++-
 2 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/include/net/nfc/nci_core.h b/include/net/nfc/nci_core.h
index f0bb5e7..0f91e09 100644
--- a/include/net/nfc/nci_core.h
+++ b/include/net/nfc/nci_core.h
@@ -381,6 +381,10 @@ struct nci_spi {
 
 	unsigned int		xfer_udelay;	/* microseconds delay between
 						  transactions */
+
+	unsigned int		xfer_speed_hz; /* SPI clock frequency
+						 0 => default clock */
+
 	u8			acknowledge_mode;
 
 	struct completion	req_completion;
diff --git a/net/nfc/nci/spi.c b/net/nfc/nci/spi.c
index 25153d0..d904cd2 100644
--- a/net/nfc/nci/spi.c
+++ b/net/nfc/nci/spi.c
@@ -58,6 +58,7 @@ static int __nci_spi_send(struct nci_spi *nspi, struct sk_buff *skb,
 	}
 	t.cs_change = cs_change;
 	t.delay_usecs = nspi->xfer_udelay;
+	t.speed_hz = nspi->xfer_speed_hz;
 
 	spi_message_init(&m);
 	spi_message_add_tail(&t, &m);
@@ -144,7 +145,8 @@ struct nci_spi *nci_spi_allocate_spi(struct spi_device *spi,
 
 	nspi->acknowledge_mode = acknowledge_mode;
 	nspi->xfer_udelay = delay;
-
+	/* Use controller max SPI speed by default */
+	nspi->xfer_speed_hz = 0;
 	nspi->spi = spi;
 	nspi->ndev = ndev;
 	init_completion(&nspi->req_completion);
@@ -197,12 +199,14 @@ static struct sk_buff *__nci_spi_read(struct nci_spi *nspi)
 	tx.tx_buf = req;
 	tx.len = 2;
 	tx.cs_change = 0;
+	tx.speed_hz = nspi->xfer_speed_hz;
 	spi_message_add_tail(&tx, &m);
 
 	memset(&rx, 0, sizeof(struct spi_transfer));
 	rx.rx_buf = resp_hdr;
 	rx.len = 2;
 	rx.cs_change = 1;
+	rx.speed_hz = nspi->xfer_speed_hz;
 	spi_message_add_tail(&rx, &m);
 
 	ret = spi_sync(nspi->spi, &m);
@@ -226,6 +230,7 @@ static struct sk_buff *__nci_spi_read(struct nci_spi *nspi)
 	rx.len = rx_len;
 	rx.cs_change = 0;
 	rx.delay_usecs = nspi->xfer_udelay;
+	rx.speed_hz = nspi->xfer_speed_hz;
 	spi_message_add_tail(&rx, &m);
 
 	ret = spi_sync(nspi->spi, &m);
-- 
2.2.0.33.gc18b867

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH v2 8/9] NFC: nfcmrvl: add spi driver
       [not found] ` <1443443594-14353-1-git-send-email-cuissard-eYqpPyKDWXRBDgjK7y7TUQ@public.gmane.org>
                     ` (6 preceding siblings ...)
  2015-09-28 12:33   ` [PATCH v2 7/9] NFC: NCI: allow spi driver to choose transfer clock Vincent Cuissard
@ 2015-09-28 12:33   ` Vincent Cuissard
  2015-09-28 12:33   ` [PATCH v2 9/9] NFC: nfcmrvl: update device tree bindings for Marvell NFC Vincent Cuissard
  8 siblings, 0 replies; 26+ messages in thread
From: Vincent Cuissard @ 2015-09-28 12:33 UTC (permalink / raw)
  To: linux-nfc-hn68Rpc1hR1g9hUCZPvPmw
  Cc: devicetree-u79uwXL29TY76Z2rM5mHXA, Vincent Cuissard

This driver adds the support of SPI-based Marvell NFC controller.

Signed-off-by: Vincent Cuissard <cuissard-eYqpPyKDWXRBDgjK7y7TUQ@public.gmane.org>
---
 .../devicetree/bindings/net/nfc/nfcmrvl.txt        |  25 +++
 drivers/nfc/nfcmrvl/Kconfig                        |  10 +
 drivers/nfc/nfcmrvl/Makefile                       |   3 +
 drivers/nfc/nfcmrvl/spi.c                          | 242 +++++++++++++++++++++
 4 files changed, 280 insertions(+)
 create mode 100644 drivers/nfc/nfcmrvl/spi.c

diff --git a/Documentation/devicetree/bindings/net/nfc/nfcmrvl.txt b/Documentation/devicetree/bindings/net/nfc/nfcmrvl.txt
index 0fa20cc..41058fc 100644
--- a/Documentation/devicetree/bindings/net/nfc/nfcmrvl.txt
+++ b/Documentation/devicetree/bindings/net/nfc/nfcmrvl.txt
@@ -4,6 +4,7 @@ Required properties:
 - compatible: Should be:
   - "mrvl,nfc-uart" for UART devices
   - "mrvl,nfc-i2c" for I2C devices
+  - "mrvl,nfc-spi" for SPI devices
 
 Optional SoC specific properties:
 - pinctrl-names: Contains only one value - "default".
@@ -59,3 +60,27 @@ Example (for ARM-based BeagleBoard Black with 88W8887 on I2C1):
 		reset-n-io = <&gpio3 19 0>;
 	};
 };
+
+
+Example (for ARM-based BeagleBoard Black on SPI0):
+
+&spi0 {
+
+	mrvlnfcspi0: spi@0 {
+		compatible = "mrvl,nfc-spi";
+
+		reg = <0>;
+
+		/* SPI Bus configuration */
+		spi-max-frequency = <3000000>;
+		spi-cpha;
+		spi-cpol;
+
+		/* SPI INT configuration */
+		interrupt-parent = <&gpio1>;
+		interrupts = <17 0>;
+
+		/* Reset IO */
+       		reset-n-io = <&gpio3 19 0>;
+	};
+};
diff --git a/drivers/nfc/nfcmrvl/Kconfig b/drivers/nfc/nfcmrvl/Kconfig
index 77b4725..e0b3d09 100644
--- a/drivers/nfc/nfcmrvl/Kconfig
+++ b/drivers/nfc/nfcmrvl/Kconfig
@@ -44,3 +44,13 @@ config NFC_MRVL_I2C
 	  Say Y here to compile support for Marvell NFC-over-I2C driver
 	  into the kernel or say M to compile it as module.
 
+config NFC_MRVL_SPI
+	tristate "Marvell NFC-over-SPI driver"
+	depends on NFC_MRVL && SPI
+	help
+	  Marvell NFC-over-SPI driver.
+
+	  This driver provides support for Marvell NFC-over-SPI devices.
+
+	  Say Y here to compile support for Marvell NFC-over-SPI driver
+	  into the kernel or say M to compile it as module.
diff --git a/drivers/nfc/nfcmrvl/Makefile b/drivers/nfc/nfcmrvl/Makefile
index 895866a..fa07c78 100644
--- a/drivers/nfc/nfcmrvl/Makefile
+++ b/drivers/nfc/nfcmrvl/Makefile
@@ -13,3 +13,6 @@ obj-$(CONFIG_NFC_MRVL_UART) += nfcmrvl_uart.o
 
 nfcmrvl_i2c-y += i2c.o
 obj-$(CONFIG_NFC_MRVL_I2C) += nfcmrvl_i2c.o
+
+nfcmrvl_spi-y += spi.o
+obj-$(CONFIG_NFC_MRVL_SPI) += nfcmrvl_spi.o
diff --git a/drivers/nfc/nfcmrvl/spi.c b/drivers/nfc/nfcmrvl/spi.c
new file mode 100644
index 0000000..9829e81
--- /dev/null
+++ b/drivers/nfc/nfcmrvl/spi.c
@@ -0,0 +1,242 @@
+/**
+ * Marvell NFC-over-SPI driver: SPI interface related functions
+ *
+ * Copyright (C) 2015, Marvell International Ltd.
+ *
+ * This software file (the "File") is distributed by Marvell International
+ * Ltd. under the terms of the GNU General Public License Version 2, June 1991
+ * (the "License").  You may use, redistribute and/or modify this File in
+ * accordance with the terms and conditions of the License, a copy of which
+ * is available on the worldwide web at
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+ *
+ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
+ * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about
+ * this warranty disclaimer.
+ **/
+
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/pm_runtime.h>
+#include <linux/nfc.h>
+#include <linux/gpio.h>
+#include <linux/of_irq.h>
+#include <linux/of_gpio.h>
+#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
+
+struct nfcmrvl_spi_drv_data {
+	unsigned long flags;
+	struct spi_device *spi;
+	struct nci_spi *nci_spi;
+	struct completion handshake_completion;
+	struct nfcmrvl_private *priv;
+};
+
+static irqreturn_t nfcmrvl_spi_int_irq_thread_fn(int irq, void *drv_data_ptr)
+{
+	struct nfcmrvl_spi_drv_data *drv_data = drv_data_ptr;
+	struct sk_buff *skb;
+
+	/*
+	 * Special case where we are waiting for SPI_INT deassertion to start a
+	 * transfer.
+	 */
+	if (test_and_clear_bit(SPI_WAIT_HANDSHAKE, &drv_data->flags)) {
+		complete(&drv_data->handshake_completion);
+		return IRQ_HANDLED;
+	}
+
+	/* Normal case, SPI_INT deasserted by slave to trigger a master read */
+
+	skb = nci_spi_read(drv_data->nci_spi);
+	if (!skb) {
+		nfc_err(&drv_data->spi->dev, "failed to read spi packet");
+		return IRQ_HANDLED;
+	}
+
+	if (nfcmrvl_nci_recv_frame(drv_data->priv, skb) < 0)
+		nfc_err(&drv_data->spi->dev, "corrupted RX packet");
+
+	return IRQ_HANDLED;
+}
+
+static int nfcmrvl_spi_nci_open(struct nfcmrvl_private *priv)
+{
+	return 0;
+}
+
+static int nfcmrvl_spi_nci_close(struct nfcmrvl_private *priv)
+{
+	return 0;
+}
+
+static int nfcmrvl_spi_nci_send(struct nfcmrvl_private *priv,
+				struct sk_buff *skb)
+{
+	struct nfcmrvl_spi_drv_data *drv_data = priv->drv_data;
+	int err;
+
+	/* Reinit completion for slave handshake */
+	reinit_completion(&drv_data->handshake_completion);
+	set_bit(SPI_WAIT_HANDSHAKE, &drv_data->flags);
+
+	/* Append a dummy byte at the end of SPI frame. This is due to a
+	   specific DMA implementation in the controller */
+	skb_put(skb, 1);
+
+	/* Send the SPI packet */
+	err = nci_spi_send(drv_data->nci_spi, &drv_data->handshake_completion,
+			   skb);
+	if (err != 0) {
+		nfc_err(priv->dev, "spi_send failed %d", err);
+		kfree_skb(skb);
+	}
+	return err;
+}
+
+static void nfcmrvl_spi_nci_update_config(struct nfcmrvl_private *priv,
+					  const void *param)
+{
+	struct nfcmrvl_spi_drv_data *drv_data = priv->drv_data;
+	const struct nfcmrvl_fw_spi_config *config = param;
+
+	drv_data->nci_spi->xfer_speed_hz = config->clk;
+}
+
+static struct nfcmrvl_if_ops spi_ops = {
+	.nci_open = nfcmrvl_spi_nci_open,
+	.nci_close = nfcmrvl_spi_nci_close,
+	.nci_send = nfcmrvl_spi_nci_send,
+	.nci_update_config = nfcmrvl_spi_nci_update_config,
+};
+
+#ifdef CONFIG_OF
+
+static int nfcmrvl_spi_parse_dt(struct device_node *node,
+				struct nfcmrvl_platform_data *pdata)
+{
+	int ret;
+
+	ret = nfcmrvl_parse_dt(node, pdata);
+	if (ret < 0) {
+		pr_err("Failed to get generic entries\n");
+		return ret;
+	}
+
+	ret = irq_of_parse_and_map(node, 0);
+	if (ret < 0) {
+		pr_err("Unable to get irq, error: %d\n", ret);
+		return ret;
+	}
+	pdata->irq = ret;
+
+	return 0;
+}
+
+#else
+
+static int nfcmrvl_spi_parse_dt(struct device_node *node,
+				struct nfcmrvl_platform_data *pdata)
+{
+	return -ENODEV;
+}
+
+#endif
+
+
+static int nfcmrvl_spi_probe(struct spi_device *spi)
+{
+	struct nfcmrvl_platform_data *pdata;
+	struct nfcmrvl_platform_data config;
+	struct nfcmrvl_spi_drv_data *drv_data;
+	int ret = 0;
+
+	drv_data = devm_kzalloc(&spi->dev, sizeof(*drv_data), GFP_KERNEL);
+	if (!drv_data)
+		return -ENOMEM;
+
+	drv_data->spi = spi;
+	drv_data->priv = NULL;
+	spi_set_drvdata(spi, drv_data);
+
+	pdata = spi->dev.platform_data;
+
+	if (!pdata && spi->dev.of_node)
+		if (nfcmrvl_spi_parse_dt(spi->dev.of_node, &config) == 0)
+			pdata = &config;
+
+	if (!pdata)
+		return -EINVAL;
+
+	pdata->phy_headroom = NCI_SPI_HDR_LEN;
+	pdata->phy_tailroom = 1;
+
+	ret = devm_request_threaded_irq(&drv_data->spi->dev, pdata->irq,
+					NULL, nfcmrvl_spi_int_irq_thread_fn,
+					IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
+					"nfcmrvl_spi_int", drv_data);
+	if (ret < 0) {
+		nfc_err(&drv_data->spi->dev, "Unable to register IRQ handler");
+		return -ENODEV;
+	}
+
+	drv_data->priv = nfcmrvl_nci_register_dev(drv_data, &spi_ops,
+						  &drv_data->spi->dev,
+						  pdata);
+	if (IS_ERR(drv_data->priv))
+		return PTR_ERR(drv_data->priv);
+
+	drv_data->priv->phy = NFCMRVL_PHY_SPI;
+	drv_data->priv->support_fw_dnld = true;
+
+	drv_data->nci_spi = nci_spi_allocate_spi(drv_data->spi, 0, 10,
+						 drv_data->priv->ndev);
+
+	/* Init completion for slave handshake */
+	init_completion(&drv_data->handshake_completion);
+	return 0;
+}
+
+static int nfcmrvl_spi_remove(struct spi_device *spi)
+{
+	struct nfcmrvl_spi_drv_data *drv_data = spi_get_drvdata(spi);
+
+	nfcmrvl_nci_unregister_dev(drv_data->priv);
+	return 0;
+}
+
+static const struct of_device_id of_nfcmrvl_spi_match[] = {
+	{ .compatible = "mrvl,nfc-spi", },
+	{},
+};
+MODULE_DEVICE_TABLE(of, of_nfcmrvl_spi_match);
+
+static const struct spi_device_id nfcmrvl_spi_id_table[] = {
+	{ "nfcmrvl_spi", 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(spi, nfcmrvl_spi_id_table);
+
+static struct spi_driver nfcmrvl_spi_driver = {
+	.probe		= nfcmrvl_spi_probe,
+	.remove		= nfcmrvl_spi_remove,
+	.id_table	= nfcmrvl_spi_id_table,
+	.driver		= {
+		.name		= "nfcmrvl_spi",
+		.owner		= THIS_MODULE,
+		.of_match_table	= of_match_ptr(of_nfcmrvl_spi_match),
+	},
+};
+
+module_spi_driver(nfcmrvl_spi_driver);
+
+MODULE_AUTHOR("Marvell International Ltd.");
+MODULE_DESCRIPTION("Marvell NFC-over-SPI driver");
+MODULE_LICENSE("GPL v2");
-- 
2.2.0.33.gc18b867

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH v2 9/9] NFC: nfcmrvl: update device tree bindings for Marvell NFC
       [not found] ` <1443443594-14353-1-git-send-email-cuissard-eYqpPyKDWXRBDgjK7y7TUQ@public.gmane.org>
                     ` (7 preceding siblings ...)
  2015-09-28 12:33   ` [PATCH v2 8/9] NFC: nfcmrvl: add spi driver Vincent Cuissard
@ 2015-09-28 12:33   ` Vincent Cuissard
       [not found]     ` <1443443594-14353-10-git-send-email-cuissard-eYqpPyKDWXRBDgjK7y7TUQ@public.gmane.org>
  8 siblings, 1 reply; 26+ messages in thread
From: Vincent Cuissard @ 2015-09-28 12:33 UTC (permalink / raw)
  To: linux-nfc-hn68Rpc1hR1g9hUCZPvPmw
  Cc: devicetree-u79uwXL29TY76Z2rM5mHXA, Vincent Cuissard

Align NFC bindgins to use marvell instead of mrvl.

Signed-off-by: Vincent Cuissard <cuissard-eYqpPyKDWXRBDgjK7y7TUQ@public.gmane.org>
---
 Documentation/devicetree/bindings/net/nfc/nfcmrvl.txt | 12 ++++++------
 drivers/nfc/nfcmrvl/i2c.c                             |  2 +-
 drivers/nfc/nfcmrvl/spi.c                             |  2 +-
 drivers/nfc/nfcmrvl/uart.c                            |  2 +-
 4 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/Documentation/devicetree/bindings/net/nfc/nfcmrvl.txt b/Documentation/devicetree/bindings/net/nfc/nfcmrvl.txt
index 41058fc..0f95924 100644
--- a/Documentation/devicetree/bindings/net/nfc/nfcmrvl.txt
+++ b/Documentation/devicetree/bindings/net/nfc/nfcmrvl.txt
@@ -2,9 +2,9 @@
 
 Required properties:
 - compatible: Should be:
-  - "mrvl,nfc-uart" for UART devices
-  - "mrvl,nfc-i2c" for I2C devices
-  - "mrvl,nfc-spi" for SPI devices
+  - "marvell,nfc-uart" for UART devices
+  - "marvell,nfc-i2c" for I2C devices
+  - "marvell,nfc-spi" for SPI devices
 
 Optional SoC specific properties:
 - pinctrl-names: Contains only one value - "default".
@@ -28,7 +28,7 @@ Example (for ARM-based BeagleBoard Black with 88W8887 on UART5):
 	status = "okay";
 
 	nfcmrvluart: nfcmrvluart@5 {
-		compatible = "mrvl,nfc-uart";
+		compatible = "marvell,nfc-uart";
 
 		reset-n-io = <&gpio3 16 0>;
 
@@ -45,7 +45,7 @@ Example (for ARM-based BeagleBoard Black with 88W8887 on I2C1):
 	clock-frequency = <400000>;
 
 	nfcmrvli2c0: i2c@1 {
-		compatible = "mrvl,nfc-i2c";
+		compatible = "marvell,nfc-i2c";
 
 		reg = <0x8>;
 
@@ -67,7 +67,7 @@ Example (for ARM-based BeagleBoard Black on SPI0):
 &spi0 {
 
 	mrvlnfcspi0: spi@0 {
-		compatible = "mrvl,nfc-spi";
+		compatible = "marvell,nfc-spi";
 
 		reg = <0>;
 
diff --git a/drivers/nfc/nfcmrvl/i2c.c b/drivers/nfc/nfcmrvl/i2c.c
index b48c3ee..aa022e3 100644
--- a/drivers/nfc/nfcmrvl/i2c.c
+++ b/drivers/nfc/nfcmrvl/i2c.c
@@ -273,7 +273,7 @@ static int nfcmrvl_i2c_remove(struct i2c_client *client)
 
 
 static const struct of_device_id of_nfcmrvl_i2c_match[] = {
-	{ .compatible = "mrvl,nfc-i2c", },
+	{ .compatible = "marvell,nfc-i2c", },
 	{},
 };
 MODULE_DEVICE_TABLE(of, of_nfcmrvl_i2c_match);
diff --git a/drivers/nfc/nfcmrvl/spi.c b/drivers/nfc/nfcmrvl/spi.c
index 9829e81..ac8fb51 100644
--- a/drivers/nfc/nfcmrvl/spi.c
+++ b/drivers/nfc/nfcmrvl/spi.c
@@ -213,7 +213,7 @@ static int nfcmrvl_spi_remove(struct spi_device *spi)
 }
 
 static const struct of_device_id of_nfcmrvl_spi_match[] = {
-	{ .compatible = "mrvl,nfc-spi", },
+	{ .compatible = "marvell,nfc-spi", },
 	{},
 };
 MODULE_DEVICE_TABLE(of, of_nfcmrvl_spi_match);
diff --git a/drivers/nfc/nfcmrvl/uart.c b/drivers/nfc/nfcmrvl/uart.c
index b851334..bb1d363 100644
--- a/drivers/nfc/nfcmrvl/uart.c
+++ b/drivers/nfc/nfcmrvl/uart.c
@@ -75,7 +75,7 @@ static int nfcmrvl_uart_parse_dt(struct device_node *node,
 	struct device_node *matched_node;
 	int ret;
 
-	matched_node = of_find_compatible_node(node, NULL, "mrvl,nfc-uart");
+	matched_node = of_find_compatible_node(node, NULL, "marvell,nfc-uart");
 	if (!matched_node)
 		return -ENODEV;
 
-- 
2.2.0.33.gc18b867

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* Re: [linux-nfc] [PATCH v2 9/9] NFC: nfcmrvl: update device tree bindings for Marvell NFC
       [not found]     ` <1443443594-14353-10-git-send-email-cuissard-eYqpPyKDWXRBDgjK7y7TUQ@public.gmane.org>
@ 2015-10-21  5:57       ` Samuel Ortiz
       [not found]         ` <20151021055734.GD11271-nKCvNrh56OoJmsy6czSMtA@public.gmane.org>
  0 siblings, 1 reply; 26+ messages in thread
From: Samuel Ortiz @ 2015-10-21  5:57 UTC (permalink / raw)
  To: Vincent Cuissard
  Cc: linux-nfc-hn68Rpc1hR1g9hUCZPvPmw, devicetree-u79uwXL29TY76Z2rM5mHXA

Hi Vincent,

On Mon, Sep 28, 2015 at 02:33:14PM +0200, Vincent Cuissard wrote:
> diff --git a/drivers/nfc/nfcmrvl/i2c.c b/drivers/nfc/nfcmrvl/i2c.c
> index b48c3ee..aa022e3 100644
> --- a/drivers/nfc/nfcmrvl/i2c.c
> +++ b/drivers/nfc/nfcmrvl/i2c.c
> @@ -273,7 +273,7 @@ static int nfcmrvl_i2c_remove(struct i2c_client *client)
>  
>  
>  static const struct of_device_id of_nfcmrvl_i2c_match[] = {
> -	{ .compatible = "mrvl,nfc-i2c", },
> +	{ .compatible = "marvell,nfc-i2c", },
You can't just replace the old one with the new one as we already
released kernels with the old compatible string. This is an ABI and we
have to be backward compatible.
Please keep both strings.

Cheers,
Samuel.
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [linux-nfc] [PATCH v2 2/9] NFC: NCI: export nci_send_frame function
       [not found]     ` <1443443594-14353-3-git-send-email-cuissard-eYqpPyKDWXRBDgjK7y7TUQ@public.gmane.org>
@ 2015-10-21  5:57       ` Samuel Ortiz
       [not found]         ` <20151021055750.GE11271-nKCvNrh56OoJmsy6czSMtA@public.gmane.org>
  0 siblings, 1 reply; 26+ messages in thread
From: Samuel Ortiz @ 2015-10-21  5:57 UTC (permalink / raw)
  To: Vincent Cuissard
  Cc: linux-nfc-hn68Rpc1hR1g9hUCZPvPmw, devicetree-u79uwXL29TY76Z2rM5mHXA

Hi Vincent,

On Mon, Sep 28, 2015 at 02:33:07PM +0200, Vincent Cuissard wrote:
> Export nci_send_frame symbol to allow drivers to use it.
> This is needed for example if NCI is used during firmware
> download phase.
If what you need is a way to directly send completely custom frames then
I'd prefer that you export a routine that puts such frame on the
cmd_q skb queue and schedule the cmd_work work.

Cheers,
Samuel.
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [linux-nfc] [PATCH v2 3/9] NFC: nfcmrvl: add firmware download support
       [not found]     ` <1443443594-14353-4-git-send-email-cuissard-eYqpPyKDWXRBDgjK7y7TUQ@public.gmane.org>
@ 2015-10-21  6:00       ` Samuel Ortiz
       [not found]         ` <20151021060021.GF11271-nKCvNrh56OoJmsy6czSMtA@public.gmane.org>
  0 siblings, 1 reply; 26+ messages in thread
From: Samuel Ortiz @ 2015-10-21  6:00 UTC (permalink / raw)
  To: Vincent Cuissard
  Cc: linux-nfc-hn68Rpc1hR1g9hUCZPvPmw, devicetree-u79uwXL29TY76Z2rM5mHXA

Hi Vincent,

On Mon, Sep 28, 2015 at 02:33:08PM +0200, Vincent Cuissard wrote:
> +#define NCI_OP_CORE_CONN_CREATE_CMD	nci_opcode_pack(NCI_GID_CORE, 0x04)
> +#define NCI_OP_CORE_CONN_CLOSE_CMD	nci_opcode_pack(NCI_GID_CORE, 0x05)
Those 2 are already defined on net/nfc/nci.h.


> +static int send_cmd(struct nci_dev *ndev, __u16 opcode, __u8 plen,
> +		    void *payload)
> +{
> +	struct nci_ctrl_hdr *hdr;
> +	struct sk_buff *skb;
> +
> +	skb = nci_skb_alloc(ndev, (NCI_CTRL_HDR_SIZE + plen), GFP_KERNEL);
> +	if (!skb) {
> +		pr_err("no memory for command\n");
> +		return -ENOMEM;
> +	}
> +
> +	hdr = (struct nci_ctrl_hdr *) skb_put(skb, NCI_CTRL_HDR_SIZE);
> +	hdr->gid = nci_opcode_gid(opcode);
> +	hdr->oid = nci_opcode_oid(opcode);
> +	hdr->plen = plen;
> +
> +	nci_mt_set((__u8 *)hdr, NCI_MT_CMD_PKT);
> +	nci_pbf_set((__u8 *)hdr, NCI_PBF_LAST);
> +
> +	if (plen)
> +		memcpy(skb_put(skb, plen), payload, plen);
> +
> +	return nci_send_frame(ndev, skb);
> +}
This is nci_send_cmd, please export that one instead.

> +static int process_state_fw_dnld(struct nfcmrvl_private *priv,
> +				 struct sk_buff *skb)
> +{
> +	uint16_t len;
> +	uint16_t comp_len;
> +	struct sk_buff *out_skb;
> +
> +	switch (priv->fw_dnld.substate) {
> +	case SUBSTATE_WAIT_COMMAND:
> +		/* Remove NCI HDR */
> +		skb_pull(skb, 3);
> +		if (skb->data[0] != HELPER_CMD_PACKET_FORMAT || skb->len != 5) {
> +			nfc_err(priv->dev, "bad command");
> +			return -EINVAL;
> +		}
> +		skb_pull(skb, 1);
> +		memcpy(&len, skb->data, 2);
> +		skb_pull(skb, 2);
> +		memcpy(&comp_len, skb->data, 2);
> +		skb_pull(skb, 2);
> +		len = get_unaligned_le16(&len);
> +		comp_len = get_unaligned_le16(&comp_len);
This sequence would probably look better with some comments on the frame
format you're expecting to get.

> +static void fw_dnld_rx_work(struct work_struct *work)
> +{
> +	int ret;
> +	struct sk_buff *skb;
> +	struct nfcmrvl_fw_dnld *fw_dnld = container_of(work,
> +						       struct nfcmrvl_fw_dnld,
> +						       rx_work);
> +	struct nfcmrvl_private *priv = container_of(fw_dnld,
> +						    struct nfcmrvl_private,
> +						    fw_dnld);
> +
> +	while ((skb = skb_dequeue(&fw_dnld->rx_q))) {
> +		nfc_send_to_raw_sock(priv->ndev->nfc_dev, skb,
> +				     RAW_PAYLOAD_NCI, NFC_DIRECTION_RX);
> +		switch (fw_dnld->state) {
> +		case STATE_RESET:
> +			ret = process_state_reset(priv, skb);
> +			break;
> +		case STATE_INIT:
> +			ret = process_state_init(priv, skb);
> +			break;
> +		case STATE_SET_REF_CLOCK:
> +			ret = process_state_set_ref_clock(priv, skb);
> +			break;
> +		case STATE_SET_HI_CONFIG:
> +			ret = process_state_set_hi_config(priv, skb);
> +			break;
> +		case STATE_OPEN_LC:
> +			ret = process_state_open_lc(priv, skb);
> +			break;
> +		case STATE_FW_DNLD:
> +			ret = process_state_fw_dnld(priv, skb);
> +			break;
> +		case STATE_CLOSE_LC:
> +			ret = process_state_close_lc(priv, skb);
> +			break;
> +		case STATE_BOOT:
> +			ret = process_state_boot(priv, skb);
> +			break;
> +		default:
> +			ret = -EFAULT;
> +		}
As part of the Fields Peak patchset, Robert is allowing drivers to
define hooks for core NCI ops (patch #4/9). Together with the already
existing hooks for proprietary ops, wouldn't that cover the state
machine below, and thus allowing you to reuse the existing
nci_recv_frame for your firmware downloading code ?

> +int nfcmrvl_fw_dnld_start(struct nci_dev *ndev, const char *firmware_name)
> +{
> +	struct nfcmrvl_private *priv = nci_get_drvdata(ndev);
> +	struct nfcmrvl_fw_dnld *fw_dnld = &priv->fw_dnld;
> +
> +	if (!priv->support_fw_dnld)
> +		return -ENOTSUPP;
> +
> +	if (!firmware_name || !firmware_name[0])
> +		return -EINVAL;
> +
> +	strcpy(fw_dnld->name, firmware_name);
> +
> +	/*
> +	 * Retrieve FW binary file and parse it to initialize FW download
> +	 * state machine.
> +	 */
> +
> +	/* Retrieve FW binary */
> +	if (request_firmware(&fw_dnld->fw, firmware_name, priv->dev) < 0) {
> +		nfc_err(priv->dev, "failed to retrieve FW %s", firmware_name);
> +		return -ENOENT;
> +	}
> +
> +	fw_dnld->header = (const struct nfcmrvl_fw *) priv->fw_dnld.fw->data;
> +
> +	if (fw_dnld->header->magic != NFCMRVL_FW_MAGIC ||
> +	    fw_dnld->header->phy != priv->phy) {
> +		nfc_err(priv->dev, "bad firmware binary %s magic=0x%x phy=%d",
> +			firmware_name, fw_dnld->header->magic,
> +			fw_dnld->header->phy);
> +		release_firmware(fw_dnld->fw);
> +		fw_dnld->header = NULL;
> +		return -EINVAL;
> +	}
> +
> +	if (fw_dnld->header->helper.offset != 0) {
> +		nfc_info(priv->dev, "loading helper");
> +		fw_dnld->binary_config = &fw_dnld->header->helper;
> +	} else {
> +		nfc_info(priv->dev, "loading firmware");
> +		fw_dnld->binary_config = &fw_dnld->header->firmware;
> +	}
> +
> +	/* Configure a timer for timeout */
> +	setup_timer(&priv->fw_dnld.timer, fw_dnld_timeout,
> +		    (unsigned long) priv);
> +	mod_timer(&priv->fw_dnld.timer,
> +		  jiffies + msecs_to_jiffies(FW_DNLD_TIMEOUT));
> +
> +	/* Ronfigure HI to be sure that it is the bootrom values */
Reconfigure ?

> +#define NCI_OP_BOOT_CMD			0x3A
You might want to prefix your proprietary commands.

> +enum nfcmrvl_phy {
> +	NFCMRVL_PHY_USB		= 0,
> +	NFCMRVL_PHY_UART	= 1,
> +	NFCMRVL_PHY_I2C		= 2,
> +	NFCMRVL_PHY_SPI		= 3,
> +};
Why is that part of the fw_dld header ?

> @@ -185,6 +202,11 @@ int nfcmrvl_nci_recv_frame(struct nfcmrvl_private *priv, struct sk_buff *skb)
>  		}
>  	}
>  
> +	if (priv->ndev->nfc_dev->fw_download_in_progress) {
Who's setting that flag to true ?

Cheers,
Samuel.
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [linux-nfc] [PATCH v2 4/9] NFC: nfcmrvl: allow low level drivers to configure head/tail room
       [not found]     ` <1443443594-14353-5-git-send-email-cuissard-eYqpPyKDWXRBDgjK7y7TUQ@public.gmane.org>
@ 2015-10-21  6:00       ` Samuel Ortiz
       [not found]         ` <20151021060030.GG11271-nKCvNrh56OoJmsy6czSMtA@public.gmane.org>
  0 siblings, 1 reply; 26+ messages in thread
From: Samuel Ortiz @ 2015-10-21  6:00 UTC (permalink / raw)
  To: Vincent Cuissard
  Cc: linux-nfc-hn68Rpc1hR1g9hUCZPvPmw, devicetree-u79uwXL29TY76Z2rM5mHXA

Hi Vincent,

On Mon, Sep 28, 2015 at 02:33:09PM +0200, Vincent Cuissard wrote:
> diff --git a/include/linux/platform_data/nfcmrvl.h b/include/linux/platform_data/nfcmrvl.h
> index ac91707..6f6ba27 100644
> --- a/include/linux/platform_data/nfcmrvl.h
> +++ b/include/linux/platform_data/nfcmrvl.h
> @@ -26,6 +26,9 @@ struct nfcmrvl_platform_data {
>  	unsigned int reset_n_io;
>  	/* Tell if transport is muxed in HCI one */
>  	unsigned int hci_muxed;
> +	/* Tell generic driver that the PHY requires some headroom space */
> +	unsigned int phy_headroom;
> +	unsigned int phy_tailroom;
This does not seems to be a platform data, but rather a static one that
only depends on the selected PHY.
It would make more sense to pass the selected PHY to
nfcmrvl_nci_register_dev() and define the head and tail room depending
on that.

Cheers,
Samuel.
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [linux-nfc] [PATCH v2 5/9] NFC: nfcmrvl: add i2c driver
       [not found]     ` <1443443594-14353-6-git-send-email-cuissard-eYqpPyKDWXRBDgjK7y7TUQ@public.gmane.org>
@ 2015-10-21  6:00       ` Samuel Ortiz
       [not found]         ` <20151021060047.GH11271-nKCvNrh56OoJmsy6czSMtA@public.gmane.org>
  0 siblings, 1 reply; 26+ messages in thread
From: Samuel Ortiz @ 2015-10-21  6:00 UTC (permalink / raw)
  To: Vincent Cuissard
  Cc: linux-nfc-hn68Rpc1hR1g9hUCZPvPmw, devicetree-u79uwXL29TY76Z2rM5mHXA

Hi Vincent,

On Mon, Sep 28, 2015 at 02:33:10PM +0200, Vincent Cuissard wrote:
> +#ifdef CONFIG_OF
Technically you don't need that as all of_* APIs are safe if CONFIG_OF_*
are not defined.


> +static int nfcmrvl_i2c_parse_dt(struct device_node *node,
> +				struct nfcmrvl_platform_data *pdata)
> +{
> +	int ret;
> +
> +	ret = nfcmrvl_parse_dt(node, pdata);
> +	if (ret < 0) {
> +		pr_err("Failed to get generic entries\n");
> +		return ret;
> +	}
> +
> +	if (of_find_property(node, "i2c-int-falling", NULL))
> +		pdata->irq_polarity = IRQF_TRIGGER_FALLING;
> +	else
> +		pdata->irq_polarity = IRQF_TRIGGER_RISING;
> +
> +	ret = irq_of_parse_and_map(node, 0);
> +	if (ret < 0) {
> +		pr_err("Unable to get irq, error: %d\n", ret);
> +		return ret;
> +	}
> +	pdata->irq = ret;
> +
> +	return 0;
> +}
> +
> +#else
> +
> +static int nfcmrvl_i2c_parse_dt(struct device_node *node,
> +				struct nfcmrvl_platform_data *pdata)
> +{
> +	return -ENODEV;
> +}
> +
> +#endif


> diff --git a/drivers/nfc/nfcmrvl/main.c b/drivers/nfc/nfcmrvl/main.c
> index bd8db3d..1104fa3 100644
> --- a/drivers/nfc/nfcmrvl/main.c
> +++ b/drivers/nfc/nfcmrvl/main.c
> @@ -33,6 +33,9 @@ static int nfcmrvl_nci_open(struct nci_dev *ndev)
>  	if (test_and_set_bit(NFCMRVL_NCI_RUNNING, &priv->flags))
>  		return 0;
>  
> +	/* Reset possible fault of previous session */
> +	clear_bit(NFCMRVL_PHY_ERROR, &priv->flags);
> +
How is that related to this i2c driver ?

>  	err = priv->if_ops->nci_open(priv);
>  
>  	if (err)
> @@ -221,10 +224,8 @@ EXPORT_SYMBOL_GPL(nfcmrvl_nci_recv_frame);
>  
>  void nfcmrvl_chip_reset(struct nfcmrvl_private *priv)
>  {
> -	/*
> -	 * This function does not take care if someone is using the device.
> -	 * To be improved.
> -	 */
> +	/* Reset possible fault of previous session */
> +	clear_bit(NFCMRVL_PHY_ERROR, &priv->flags);
Ditto.

Cheers,
Samuel.
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [linux-nfc] [PATCH v2 2/9] NFC: NCI: export nci_send_frame function
       [not found]         ` <20151021055750.GE11271-nKCvNrh56OoJmsy6czSMtA@public.gmane.org>
@ 2015-10-21  8:22           ` Vincent Cuissard
       [not found]             ` <DFA9399D-2B41-4EE2-831F-DB7011AB1127-eYqpPyKDWXRBDgjK7y7TUQ@public.gmane.org>
  0 siblings, 1 reply; 26+ messages in thread
From: Vincent Cuissard @ 2015-10-21  8:22 UTC (permalink / raw)
  To: Samuel Ortiz
  Cc: linux-nfc-hn68Rpc1hR1g9hUCZPvPmw, devicetree-u79uwXL29TY76Z2rM5mHXA

Hi Samuel,



-- 
Vincent Cuissard

> Le 21 oct. 2015 à 07:57, Samuel Ortiz <sameo-VuQAYsv1563Yd54FQh9/CA@public.gmane.org> a écrit :
> 
> Hi Vincent,
> 
>> On Mon, Sep 28, 2015 at 02:33:07PM +0200, Vincent Cuissard wrote:
>> Export nci_send_frame symbol to allow drivers to use it.
>> This is needed for example if NCI is used during firmware
>> download phase.
> If what you need is a way to directly send completely custom frames then
> I'd prefer that you export a routine that puts such frame on the
> cmd_q skb queue and schedule the cmd_work work.

I need this to send frames over our proprietary logical connection for fw download.

I will check if I can use the conn create and nci_send_frame instead.

Br,
-- 
Vincent--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [linux-nfc] [PATCH v2 3/9] NFC: nfcmrvl: add firmware download support
       [not found]         ` <20151021060021.GF11271-nKCvNrh56OoJmsy6czSMtA@public.gmane.org>
@ 2015-10-21  8:48           ` Vincent Cuissard
       [not found]             ` <5B945DE3-A26C-4E4B-B1B6-DF52BEA0A567-eYqpPyKDWXRBDgjK7y7TUQ@public.gmane.org>
  0 siblings, 1 reply; 26+ messages in thread
From: Vincent Cuissard @ 2015-10-21  8:48 UTC (permalink / raw)
  To: Samuel Ortiz
  Cc: linux-nfc-hn68Rpc1hR1g9hUCZPvPmw, devicetree-u79uwXL29TY76Z2rM5mHXA

Hi Samuel,


> Le 21 oct. 2015 à 08:00, Samuel Ortiz <sameo-VuQAYsv1563Yd54FQh9/CA@public.gmane.org> a écrit 
> 
>> On Mon, Sep 28, 2015 at 02:33:08PM +0200, Vincent Cuissard wrote:
>> +#define NCI_OP_CORE_CONN_CREATE_CMD    nci_opcode_pack(NCI_GID_CORE, 0x04)
>> +#define NCI_OP_CORE_CONN_CLOSE_CMD    nci_opcode_pack(NCI_GID_CORE, 0x05)
> Those 2 are already defined on net/nfc/nci.h.

Ok.

>> +static int send_cmd(struct nci_dev *ndev, __u16 opcode, __u8 plen,
>> +            void *payload)
>> +{
>> +    struct nci_ctrl_hdr *hdr;
>> +    struct sk_buff *skb;
>> +
>> +    skb = nci_skb_alloc(ndev, (NCI_CTRL_HDR_SIZE + plen), GFP_KERNEL);
>> +    if (!skb) {
>> +        pr_err("no memory for command\n");
>> +        return -ENOMEM;
>> +    }
>> +
>> +    hdr = (struct nci_ctrl_hdr *) skb_put(skb, NCI_CTRL_HDR_SIZE);
>> +    hdr->gid = nci_opcode_gid(opcode);
>> +    hdr->oid = nci_opcode_oid(opcode);
>> +    hdr->plen = plen;
>> +
>> +    nci_mt_set((__u8 *)hdr, NCI_MT_CMD_PKT);
>> +    nci_pbf_set((__u8 *)hdr, NCI_PBF_LAST);
>> +
>> +    if (plen)
>> +        memcpy(skb_put(skb, plen), payload, plen);
>> +
>> +    return nci_send_frame(ndev, skb);
>> +}
> This is nci_send_cmd, please export that one instead.

I will check that there is no side effect to use the cmd_queue. FW download is done before any NCI initialization so I need to be sure that there is no dependency to use this API.

>> +static int process_state_fw_dnld(struct nfcmrvl_private *priv,
>> +                 struct sk_buff *skb)
>> +{
>> +    uint16_t len;
>> +    uint16_t comp_len;
>> +    struct sk_buff *out_skb;
>> +
>> +    switch (priv->fw_dnld.substate) {
>> +    case SUBSTATE_WAIT_COMMAND:
>> +        /* Remove NCI HDR */
>> +        skb_pull(skb, 3);
>> +        if (skb->data[0] != HELPER_CMD_PACKET_FORMAT || skb->len != 5) {
>> +            nfc_err(priv->dev, "bad command");
>> +            return -EINVAL;
>> +        }
>> +        skb_pull(skb, 1);
>> +        memcpy(&len, skb->data, 2);
>> +        skb_pull(skb, 2);
>> +        memcpy(&comp_len, skb->data, 2);
>> +        skb_pull(skb, 2);
>> +        len = get_unaligned_le16(&len);
>> +        comp_len = get_unaligned_le16(&comp_len);
> This sequence would probably look better with some comments on the frame
> format you're expecting to get.

Ok.

>> +static void fw_dnld_rx_work(struct work_struct *work)
>> +{
>> +    int ret;
>> +    struct sk_buff *skb;
>> +    struct nfcmrvl_fw_dnld *fw_dnld = container_of(work,
>> +                               struct nfcmrvl_fw_dnld,
>> +                               rx_work);
>> +    struct nfcmrvl_private *priv = container_of(fw_dnld,
>> +                            struct nfcmrvl_private,
>> +                            fw_dnld);
>> +
>> +    while ((skb = skb_dequeue(&fw_dnld->rx_q))) {
>> +        nfc_send_to_raw_sock(priv->ndev->nfc_dev, skb,
>> +                     RAW_PAYLOAD_NCI, NFC_DIRECTION_RX);
>> +        switch (fw_dnld->state) {
>> +        case STATE_RESET:
>> +            ret = process_state_reset(priv, skb);
>> +            break;
>> +        case STATE_INIT:
>> +            ret = process_state_init(priv, skb);
>> +            break;
>> +        case STATE_SET_REF_CLOCK:
>> +            ret = process_state_set_ref_clock(priv, skb);
>> +            break;
>> +        case STATE_SET_HI_CONFIG:
>> +            ret = process_state_set_hi_config(priv, skb);
>> +            break;
>> +        case STATE_OPEN_LC:
>> +            ret = process_state_open_lc(priv, skb);
>> +            break;
>> +        case STATE_FW_DNLD:
>> +            ret = process_state_fw_dnld(priv, skb);
>> +            break;
>> +        case STATE_CLOSE_LC:
>> +            ret = process_state_close_lc(priv, skb);
>> +            break;
>> +        case STATE_BOOT:
>> +            ret = process_state_boot(priv, skb);
>> +            break;
>> +        default:
>> +            ret = -EFAULT;
>> +        }
> As part of the Fields Peak patchset, Robert is allowing drivers to
> define hooks for core NCI ops (patch #4/9). Together with the already
> existing hooks for proprietary ops, wouldn't that cover the state
> machine below, and thus allowing you to reuse the existing
> nci_recv_frame for your firmware downloading code ?

My understanding of Robert's patches is that a driver can hook the generic code. In my case this is only needed during FW download.

And this state machine is not always based on the received message, it is really based on a given sequence.

So I think this state machine shall be kept.

>> +int nfcmrvl_fw_dnld_start(struct nci_dev *ndev, const char *firmware_name)
>> +{
>> +    struct nfcmrvl_private *priv = nci_get_drvdata(ndev);
>> +    struct nfcmrvl_fw_dnld *fw_dnld = &priv->fw_dnld;
>> +
>> +    if (!priv->support_fw_dnld)
>> +        return -ENOTSUPP;
>> +
>> +    if (!firmware_name || !firmware_name[0])
>> +        return -EINVAL;
>> +
>> +    strcpy(fw_dnld->name, firmware_name);
>> +
>> +    /*
>> +     * Retrieve FW binary file and parse it to initialize FW download
>> +     * state machine.
>> +     */
>> +
>> +    /* Retrieve FW binary */
>> +    if (request_firmware(&fw_dnld->fw, firmware_name, priv->dev) < 0) {
>> +        nfc_err(priv->dev, "failed to retrieve FW %s", firmware_name);
>> +        return -ENOENT;
>> +    }
>> +
>> +    fw_dnld->header = (const struct nfcmrvl_fw *) priv->fw_dnld.fw->data;
>> +
>> +    if (fw_dnld->header->magic != NFCMRVL_FW_MAGIC ||
>> +        fw_dnld->header->phy != priv->phy) {
>> +        nfc_err(priv->dev, "bad firmware binary %s magic=0x%x phy=%d",
>> +            firmware_name, fw_dnld->header->magic,
>> +            fw_dnld->header->phy);
>> +        release_firmware(fw_dnld->fw);
>> +        fw_dnld->header = NULL;
>> +        return -EINVAL;
>> +    }
>> +
>> +    if (fw_dnld->header->helper.offset != 0) {
>> +        nfc_info(priv->dev, "loading helper");
>> +        fw_dnld->binary_config = &fw_dnld->header->helper;
>> +    } else {
>> +        nfc_info(priv->dev, "loading firmware");
>> +        fw_dnld->binary_config = &fw_dnld->header->firmware;
>> +    }
>> +
>> +    /* Configure a timer for timeout */
>> +    setup_timer(&priv->fw_dnld.timer, fw_dnld_timeout,
>> +            (unsigned long) priv);
>> +    mod_timer(&priv->fw_dnld.timer,
>> +          jiffies + msecs_to_jiffies(FW_DNLD_TIMEOUT));
>> +
>> +    /* Ronfigure HI to be sure that it is the bootrom values */
> Reconfigure ?

Yes. Depending on the host interface used, fw download code can update interface rate to speed up the fw download and return back to a lower rate for power consumption.

This code is to ensure that at the beginning the right rate is used.

>> +#define NCI_OP_BOOT_CMD            0x3A
> You might want to prefix your proprietary commands.

Ok.

>> +enum nfcmrvl_phy {
>> +    NFCMRVL_PHY_USB        = 0,
>> +    NFCMRVL_PHY_UART    = 1,
>> +    NFCMRVL_PHY_I2C        = 2,
>> +    NFCMRVL_PHY_SPI        = 3,
>> +};
> Why is that part of the fw_dld header ?

Because this information is given by the FW header inside the firmware binary. This is used to ensure that the firmaware used was configured for the current phy interface.

>> @@ -185,6 +202,11 @@ int nfcmrvl_nci_recv_frame(struct nfcmrvl_private *priv, struct sk_buff *skb)
>>        }
>>    }
>> 
>> +    if (priv->ndev->nfc_dev->fw_download_in_progress) {
> Who's setting that flag to true ?

This is done by core code (check nfc_fw_download function in net/nfc/core.c).

Br,
-- 
Vincent--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [linux-nfc] [PATCH v2 4/9] NFC: nfcmrvl: allow low level drivers to configure head/tail room
       [not found]         ` <20151021060030.GG11271-nKCvNrh56OoJmsy6czSMtA@public.gmane.org>
@ 2015-10-21  8:49           ` Vincent Cuissard
  0 siblings, 0 replies; 26+ messages in thread
From: Vincent Cuissard @ 2015-10-21  8:49 UTC (permalink / raw)
  To: Samuel Ortiz
  Cc: linux-nfc-hn68Rpc1hR1g9hUCZPvPmw, devicetree-u79uwXL29TY76Z2rM5mHXA

Hi Samuel,

> Le 21 oct. 2015 à 08:00, Samuel Ortiz <sameo-VuQAYsv1563Yd54FQh9/CA@public.gmane.org> a écrit :
> 
> Hi Vincent,
> 
>> On Mon, Sep 28, 2015 at 02:33:09PM +0200, Vincent Cuissard wrote:
>> diff --git a/include/linux/platform_data/nfcmrvl.h b/include/linux/platform_data/nfcmrvl.h
>> index ac91707..6f6ba27 100644
>> --- a/include/linux/platform_data/nfcmrvl.h
>> +++ b/include/linux/platform_data/nfcmrvl.h
>> @@ -26,6 +26,9 @@ struct nfcmrvl_platform_data {
>>    unsigned int reset_n_io;
>>    /* Tell if transport is muxed in HCI one */
>>    unsigned int hci_muxed;
>> +    /* Tell generic driver that the PHY requires some headroom space */
>> +    unsigned int phy_headroom;
>> +    unsigned int phy_tailroom;
> This does not seems to be a platform data, but rather a static one that
> only depends on the selected PHY.
> It would make more sense to pass the selected PHY to
> nfcmrvl_nci_register_dev() and define the head and tail room depending
> on that.

Ok.

Br,
-- 
Vincent--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [linux-nfc] [PATCH v2 5/9] NFC: nfcmrvl: add i2c driver
       [not found]         ` <20151021060047.GH11271-nKCvNrh56OoJmsy6czSMtA@public.gmane.org>
@ 2015-10-21  8:54           ` Vincent Cuissard
       [not found]             ` <EF5A5C37-4C16-49A6-BF4E-1894C22CC111-eYqpPyKDWXRBDgjK7y7TUQ@public.gmane.org>
  0 siblings, 1 reply; 26+ messages in thread
From: Vincent Cuissard @ 2015-10-21  8:54 UTC (permalink / raw)
  To: Samuel Ortiz
  Cc: linux-nfc-hn68Rpc1hR1g9hUCZPvPmw, devicetree-u79uwXL29TY76Z2rM5mHXA

Hi Samuel,

> Le 21 oct. 2015 à 08:00, Samuel Ortiz <sameo-VuQAYsv1563Yd54FQh9/CA@public.gmane.org> a écrit :
> 
> Hi Vincent,
> 
>> On Mon, Sep 28, 2015 at 02:33:10PM +0200, Vincent Cuissard wrote:
>> +#ifdef CONFIG_OF
> Technically you don't need that as all of_* APIs are safe if CONFIG_OF_*
> are not defined.

Ok.

>> diff --git a/drivers/nfc/nfcmrvl/main.c b/drivers/nfc/nfcmrvl/main.c
>> index bd8db3d..1104fa3 100644
>> --- a/drivers/nfc/nfcmrvl/main.c
>> +++ b/drivers/nfc/nfcmrvl/main.c
>> @@ -33,6 +33,9 @@ static int nfcmrvl_nci_open(struct nci_dev *ndev)
>>    if (test_and_set_bit(NFCMRVL_NCI_RUNNING, &priv->flags))
>>        return 0;
>> 
>> +    /* Reset possible fault of previous session */
>> +    clear_bit(NFCMRVL_PHY_ERROR, &priv->flags);
>> +
> How is that related to this i2c driver ?

i2c driver is currently the only deiver that needs to set this error. But in the future other interfaces may need it too. That's why this clear code was done in the main file to allow future code reuse.

>>    err = priv->if_ops->nci_open(priv);
>> 
>>    if (err)
>> @@ -221,10 +224,8 @@ EXPORT_SYMBOL_GPL(nfcmrvl_nci_recv_frame);
>> 
>> void nfcmrvl_chip_reset(struct nfcmrvl_private *priv)
>> {
>> -    /*
>> -     * This function does not take care if someone is using the device.
>> -     * To be improved.
>> -     */
>> +    /* Reset possible fault of previous session */
>> +    clear_bit(NFCMRVL_PHY_ERROR, &priv->flags);

Same.

Br,
-- 
Vincent--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [linux-nfc] [PATCH v2 9/9] NFC: nfcmrvl: update device tree bindings for Marvell NFC
       [not found]         ` <20151021055734.GD11271-nKCvNrh56OoJmsy6czSMtA@public.gmane.org>
@ 2015-10-21  8:55           ` Vincent Cuissard
  2015-10-23 12:25           ` Vincent Cuissard
  1 sibling, 0 replies; 26+ messages in thread
From: Vincent Cuissard @ 2015-10-21  8:55 UTC (permalink / raw)
  To: Samuel Ortiz
  Cc: linux-nfc-hn68Rpc1hR1g9hUCZPvPmw, devicetree-u79uwXL29TY76Z2rM5mHXA

Hi Samuel,

> Le 21 oct. 2015 à 07:58, Samuel Ortiz <sameo-VuQAYsv1563Yd54FQh9/CA@public.gmane.org> a écrit :
> 
> Hi Vincent,
> 
>> On Mon, Sep 28, 2015 at 02:33:14PM +0200, Vincent Cuissard wrote:
>> diff --git a/drivers/nfc/nfcmrvl/i2c.c b/drivers/nfc/nfcmrvl/i2c.c
>> index b48c3ee..aa022e3 100644
>> --- a/drivers/nfc/nfcmrvl/i2c.c
>> +++ b/drivers/nfc/nfcmrvl/i2c.c
>> @@ -273,7 +273,7 @@ static int nfcmrvl_i2c_remove(struct i2c_client *client)
>> 
>> 
>> static const struct of_device_id of_nfcmrvl_i2c_match[] = {
>> -    { .compatible = "mrvl,nfc-i2c", },
>> +    { .compatible = "marvell,nfc-i2c", },
> You can't just replace the old one with the new one as we already
> released kernels with the old compatible string. This is an ABI and we
> have to be backward compatible.
> Please keep both strings.

Ok.

Br,
-- 
Vincent--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [linux-nfc] [PATCH v2 2/9] NFC: NCI: export nci_send_frame function
       [not found]             ` <DFA9399D-2B41-4EE2-831F-DB7011AB1127-eYqpPyKDWXRBDgjK7y7TUQ@public.gmane.org>
@ 2015-10-21 22:12               ` Vincent Cuissard
       [not found]                 ` <1CC98D3D-42C1-43A4-87A3-3802863B956A-eYqpPyKDWXRBDgjK7y7TUQ@public.gmane.org>
  0 siblings, 1 reply; 26+ messages in thread
From: Vincent Cuissard @ 2015-10-21 22:12 UTC (permalink / raw)
  To: Samuel Ortiz
  Cc: devicetree-u79uwXL29TY76Z2rM5mHXA, linux-nfc-hn68Rpc1hR1g9hUCZPvPmw

Hi Samuel,

>> Le 21 oct. 2015 à 07:57, Samuel Ortiz <sameo-VuQAYsv1563Yd54FQh9/CA@public.gmane.org> a écrit :
>> 
>> Hi Vincent,
>> 
>>> On Mon, Sep 28, 2015 at 02:33:07PM +0200, Vincent Cuissard wrote:
>>> Export nci_send_frame symbol to allow drivers to use it.
>>> This is needed for example if NCI is used during firmware
>>> download phase.
>> If what you need is a way to directly send completely custom frames then
>> I'd prefer that you export a routine that puts such frame on the
>> cmd_q skb queue and schedule the cmd_work work.
> 
> I need this to send frames over our proprietary logical connection for fw download.
> 
> I will check if I can use the conn create and nci_send_cmd.

I have checked. I should be able to use nci_send_cmd without hacking the whole code. For logical connection I still need nci_send_frame because related APIs are synchrounous and not designed to be used when device is not up. I tried to tweak this but the code became too ugly since in my driver I got to forward some packets to core RX while keeping handling others in my workqueue. The code was really unreadable.

I will send a v3 with nci_send_cmd usage.

BTW, keep in mind that this fw download code is a proprietary protocol based on NCI style frames. I tried to reuse all generic functions but I don't want to complexify the driver and the core part for such proprietary stuff.

Br,
-- 
Vincent--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [linux-nfc] [PATCH v2 2/9] NFC: NCI: export nci_send_frame function
       [not found]                 ` <1CC98D3D-42C1-43A4-87A3-3802863B956A-eYqpPyKDWXRBDgjK7y7TUQ@public.gmane.org>
@ 2015-10-22 15:43                   ` Samuel Ortiz
  0 siblings, 0 replies; 26+ messages in thread
From: Samuel Ortiz @ 2015-10-22 15:43 UTC (permalink / raw)
  To: Vincent Cuissard
  Cc: devicetree-u79uwXL29TY76Z2rM5mHXA, linux-nfc-hn68Rpc1hR1g9hUCZPvPmw

Hi Vincent,

On Wed, Oct 21, 2015 at 10:12:06PM +0000, Vincent Cuissard wrote:
> Hi Samuel,
> 
> >> Le 21 oct. 2015 à 07:57, Samuel Ortiz <sameo-VuQAYsv1563Yd54FQh9/CA@public.gmane.org> a écrit :
> >> 
> >> Hi Vincent,
> >> 
> >>> On Mon, Sep 28, 2015 at 02:33:07PM +0200, Vincent Cuissard wrote:
> >>> Export nci_send_frame symbol to allow drivers to use it.
> >>> This is needed for example if NCI is used during firmware
> >>> download phase.
> >> If what you need is a way to directly send completely custom frames then
> >> I'd prefer that you export a routine that puts such frame on the
> >> cmd_q skb queue and schedule the cmd_work work.
> > 
> > I need this to send frames over our proprietary logical connection for fw download.
> > 
> > I will check if I can use the conn create and nci_send_cmd.
> 
> I have checked. I should be able to use nci_send_cmd without hacking the whole code. For logical connection I still need nci_send_frame because related APIs are synchrounous and not designed to be used when device is not up. I tried to tweak this but the code became too ugly since in my driver I got to forward some packets to core RX while keeping handling others in my workqueue. The code was really unreadable.
> 
> I will send a v3 with nci_send_cmd usage.
> 
> BTW, keep in mind that this fw download code is a proprietary protocol based on NCI style frames. I tried to reuse all generic functions but I don't want to complexify the driver and the core part for such proprietary stuff.
>
Sure. The idea is to make it simpler and less error prone by avoiding
code duplication, not the other way around.

Cheers,
Samuel.
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [linux-nfc] [PATCH v2 3/9] NFC: nfcmrvl: add firmware download support
       [not found]             ` <5B945DE3-A26C-4E4B-B1B6-DF52BEA0A567-eYqpPyKDWXRBDgjK7y7TUQ@public.gmane.org>
@ 2015-10-22 15:43               ` Samuel Ortiz
       [not found]                 ` <20151022154323.GB7633-nKCvNrh56OoJmsy6czSMtA@public.gmane.org>
  0 siblings, 1 reply; 26+ messages in thread
From: Samuel Ortiz @ 2015-10-22 15:43 UTC (permalink / raw)
  To: Vincent Cuissard
  Cc: linux-nfc-hn68Rpc1hR1g9hUCZPvPmw, devicetree-u79uwXL29TY76Z2rM5mHXA

Hi Vincent,

On Wed, Oct 21, 2015 at 08:48:33AM +0000, Vincent Cuissard wrote:
> > As part of the Fields Peak patchset, Robert is allowing drivers to
> > define hooks for core NCI ops (patch #4/9). Together with the already
> > existing hooks for proprietary ops, wouldn't that cover the state
> > machine below, and thus allowing you to reuse the existing
> > nci_recv_frame for your firmware downloading code ?
> 
> My understanding of Robert's patches is that a driver can hook the generic code. In my case this is only needed during FW download.
> 
> And this state machine is not always based on the received message, it is really based on a given sequence.
> 
> So I think this state machine shall be kept.
Ok. I'm fine with it staying as is.

> >> +    /* Ronfigure HI to be sure that it is the bootrom values */
> > Reconfigure ?
> 
> Yes. Depending on the host interface used, fw download code can update interface rate to speed up the fw download and return back to a lower rate for power consumption.
> 
> This code is to ensure that at the beginning the right rate is used.
Thanks for the explanation, I was mostly pointing at the typo.

> >> +enum nfcmrvl_phy {
> >> +    NFCMRVL_PHY_USB        = 0,
> >> +    NFCMRVL_PHY_UART    = 1,
> >> +    NFCMRVL_PHY_I2C        = 2,
> >> +    NFCMRVL_PHY_SPI        = 3,
> >> +};
> > Why is that part of the fw_dld header ?
> 
> Because this information is given by the FW header inside the firmware binary. This is used to ensure that the firmaware used was configured for the current phy interface.
Sure. But can we keep it in the nfcmrvl.h header ?

> >> @@ -185,6 +202,11 @@ int nfcmrvl_nci_recv_frame(struct nfcmrvl_private *priv, struct sk_buff *skb)
> >>        }
> >>    }
> >> 
> >> +    if (priv->ndev->nfc_dev->fw_download_in_progress) {
> > Who's setting that flag to true ?
> 
> This is done by core code (check nfc_fw_download function in net/nfc/core.c).
Duh. Sorry for the brain fart...

Cheers,
Samuel.
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [linux-nfc] [PATCH v2 5/9] NFC: nfcmrvl: add i2c driver
       [not found]             ` <EF5A5C37-4C16-49A6-BF4E-1894C22CC111-eYqpPyKDWXRBDgjK7y7TUQ@public.gmane.org>
@ 2015-10-22 15:43               ` Samuel Ortiz
  0 siblings, 0 replies; 26+ messages in thread
From: Samuel Ortiz @ 2015-10-22 15:43 UTC (permalink / raw)
  To: Vincent Cuissard
  Cc: linux-nfc-hn68Rpc1hR1g9hUCZPvPmw, devicetree-u79uwXL29TY76Z2rM5mHXA

Hi Vincent,

On Wed, Oct 21, 2015 at 08:54:07AM +0000, Vincent Cuissard wrote:
> >> diff --git a/drivers/nfc/nfcmrvl/main.c b/drivers/nfc/nfcmrvl/main.c
> >> index bd8db3d..1104fa3 100644
> >> --- a/drivers/nfc/nfcmrvl/main.c
> >> +++ b/drivers/nfc/nfcmrvl/main.c
> >> @@ -33,6 +33,9 @@ static int nfcmrvl_nci_open(struct nci_dev *ndev)
> >>    if (test_and_set_bit(NFCMRVL_NCI_RUNNING, &priv->flags))
> >>        return 0;
> >> 
> >> +    /* Reset possible fault of previous session */
> >> +    clear_bit(NFCMRVL_PHY_ERROR, &priv->flags);
> >> +
> > How is that related to this i2c driver ?
> 
> i2c driver is currently the only deiver that needs to set this error. But in the future other interfaces may need it too. That's why this clear code was done in the main file to allow future code reuse.
>
Ok. I missed the fact that the i2c driver was actually setting this bit.
Makes sense to me now.

Cheers,
Samuel.
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [linux-nfc] [PATCH v2 3/9] NFC: nfcmrvl: add firmware download support
       [not found]                 ` <20151022154323.GB7633-nKCvNrh56OoJmsy6czSMtA@public.gmane.org>
@ 2015-10-22 19:25                   ` Vincent Cuissard
  0 siblings, 0 replies; 26+ messages in thread
From: Vincent Cuissard @ 2015-10-22 19:25 UTC (permalink / raw)
  To: Samuel Ortiz
  Cc: linux-nfc-hn68Rpc1hR1g9hUCZPvPmw, devicetree-u79uwXL29TY76Z2rM5mHXA

Hi Samuel,

> Le 22 oct. 2015 à 17:44, Samuel Ortiz <sameo-VuQAYsv1563Yd54FQh9/CA@public.gmane.org> a écrit :
> 
...

>>>> +enum nfcmrvl_phy {
>>>> +    NFCMRVL_PHY_USB        = 0,
>>>> +    NFCMRVL_PHY_UART    = 1,
>>>> +    NFCMRVL_PHY_I2C        = 2,
>>>> +    NFCMRVL_PHY_SPI        = 3,
>>>> +};
>>> Why is that part of the fw_dld header ?
>> 
>> Because this information is given by the FW header inside the firmware binary. This is used to ensure that the firmaware used was configured for the current phy interface.
> Sure. But can we keep it in the nfcmrvl.h header ?

Ok.

>>>> @@ -185,6 +202,11 @@ int nfcmrvl_nci_recv_frame(struct nfcmrvl_private *priv, struct sk_buff *skb)
>>>>       }
>>>>   }
>>>> 
>>>> +    if (priv->ndev->nfc_dev->fw_download_in_progress) {
>>> Who's setting that flag to true ?
>> 
>> This is done by core code (check nfc_fw_download function in net/nfc/core.c).
> Duh. Sorry for the brain fart...

No problem

Br,
-- 
Vincent--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [linux-nfc] [PATCH v2 9/9] NFC: nfcmrvl: update device tree bindings for Marvell NFC
       [not found]         ` <20151021055734.GD11271-nKCvNrh56OoJmsy6czSMtA@public.gmane.org>
  2015-10-21  8:55           ` Vincent Cuissard
@ 2015-10-23 12:25           ` Vincent Cuissard
  1 sibling, 0 replies; 26+ messages in thread
From: Vincent Cuissard @ 2015-10-23 12:25 UTC (permalink / raw)
  To: Samuel Ortiz
  Cc: linux-nfc-hn68Rpc1hR1g9hUCZPvPmw, devicetree-u79uwXL29TY76Z2rM5mHXA

Hi Samuel,

> Le 21 oct. 2015 à 07:58, Samuel Ortiz <sameo-VuQAYsv1563Yd54FQh9/CA@public.gmane.org> a écrit :
> 
> Hi Vincent,
> 
>> On Mon, Sep 28, 2015 at 02:33:14PM +0200, Vincent Cuissard wrote:
>> diff --git a/drivers/nfc/nfcmrvl/i2c.c b/drivers/nfc/nfcmrvl/i2c.c
>> index b48c3ee..aa022e3 100644
>> --- a/drivers/nfc/nfcmrvl/i2c.c
>> +++ b/drivers/nfc/nfcmrvl/i2c.c
>> @@ -273,7 +273,7 @@ static int nfcmrvl_i2c_remove(struct i2c_client *client)
>> 
>> 
>> static const struct of_device_id of_nfcmrvl_i2c_match[] = {
>> -    { .compatible = "mrvl,nfc-i2c", },
>> +    { .compatible = "marvell,nfc-i2c", },
> You can't just replace the old one with the new one as we already
> released kernels with the old compatible string. This is an ABI and we
> have to be backward compatible.
> Please keep both strings.

Since this driver is new I finally kept the latest string since it is impossible that someone used it already.

Br,
-- 
Vincent--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 26+ messages in thread

end of thread, other threads:[~2015-10-23 12:25 UTC | newest]

Thread overview: 26+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-09-28 12:33 [PATCH v2 0/9] Marvell NFC drivers for i2c and spi Vincent Cuissard
     [not found] ` <1443443594-14353-1-git-send-email-cuissard-eYqpPyKDWXRBDgjK7y7TUQ@public.gmane.org>
2015-09-28 12:33   ` [PATCH v2 1/9] NFC: nfcmrvl: remove unneeded version defines Vincent Cuissard
2015-09-28 12:33   ` [PATCH v2 2/9] NFC: NCI: export nci_send_frame function Vincent Cuissard
     [not found]     ` <1443443594-14353-3-git-send-email-cuissard-eYqpPyKDWXRBDgjK7y7TUQ@public.gmane.org>
2015-10-21  5:57       ` [linux-nfc] " Samuel Ortiz
     [not found]         ` <20151021055750.GE11271-nKCvNrh56OoJmsy6czSMtA@public.gmane.org>
2015-10-21  8:22           ` Vincent Cuissard
     [not found]             ` <DFA9399D-2B41-4EE2-831F-DB7011AB1127-eYqpPyKDWXRBDgjK7y7TUQ@public.gmane.org>
2015-10-21 22:12               ` Vincent Cuissard
     [not found]                 ` <1CC98D3D-42C1-43A4-87A3-3802863B956A-eYqpPyKDWXRBDgjK7y7TUQ@public.gmane.org>
2015-10-22 15:43                   ` Samuel Ortiz
2015-09-28 12:33   ` [PATCH v2 3/9] NFC: nfcmrvl: add firmware download support Vincent Cuissard
     [not found]     ` <1443443594-14353-4-git-send-email-cuissard-eYqpPyKDWXRBDgjK7y7TUQ@public.gmane.org>
2015-10-21  6:00       ` [linux-nfc] " Samuel Ortiz
     [not found]         ` <20151021060021.GF11271-nKCvNrh56OoJmsy6czSMtA@public.gmane.org>
2015-10-21  8:48           ` Vincent Cuissard
     [not found]             ` <5B945DE3-A26C-4E4B-B1B6-DF52BEA0A567-eYqpPyKDWXRBDgjK7y7TUQ@public.gmane.org>
2015-10-22 15:43               ` Samuel Ortiz
     [not found]                 ` <20151022154323.GB7633-nKCvNrh56OoJmsy6czSMtA@public.gmane.org>
2015-10-22 19:25                   ` Vincent Cuissard
2015-09-28 12:33   ` [PATCH v2 4/9] NFC: nfcmrvl: allow low level drivers to configure head/tail room Vincent Cuissard
     [not found]     ` <1443443594-14353-5-git-send-email-cuissard-eYqpPyKDWXRBDgjK7y7TUQ@public.gmane.org>
2015-10-21  6:00       ` [linux-nfc] " Samuel Ortiz
     [not found]         ` <20151021060030.GG11271-nKCvNrh56OoJmsy6czSMtA@public.gmane.org>
2015-10-21  8:49           ` Vincent Cuissard
2015-09-28 12:33   ` [PATCH v2 5/9] NFC: nfcmrvl: add i2c driver Vincent Cuissard
     [not found]     ` <1443443594-14353-6-git-send-email-cuissard-eYqpPyKDWXRBDgjK7y7TUQ@public.gmane.org>
2015-10-21  6:00       ` [linux-nfc] " Samuel Ortiz
     [not found]         ` <20151021060047.GH11271-nKCvNrh56OoJmsy6czSMtA@public.gmane.org>
2015-10-21  8:54           ` Vincent Cuissard
     [not found]             ` <EF5A5C37-4C16-49A6-BF4E-1894C22CC111-eYqpPyKDWXRBDgjK7y7TUQ@public.gmane.org>
2015-10-22 15:43               ` Samuel Ortiz
2015-09-28 12:33   ` [PATCH v2 6/9] NFC: NCI: move generic spi driver to a module Vincent Cuissard
2015-09-28 12:33   ` [PATCH v2 7/9] NFC: NCI: allow spi driver to choose transfer clock Vincent Cuissard
2015-09-28 12:33   ` [PATCH v2 8/9] NFC: nfcmrvl: add spi driver Vincent Cuissard
2015-09-28 12:33   ` [PATCH v2 9/9] NFC: nfcmrvl: update device tree bindings for Marvell NFC Vincent Cuissard
     [not found]     ` <1443443594-14353-10-git-send-email-cuissard-eYqpPyKDWXRBDgjK7y7TUQ@public.gmane.org>
2015-10-21  5:57       ` [linux-nfc] " Samuel Ortiz
     [not found]         ` <20151021055734.GD11271-nKCvNrh56OoJmsy6czSMtA@public.gmane.org>
2015-10-21  8:55           ` Vincent Cuissard
2015-10-23 12:25           ` Vincent Cuissard

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.