/* -------------------------------------------------------------------------
 * Copyright (C) 2014-2016, Intel Corporation
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 * -------------------------------------------------------------------------
 */

#include <linux/module.h>
#include <linux/nfc.h>
#include <linux/i2c.h>
#include <linux/delay.h>
#include <linux/firmware.h>
#include <net/nfc/nci_core.h>

#include "fdp.h"

#define FDP_OTP_PATCH_NAME			"otp.bin"
#define FDP_RAM_PATCH_NAME			"ram.bin"
#define FDP_FW_HEADER_SIZE			576
#define FDP_FW_UPDATE_SLEEP			1000

#define NCI_GET_VERSION_TIMEOUT			8000
#define NCI_PATCH_REQUEST_TIMEOUT		8000
#define FDP_PATCH_CONN_DEST			0xC2
#define FDP_PATCH_CONN_PARAM_TYPE		0xA0

#define NCI_PATCH_TYPE_RAM			0x00
#define NCI_PATCH_TYPE_OTP			0x01
#define NCI_PATCH_TYPE_EOT			0xFF

#define NCI_PARAM_ID_FW_RAM_VERSION		0xA0
#define NCI_PARAM_ID_FW_OTP_VERSION		0xA1
#define NCI_PARAM_ID_OTP_LIMITED_VERSION	0xC5
#define NCI_PARAM_ID_KEY_INDEX_ID		0xC6

#define NCI_GID_PROP				0x0F
#define NCI_OP_PROP_PATCH_OID			0x08
#define NCI_OP_PROP_SET_PDATA_OID		0x23

struct fdp_nci_info {
	struct nfc_phy_ops *phy_ops;
	struct fdp_i2c_phy *phy;
	struct nci_dev *ndev;

	const struct firmware *otp_patch;
	const struct firmware *ram_patch;
	u32 otp_patch_version;
	u32 ram_patch_version;

	u32 otp_version;
	u32 ram_version;
	u32 limited_otp_version;
	u8 key_index;

	u8 *fw_vsc_cfg;
	u8 clock_type;
	u32 clock_freq;

	atomic_t data_pkt_counter;
	void (*data_pkt_counter_cb)(struct nci_dev *ndev);
	u8 setup_patch_sent;
	u8 setup_patch_ntf;
	u8 setup_patch_status;
	u8 setup_reset_ntf;
	wait_queue_head_t setup_wq;
};

static u8 nci_core_get_config_otp_ram_version[5] = {
	0x04,
	NCI_PARAM_ID_FW_RAM_VERSION,
	NCI_PARAM_ID_FW_OTP_VERSION,
	NCI_PARAM_ID_OTP_LIMITED_VERSION,
	NCI_PARAM_ID_KEY_INDEX_ID
};

struct nci_core_get_config_rsp {
	u8 status;
	u8 count;
	u8 data[0];
};

static int fdp_nci_create_conn(struct nci_dev *ndev)
{
	struct fdp_nci_info *info = nci_get_drvdata(ndev);
	struct core_conn_create_dest_spec_params param;
	int r;

	/* proprietary destination specific paramerer without value */
	param.type = FDP_PATCH_CONN_PARAM_TYPE;
	param.length = 0x00;

	r = nci_core_conn_create(info->ndev, FDP_PATCH_CONN_DEST, 1,
				 sizeof(param), &param);
	if (r)
		return r;

	return nci_get_conn_info_by_dest_type_params(ndev,
						     FDP_PATCH_CONN_DEST, NULL);
}

static inline int fdp_nci_get_versions(struct nci_dev *ndev)
{
	return nci_core_cmd(ndev, NCI_OP_CORE_GET_CONFIG_CMD,
			    sizeof(nci_core_get_config_otp_ram_version),
			    (__u8 *) &nci_core_get_config_otp_ram_version);
}

static inline int fdp_nci_patch_cmd(struct nci_dev *ndev, u8 type)
{
	return nci_prop_cmd(ndev, NCI_OP_PROP_PATCH_OID, sizeof(type), &type);
}

static inline int fdp_nci_set_production_data(struct nci_dev *ndev, u8 len,
					      char *data)
{
	return nci_prop_cmd(ndev, NCI_OP_PROP_SET_PDATA_OID, len, data);
}

static int fdp_nci_set_clock(struct nci_dev *ndev, u8 clock_type,
			     u32 clock_freq)
{
	u32 fc = 13560;
	u32 nd, num, delta;
	char data[9];

	nd = (24 * fc) / clock_freq;
	delta = 24 * fc - nd * clock_freq;
	num = (32768 * delta) / clock_freq;

	data[0] = 0x00;
	data[1] = 0x00;
	data[2] = 0x00;

	data[3] = 0x10;
	data[4] = 0x04;
	data[5] = num & 0xFF;
	data[6] = (num >> 8) & 0xff;
	data[7] = nd;
	data[8] = clock_type;

	return fdp_nci_set_production_data(ndev, 9, data);
}

static void fdp_nci_send_patch_cb(struct nci_dev *ndev)
{
	struct fdp_nci_info *info = nci_get_drvdata(ndev);

	info->setup_patch_sent = 1;
	wake_up(&info->setup_wq);
}

/**
 * Register a packet sent counter and a callback
 *
 * We have no other way of knowing when all firmware packets were sent out
 * on the i2c bus. We need to know that in order to close the connection and
 * send the patch end message.
 */
static void fdp_nci_set_data_pkt_counter(struct nci_dev *ndev,
				  void (*cb)(struct nci_dev *ndev), int count)
{
	struct fdp_nci_info *info = nci_get_drvdata(ndev);
	struct device *dev = &info->phy->i2c_dev->dev;

	dev_dbg(dev, "NCI data pkt counter %d\n", count);
	atomic_set(&info->data_pkt_counter, count);
	info->data_pkt_counter_cb = cb;
}

/**
 * The device is expecting a stream of packets. All packets need to
 * have the PBF flag set to 0x0 (last packet) even if the firmware
 * file is segmented and there are multiple packets. If we give the
 * whole firmware to nci_send_data it will segment it and it will set
 * the PBF flag to 0x01 so we need to do the segmentation here.
 *
 * The firmware will be analyzed and applied when we send NCI_OP_PROP_PATCH_CMD
 * command with NCI_PATCH_TYPE_EOT parameter. The device will send a
 * NFCC_PATCH_NTF packaet and a NCI_OP_CORE_RESET_NTF packet.
 */
static int fdp_nci_send_patch(struct nci_dev *ndev, u8 conn_id, u8 type)
{
	struct fdp_nci_info *info = nci_get_drvdata(ndev);
	const struct firmware *fw;
	struct sk_buff *skb;
	unsigned long len;
	u8 max_size, payload_size;
	int rc = 0;

	if ((type == NCI_PATCH_TYPE_OTP && !info->otp_patch) ||
	    (type == NCI_PATCH_TYPE_RAM && !info->ram_patch))
		return -EINVAL;

	if (type == NCI_PATCH_TYPE_OTP)
		fw = info->otp_patch;
	else
		fw = info->ram_patch;

	max_size = nci_conn_max_data_pkt_payload_size(ndev, conn_id);
	if (max_size <= 0)
		return -EINVAL;

	len = fw->size;

	fdp_nci_set_data_pkt_counter(ndev, fdp_nci_send_patch_cb,
				     DIV_ROUND_UP(fw->size, max_size));

	while (len) {

		payload_size = min_t(unsigned long, (unsigned long) max_size,
				     len);

		skb = nci_skb_alloc(ndev, (NCI_CTRL_HDR_SIZE + payload_size),
				    GFP_KERNEL);
		if (!skb) {
			fdp_nci_set_data_pkt_counter(ndev, NULL, 0);
			return -ENOMEM;
		}


		skb_reserve(skb, NCI_CTRL_HDR_SIZE);

		skb_put_data(skb, fw->data + (fw->size - len), payload_size);

		rc = nci_send_data(ndev, conn_id, skb);

		if (rc) {
			fdp_nci_set_data_pkt_counter(ndev, NULL, 0);
			return rc;
		}

		len -= payload_size;
	}

	return rc;
}

static int fdp_nci_open(struct nci_dev *ndev)
{
	int r;
	struct fdp_nci_info *info = nci_get_drvdata(ndev);
	struct device *dev = &info->phy->i2c_dev->dev;

	dev_dbg(dev, "%s\n", __func__);

	r = info->phy_ops->enable(info->phy);

	return r;
}

static int fdp_nci_close(struct nci_dev *ndev)
{
	struct fdp_nci_info *info = nci_get_drvdata(ndev);
	struct device *dev = &info->phy->i2c_dev->dev;

	dev_dbg(dev, "%s\n", __func__);
	return 0;
}

static int fdp_nci_send(struct nci_dev *ndev, struct sk_buff *skb)
{
	struct fdp_nci_info *info = nci_get_drvdata(ndev);
	struct device *dev = &info->phy->i2c_dev->dev;

	dev_dbg(dev, "%s\n", __func__);

	if (atomic_dec_and_test(&info->data_pkt_counter))
		info->data_pkt_counter_cb(ndev);

	return info->phy_ops->write(info->phy, skb);
}

int fdp_nci_recv_frame(struct nci_dev *ndev, struct sk_buff *skb)
{
	struct fdp_nci_info *info = nci_get_drvdata(ndev);
	struct device *dev = &info->phy->i2c_dev->dev;

	dev_dbg(dev, "%s\n", __func__);
	return nci_recv_frame(ndev, skb);
}
EXPORT_SYMBOL(fdp_nci_recv_frame);

static int fdp_nci_request_firmware(struct nci_dev *ndev)
{
	struct fdp_nci_info *info = nci_get_drvdata(ndev);
	struct device *dev = &info->phy->i2c_dev->dev;
	u8 *data;
	int r;

	r = request_firmware(&info->ram_patch, FDP_RAM_PATCH_NAME, dev);
	if (r < 0) {
		nfc_err(dev, "RAM patch request error\n");
		goto error;
	}

	data = (u8 *) info->ram_patch->data;
	info->ram_patch_version =
		data[FDP_FW_HEADER_SIZE] |
		(data[FDP_FW_HEADER_SIZE + 1] << 8) |
		(data[FDP_FW_HEADER_SIZE + 2] << 16) |
		(data[FDP_FW_HEADER_SIZE + 3] << 24);

	dev_dbg(dev, "RAM patch version: %d, size: %d\n",
		  info->ram_patch_version, (int) info->ram_patch->size);


	r = request_firmware(&info->otp_patch, FDP_OTP_PATCH_NAME, dev);
	if (r < 0) {
		nfc_err(dev, "OTP patch request error\n");
		goto out;
	}

	data = (u8 *) info->otp_patch->data;
	info->otp_patch_version =
		data[FDP_FW_HEADER_SIZE] |
		(data[FDP_FW_HEADER_SIZE + 1] << 8) |
		(data[FDP_FW_HEADER_SIZE+2] << 16) |
		(data[FDP_FW_HEADER_SIZE+3] << 24);

	dev_dbg(dev, "OTP patch version: %d, size: %d\n",
		 info->otp_patch_version, (int) info->otp_patch->size);
out:
	return 0;
error:
	return r;
}

static void fdp_nci_release_firmware(struct nci_dev *ndev)
{
	struct fdp_nci_info *info = nci_get_drvdata(ndev);

	if (info->otp_patch) {
		release_firmware(info->otp_patch);
		info->otp_patch = NULL;
	}

	if (info->ram_patch) {
		release_firmware(info->ram_patch);
		info->ram_patch = NULL;
	}
}

static int fdp_nci_patch_otp(struct nci_dev *ndev)
{
	struct fdp_nci_info *info = nci_get_drvdata(ndev);
	struct device *dev = &info->phy->i2c_dev->dev;
	int conn_id;
	int r = 0;

	if (info->otp_version >= info->otp_patch_version)
		goto out;

	info->setup_patch_sent = 0;
	info->setup_reset_ntf = 0;
	info->setup_patch_ntf = 0;

	/* Patch init request */
	r = fdp_nci_patch_cmd(ndev, NCI_PATCH_TYPE_OTP);
	if (r)
		goto out;

	/* Patch data connection creation */
	conn_id = fdp_nci_create_conn(ndev);
	if (conn_id < 0) {
		r = conn_id;
		goto out;
	}

	/* Send the patch over the data connection */
	r = fdp_nci_send_patch(ndev, conn_id, NCI_PATCH_TYPE_OTP);
	if (r)
		goto out;

	/* Wait for all the packets to be send over i2c */
	wait_event_interruptible(info->setup_wq,
				 info->setup_patch_sent == 1);

	/* make sure that the NFCC processed the last data packet */
	msleep(FDP_FW_UPDATE_SLEEP);

	/* Close the data connection */
	r = nci_core_conn_close(info->ndev, conn_id);
	if (r)
		goto out;

	/* Patch finish message */
	if (fdp_nci_patch_cmd(ndev, NCI_PATCH_TYPE_EOT)) {
		nfc_err(dev, "OTP patch error 0x%x\n", r);
		r = -EINVAL;
		goto out;
	}

	/* If the patch notification didn't arrive yet, wait for it */
	wait_event_interruptible(info->setup_wq, info->setup_patch_ntf);

	/* Check if the patching was successful */
	r = info->setup_patch_status;
	if (r) {
		nfc_err(dev, "OTP patch error 0x%x\n", r);
		r = -EINVAL;
		goto out;
	}

	/*
	 * We need to wait for the reset notification before we
	 * can continue
	 */
	wait_event_interruptible(info->setup_wq, info->setup_reset_ntf);

out:
	return r;
}

static int fdp_nci_patch_ram(struct nci_dev *ndev)
{
	struct fdp_nci_info *info = nci_get_drvdata(ndev);
	struct device *dev = &info->phy->i2c_dev->dev;
	int conn_id;
	int r = 0;

	if (info->ram_version >= info->ram_patch_version)
		goto out;

	info->setup_patch_sent = 0;
	info->setup_reset_ntf = 0;
	info->setup_patch_ntf = 0;

	/* Patch init request */
	r = fdp_nci_patch_cmd(ndev, NCI_PATCH_TYPE_RAM);
	if (r)
		goto out;

	/* Patch data connection creation */
	conn_id = fdp_nci_create_conn(ndev);
	if (conn_id < 0) {
		r = conn_id;
		goto out;
	}

	/* Send the patch over the data connection */
	r = fdp_nci_send_patch(ndev, conn_id, NCI_PATCH_TYPE_RAM);
	if (r)
		goto out;

	/* Wait for all the packets to be send over i2c */
	wait_event_interruptible(info->setup_wq,
				 info->setup_patch_sent == 1);

	/* make sure that the NFCC processed the last data packet */
	msleep(FDP_FW_UPDATE_SLEEP);

	/* Close the data connection */
	r = nci_core_conn_close(info->ndev, conn_id);
	if (r)
		goto out;

	/* Patch finish message */
	if (fdp_nci_patch_cmd(ndev, NCI_PATCH_TYPE_EOT)) {
		nfc_err(dev, "RAM patch error 0x%x\n", r);
		r = -EINVAL;
		goto out;
	}

	/* If the patch notification didn't arrive yet, wait for it */
	wait_event_interruptible(info->setup_wq, info->setup_patch_ntf);

	/* Check if the patching was successful */
	r = info->setup_patch_status;
	if (r) {
		nfc_err(dev, "RAM patch error 0x%x\n", r);
		r = -EINVAL;
		goto out;
	}

	/*
	 * We need to wait for the reset notification before we
	 * can continue
	 */
	wait_event_interruptible(info->setup_wq, info->setup_reset_ntf);

out:
	return r;
}

static int fdp_nci_setup(struct nci_dev *ndev)
{
	/* Format: total length followed by an NCI packet */
	struct fdp_nci_info *info = nci_get_drvdata(ndev);
	struct device *dev = &info->phy->i2c_dev->dev;
	int r;
	u8 patched = 0;

	dev_dbg(dev, "%s\n", __func__);

	r = nci_core_init(ndev);
	if (r)
		goto error;

	/* Get RAM and OTP version */
	r = fdp_nci_get_versions(ndev);
	if (r)
		goto error;

	/* Load firmware from disk */
	r = fdp_nci_request_firmware(ndev);
	if (r)
		goto error;

	/* Update OTP */
	if (info->otp_version < info->otp_patch_version) {
		r = fdp_nci_patch_otp(ndev);
		if (r)
			goto error;
		patched = 1;
	}

	/* Update RAM */
	if (info->ram_version < info->ram_patch_version) {
		r = fdp_nci_patch_ram(ndev);
		if (r)
			goto error;
		patched = 1;
	}

	/* Release the firmware buffers */
	fdp_nci_release_firmware(ndev);

	/* If a patch was applied the new version is checked */
	if (patched) {
		r = nci_core_init(ndev);
		if (r)
			goto error;

		r = fdp_nci_get_versions(ndev);
		if (r)
			goto error;

		if (info->otp_version != info->otp_patch_version ||
		    info->ram_version != info->ram_patch_version) {
			nfc_err(dev, "Firmware update failed");
			r = -EINVAL;
			goto error;
		}
	}

	/*
	 * We initialized the devices but the NFC subsystem expects
	 * it to not be initialized.
	 */
	return nci_core_reset(ndev);

error:
	fdp_nci_release_firmware(ndev);
	nfc_err(dev, "Setup error %d\n", r);
	return r;
}

static int fdp_nci_post_setup(struct nci_dev *ndev)
{
	struct fdp_nci_info *info = nci_get_drvdata(ndev);
	struct device *dev = &info->phy->i2c_dev->dev;
	int r;

	/* Check if the device has VSC */
	if (info->fw_vsc_cfg && info->fw_vsc_cfg[0]) {

		/* Set the vendor specific configuration */
		r = fdp_nci_set_production_data(ndev, info->fw_vsc_cfg[3],
						&info->fw_vsc_cfg[4]);
		if (r) {
			nfc_err(dev, "Vendor specific config set error %d\n",
				r);
			return r;
		}
	}

	/* Set clock type and frequency */
	r = fdp_nci_set_clock(ndev, info->clock_type, info->clock_freq);
	if (r) {
		nfc_err(dev, "Clock set error %d\n", r);
		return r;
	}

	/*
	 * In order to apply the VSC FDP needs a reset
	 */
	r = nci_core_reset(ndev);
	if (r)
		return r;

	/**
	 * The nci core was initialized when post setup was called
	 * so we leave it like that
	 */
	return nci_core_init(ndev);
}

static int fdp_nci_core_reset_ntf_packet(struct nci_dev *ndev,
					  struct sk_buff *skb)
{
	struct fdp_nci_info *info = nci_get_drvdata(ndev);
	struct device *dev = &info->phy->i2c_dev->dev;

	dev_dbg(dev, "%s\n", __func__);
	info->setup_reset_ntf = 1;
	wake_up(&info->setup_wq);

	return 0;
}

static int fdp_nci_prop_patch_ntf_packet(struct nci_dev *ndev,
					  struct sk_buff *skb)
{
	struct fdp_nci_info *info = nci_get_drvdata(ndev);
	struct device *dev = &info->phy->i2c_dev->dev;

	dev_dbg(dev, "%s\n", __func__);
	info->setup_patch_ntf = 1;
	info->setup_patch_status = skb->data[0];
	wake_up(&info->setup_wq);

	return 0;
}

static int fdp_nci_prop_patch_rsp_packet(struct nci_dev *ndev,
					  struct sk_buff *skb)
{
	struct fdp_nci_info *info = nci_get_drvdata(ndev);
	struct device *dev = &info->phy->i2c_dev->dev;
	u8 status = skb->data[0];

	dev_dbg(dev, "%s: status 0x%x\n", __func__, status);
	nci_req_complete(ndev, status);

	return 0;
}

static int fdp_nci_prop_set_production_data_rsp_packet(struct nci_dev *ndev,
							struct sk_buff *skb)
{
	struct fdp_nci_info *info = nci_get_drvdata(ndev);
	struct device *dev = &info->phy->i2c_dev->dev;
	u8 status = skb->data[0];

	dev_dbg(dev, "%s: status 0x%x\n", __func__, status);
	nci_req_complete(ndev, status);

	return 0;
}

static int fdp_nci_core_get_config_rsp_packet(struct nci_dev *ndev,
						struct sk_buff *skb)
{
	struct fdp_nci_info *info = nci_get_drvdata(ndev);
	struct device *dev = &info->phy->i2c_dev->dev;
	struct nci_core_get_config_rsp *rsp = (void *) skb->data;
	u8 i, *p;

	if (rsp->status == NCI_STATUS_OK) {

		p = rsp->data;
		for (i = 0; i < 4; i++) {

			switch (*p++) {
			case NCI_PARAM_ID_FW_RAM_VERSION:
				p++;
				info->ram_version = le32_to_cpup((__le32 *) p);
				p += 4;
				break;
			case NCI_PARAM_ID_FW_OTP_VERSION:
				p++;
				info->otp_version = le32_to_cpup((__le32 *) p);
				p += 4;
				break;
			case NCI_PARAM_ID_OTP_LIMITED_VERSION:
				p++;
				info->otp_version = le32_to_cpup((__le32 *) p);
				p += 4;
				break;
			case NCI_PARAM_ID_KEY_INDEX_ID:
				p++;
				info->key_index = *p++;
			}
		}
	}

	dev_dbg(dev, "OTP version %d\n", info->otp_version);
	dev_dbg(dev, "RAM version %d\n", info->ram_version);
	dev_dbg(dev, "key index %d\n", info->key_index);
	dev_dbg(dev, "%s: status 0x%x\n", __func__, rsp->status);

	nci_req_complete(ndev, rsp->status);

	return 0;
}

static struct nci_driver_ops fdp_core_ops[] = {
	{
		.opcode = NCI_OP_CORE_GET_CONFIG_RSP,
		.rsp = fdp_nci_core_get_config_rsp_packet,
	},
	{
		.opcode = NCI_OP_CORE_RESET_NTF,
		.ntf = fdp_nci_core_reset_ntf_packet,
	},
};

static struct nci_driver_ops fdp_prop_ops[] = {
	{
		.opcode = nci_opcode_pack(NCI_GID_PROP, NCI_OP_PROP_PATCH_OID),
		.rsp = fdp_nci_prop_patch_rsp_packet,
		.ntf = fdp_nci_prop_patch_ntf_packet,
	},
	{
		.opcode = nci_opcode_pack(NCI_GID_PROP,
					  NCI_OP_PROP_SET_PDATA_OID),
		.rsp = fdp_nci_prop_set_production_data_rsp_packet,
	},
};

struct nci_ops nci_ops = {
	.open = fdp_nci_open,
	.close = fdp_nci_close,
	.send = fdp_nci_send,
	.setup = fdp_nci_setup,
	.post_setup = fdp_nci_post_setup,
	.prop_ops = fdp_prop_ops,
	.n_prop_ops = ARRAY_SIZE(fdp_prop_ops),
	.core_ops = fdp_core_ops,
	.n_core_ops = ARRAY_SIZE(fdp_core_ops),
};

int fdp_nci_probe(struct fdp_i2c_phy *phy, struct nfc_phy_ops *phy_ops,
			struct nci_dev **ndevp, int tx_headroom,
			int tx_tailroom, u8 clock_type, u32 clock_freq,
			u8 *fw_vsc_cfg)
{
	struct device *dev = &phy->i2c_dev->dev;
	struct fdp_nci_info *info;
	struct nci_dev *ndev;
	u32 protocols;
	int r;

	info = devm_kzalloc(dev, sizeof(struct fdp_nci_info), GFP_KERNEL);
	if (!info)
		return -ENOMEM;

	info->phy = phy;
	info->phy_ops = phy_ops;
	info->clock_type = clock_type;
	info->clock_freq = clock_freq;
	info->fw_vsc_cfg = fw_vsc_cfg;

	init_waitqueue_head(&info->setup_wq);

	protocols = NFC_PROTO_JEWEL_MASK |
		    NFC_PROTO_MIFARE_MASK |
		    NFC_PROTO_FELICA_MASK |
		    NFC_PROTO_ISO14443_MASK |
		    NFC_PROTO_ISO14443_B_MASK |
		    NFC_PROTO_NFC_DEP_MASK |
		    NFC_PROTO_ISO15693_MASK;

	ndev = nci_allocate_device(&nci_ops, protocols, tx_headroom,
				   tx_tailroom);
	if (!ndev) {
		nfc_err(dev, "Cannot allocate nfc ndev\n");
		return -ENOMEM;
	}

	r = nci_register_device(ndev);
	if (r)
		goto err_regdev;

	*ndevp = ndev;
	info->ndev = ndev;

	nci_set_drvdata(ndev, info);

	return 0;

err_regdev:
	nci_free_device(ndev);
	return r;
}
EXPORT_SYMBOL(fdp_nci_probe);

void fdp_nci_remove(struct nci_dev *ndev)
{
	struct fdp_nci_info *info = nci_get_drvdata(ndev);
	struct device *dev = &info->phy->i2c_dev->dev;

	dev_dbg(dev, "%s\n", __func__);

	nci_unregister_device(ndev);
	nci_free_device(ndev);
}
EXPORT_SYMBOL(fdp_nci_remove);

MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("NFC NCI driver for Intel Fields Peak NFC controller");
MODULE_AUTHOR("Robert Dolca <robert.dolca@intel.com>");
