/*
 * HCI based Driver for Inside Secure microread NFC Chip
 *
 * Copyright (C) 2013  Intel Corporation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU General Public License,
 * version 2, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
 */

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include <linux/module.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/crc-ccitt.h>

#include <linux/nfc.h>
#include <net/nfc/nfc.h>
#include <net/nfc/hci.h>
#include <net/nfc/llc.h>

#include "microread.h"

/* Proprietary gates, events, commands and registers */
/* Admin */
#define MICROREAD_GATE_ID_ADM NFC_HCI_ADMIN_GATE
#define MICROREAD_GATE_ID_MGT 0x01
#define MICROREAD_GATE_ID_OS 0x02
#define MICROREAD_GATE_ID_TESTRF 0x03
#define MICROREAD_GATE_ID_LOOPBACK NFC_HCI_LOOPBACK_GATE
#define MICROREAD_GATE_ID_IDT NFC_HCI_ID_MGMT_GATE
#define MICROREAD_GATE_ID_LMS NFC_HCI_LINK_MGMT_GATE

/* Reader */
#define MICROREAD_GATE_ID_MREAD_GEN 0x10
#define MICROREAD_GATE_ID_MREAD_ISO_B NFC_HCI_RF_READER_B_GATE
#define MICROREAD_GATE_ID_MREAD_NFC_T1 0x12
#define MICROREAD_GATE_ID_MREAD_ISO_A NFC_HCI_RF_READER_A_GATE
#define MICROREAD_GATE_ID_MREAD_NFC_T3 0x14
#define MICROREAD_GATE_ID_MREAD_ISO_15_3 0x15
#define MICROREAD_GATE_ID_MREAD_ISO_15_2 0x16
#define MICROREAD_GATE_ID_MREAD_ISO_B_3 0x17
#define MICROREAD_GATE_ID_MREAD_BPRIME 0x18
#define MICROREAD_GATE_ID_MREAD_ISO_A_3 0x19

/* Card */
#define MICROREAD_GATE_ID_MCARD_GEN 0x20
#define MICROREAD_GATE_ID_MCARD_ISO_B 0x21
#define MICROREAD_GATE_ID_MCARD_BPRIME 0x22
#define MICROREAD_GATE_ID_MCARD_ISO_A 0x23
#define MICROREAD_GATE_ID_MCARD_NFC_T3 0x24
#define MICROREAD_GATE_ID_MCARD_ISO_15_3 0x25
#define MICROREAD_GATE_ID_MCARD_ISO_15_2 0x26
#define MICROREAD_GATE_ID_MCARD_ISO_B_2 0x27
#define MICROREAD_GATE_ID_MCARD_ISO_CUSTOM 0x28
#define MICROREAD_GATE_ID_SECURE_ELEMENT 0x2F

/* P2P */
#define MICROREAD_GATE_ID_P2P_GEN 0x30
#define MICROREAD_GATE_ID_P2P_TARGET 0x31
#define MICROREAD_PAR_P2P_TARGET_MODE 0x01
#define MICROREAD_PAR_P2P_TARGET_GT 0x04
#define MICROREAD_GATE_ID_P2P_INITIATOR 0x32
#define MICROREAD_PAR_P2P_INITIATOR_GI 0x01
#define MICROREAD_PAR_P2P_INITIATOR_GT 0x03

/* Those pipes are created/opened by default in the chip */
#define MICROREAD_PIPE_ID_LMS 0x00
#define MICROREAD_PIPE_ID_ADMIN 0x01
#define MICROREAD_PIPE_ID_MGT 0x02
#define MICROREAD_PIPE_ID_OS 0x03
#define MICROREAD_PIPE_ID_HDS_LOOPBACK 0x04
#define MICROREAD_PIPE_ID_HDS_IDT 0x05
#define MICROREAD_PIPE_ID_HDS_MCARD_ISO_B 0x08
#define MICROREAD_PIPE_ID_HDS_MCARD_ISO_BPRIME 0x09
#define MICROREAD_PIPE_ID_HDS_MCARD_ISO_A 0x0A
#define MICROREAD_PIPE_ID_HDS_MCARD_ISO_15_3 0x0B
#define MICROREAD_PIPE_ID_HDS_MCARD_ISO_15_2 0x0C
#define MICROREAD_PIPE_ID_HDS_MCARD_NFC_T3 0x0D
#define MICROREAD_PIPE_ID_HDS_MCARD_ISO_B_2 0x0E
#define MICROREAD_PIPE_ID_HDS_MCARD_CUSTOM 0x0F
#define MICROREAD_PIPE_ID_HDS_MREAD_ISO_B 0x10
#define MICROREAD_PIPE_ID_HDS_MREAD_NFC_T1 0x11
#define MICROREAD_PIPE_ID_HDS_MREAD_ISO_A 0x12
#define MICROREAD_PIPE_ID_HDS_MREAD_ISO_15_3 0x13
#define MICROREAD_PIPE_ID_HDS_MREAD_ISO_15_2 0x14
#define MICROREAD_PIPE_ID_HDS_MREAD_NFC_T3 0x15
#define MICROREAD_PIPE_ID_HDS_MREAD_ISO_B_3 0x16
#define MICROREAD_PIPE_ID_HDS_MREAD_BPRIME 0x17
#define MICROREAD_PIPE_ID_HDS_MREAD_ISO_A_3 0x18
#define MICROREAD_PIPE_ID_HDS_MREAD_GEN 0x1B
#define MICROREAD_PIPE_ID_HDS_STACKED_ELEMENT 0x1C
#define MICROREAD_PIPE_ID_HDS_INSTANCES 0x1D
#define MICROREAD_PIPE_ID_HDS_TESTRF 0x1E
#define MICROREAD_PIPE_ID_HDS_P2P_TARGET 0x1F
#define MICROREAD_PIPE_ID_HDS_P2P_INITIATOR 0x20

/* Events */
#define MICROREAD_EVT_MREAD_DISCOVERY_OCCURED NFC_HCI_EVT_TARGET_DISCOVERED
#define MICROREAD_EVT_MREAD_CARD_FOUND 0x3D
#define MICROREAD_EMCF_A_ATQA 0
#define MICROREAD_EMCF_A_SAK 2
#define MICROREAD_EMCF_A_LEN 3
#define MICROREAD_EMCF_A_UID 4
#define MICROREAD_EMCF_A3_ATQA 0
#define MICROREAD_EMCF_A3_SAK 2
#define MICROREAD_EMCF_A3_LEN 3
#define MICROREAD_EMCF_A3_UID 4
#define MICROREAD_EMCF_B_UID 0
#define MICROREAD_EMCF_T1_ATQA 0
#define MICROREAD_EMCF_T1_UID 4
#define MICROREAD_EMCF_T3_UID 0
#define MICROREAD_EVT_MREAD_DISCOVERY_START NFC_HCI_EVT_READER_REQUESTED
#define MICROREAD_EVT_MREAD_DISCOVERY_START_SOME 0x3E
#define MICROREAD_EVT_MREAD_DISCOVERY_STOP NFC_HCI_EVT_END_OPERATION
#define MICROREAD_EVT_MREAD_SIM_REQUESTS 0x3F
#define MICROREAD_EVT_MCARD_EXCHANGE NFC_HCI_EVT_TARGET_DISCOVERED
#define MICROREAD_EVT_P2P_INITIATOR_EXCHANGE_TO_RF 0x20
#define MICROREAD_EVT_P2P_INITIATOR_EXCHANGE_FROM_RF 0x21
#define MICROREAD_EVT_MCARD_FIELD_ON 0x11
#define MICROREAD_EVT_P2P_TARGET_ACTIVATED 0x13
#define MICROREAD_EVT_P2P_TARGET_DEACTIVATED 0x12
#define MICROREAD_EVT_MCARD_FIELD_OFF 0x14

/* Commands */
#define MICROREAD_CMD_MREAD_EXCHANGE 0x10
#define MICROREAD_CMD_MREAD_SUBSCRIBE 0x3F

/* Hosts IDs */
#define MICROREAD_ELT_ID_HDS NFC_HCI_TERMINAL_HOST_ID
#define MICROREAD_ELT_ID_SIM NFC_HCI_UICC_HOST_ID
#define MICROREAD_ELT_ID_SE1 0x03
#define MICROREAD_ELT_ID_SE2 0x04
#define MICROREAD_ELT_ID_SE3 0x05

static struct nfc_hci_gate microread_gates[] = {
	{MICROREAD_GATE_ID_ADM, MICROREAD_PIPE_ID_ADMIN},
	{MICROREAD_GATE_ID_LOOPBACK, MICROREAD_PIPE_ID_HDS_LOOPBACK},
	{MICROREAD_GATE_ID_IDT, MICROREAD_PIPE_ID_HDS_IDT},
	{MICROREAD_GATE_ID_LMS, MICROREAD_PIPE_ID_LMS},
	{MICROREAD_GATE_ID_MREAD_ISO_B, MICROREAD_PIPE_ID_HDS_MREAD_ISO_B},
	{MICROREAD_GATE_ID_MREAD_ISO_A, MICROREAD_PIPE_ID_HDS_MREAD_ISO_A},
	{MICROREAD_GATE_ID_MREAD_ISO_A_3, MICROREAD_PIPE_ID_HDS_MREAD_ISO_A_3},
	{MICROREAD_GATE_ID_MGT, MICROREAD_PIPE_ID_MGT},
	{MICROREAD_GATE_ID_OS, MICROREAD_PIPE_ID_OS},
	{MICROREAD_GATE_ID_MREAD_NFC_T1, MICROREAD_PIPE_ID_HDS_MREAD_NFC_T1},
	{MICROREAD_GATE_ID_MREAD_NFC_T3, MICROREAD_PIPE_ID_HDS_MREAD_NFC_T3},
	{MICROREAD_GATE_ID_P2P_TARGET, MICROREAD_PIPE_ID_HDS_P2P_TARGET},
	{MICROREAD_GATE_ID_P2P_INITIATOR, MICROREAD_PIPE_ID_HDS_P2P_INITIATOR}
};

/* Largest headroom needed for outgoing custom commands */
#define MICROREAD_CMDS_HEADROOM	2
#define MICROREAD_CMD_TAILROOM	2

struct microread_info {
	struct nfc_phy_ops *phy_ops;
	void *phy_id;

	struct nfc_hci_dev *hdev;

	int async_cb_type;
	data_exchange_cb_t async_cb;
	void *async_cb_context;
};

static int microread_open(struct nfc_hci_dev *hdev)
{
	struct microread_info *info = nfc_hci_get_clientdata(hdev);

	return info->phy_ops->enable(info->phy_id);
}

static void microread_close(struct nfc_hci_dev *hdev)
{
	struct microread_info *info = nfc_hci_get_clientdata(hdev);

	info->phy_ops->disable(info->phy_id);
}

static int microread_hci_ready(struct nfc_hci_dev *hdev)
{
	int r;
	u8 param[4];

	param[0] = 0x03;
	r = nfc_hci_send_cmd(hdev, MICROREAD_GATE_ID_MREAD_ISO_A,
			     MICROREAD_CMD_MREAD_SUBSCRIBE, param, 1, NULL);
	if (r)
		return r;

	r = nfc_hci_send_cmd(hdev, MICROREAD_GATE_ID_MREAD_ISO_A_3,
			     MICROREAD_CMD_MREAD_SUBSCRIBE, NULL, 0, NULL);
	if (r)
		return r;

	param[0] = 0x00;
	param[1] = 0x03;
	param[2] = 0x00;
	r = nfc_hci_send_cmd(hdev, MICROREAD_GATE_ID_MREAD_ISO_B,
			     MICROREAD_CMD_MREAD_SUBSCRIBE, param, 3, NULL);
	if (r)
		return r;

	r = nfc_hci_send_cmd(hdev, MICROREAD_GATE_ID_MREAD_NFC_T1,
			     MICROREAD_CMD_MREAD_SUBSCRIBE, NULL, 0, NULL);
	if (r)
		return r;

	param[0] = 0xFF;
	param[1] = 0xFF;
	param[2] = 0x00;
	param[3] = 0x00;
	r = nfc_hci_send_cmd(hdev, MICROREAD_GATE_ID_MREAD_NFC_T3,
			     MICROREAD_CMD_MREAD_SUBSCRIBE, param, 4, NULL);

	return r;
}

static int microread_xmit(struct nfc_hci_dev *hdev, struct sk_buff *skb)
{
	struct microread_info *info = nfc_hci_get_clientdata(hdev);

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

static int microread_start_poll(struct nfc_hci_dev *hdev,
				u32 im_protocols, u32 tm_protocols)
{
	int r;

	u8 param[2];
	u8 mode;

	param[0] = 0x00;
	param[1] = 0x00;

	if (im_protocols & NFC_PROTO_ISO14443_MASK)
		param[0] |= (1 << 2);

	if (im_protocols & NFC_PROTO_ISO14443_B_MASK)
		param[0] |= 1;

	if (im_protocols & NFC_PROTO_MIFARE_MASK)
		param[1] |= 1;

	if (im_protocols & NFC_PROTO_JEWEL_MASK)
		param[0] |= (1 << 1);

	if (im_protocols & NFC_PROTO_FELICA_MASK)
		param[0] |= (1 << 5);

	if (im_protocols & NFC_PROTO_NFC_DEP_MASK)
		param[1] |= (1 << 1);

	if ((im_protocols | tm_protocols) & NFC_PROTO_NFC_DEP_MASK) {
		hdev->gb = nfc_get_local_general_bytes(hdev->ndev,
						       &hdev->gb_len);
		if (hdev->gb == NULL || hdev->gb_len == 0) {
			im_protocols &= ~NFC_PROTO_NFC_DEP_MASK;
			tm_protocols &= ~NFC_PROTO_NFC_DEP_MASK;
		}
	}

	r = nfc_hci_send_event(hdev, MICROREAD_GATE_ID_MREAD_ISO_A,
			       MICROREAD_EVT_MREAD_DISCOVERY_STOP, NULL, 0);
	if (r)
		return r;

	mode = 0xff;
	r = nfc_hci_set_param(hdev, MICROREAD_GATE_ID_P2P_TARGET,
			      MICROREAD_PAR_P2P_TARGET_MODE, &mode, 1);
	if (r)
		return r;

	if (im_protocols & NFC_PROTO_NFC_DEP_MASK) {
		r = nfc_hci_set_param(hdev, MICROREAD_GATE_ID_P2P_INITIATOR,
				      MICROREAD_PAR_P2P_INITIATOR_GI,
				      hdev->gb, hdev->gb_len);
		if (r)
			return r;
	}

	if (tm_protocols & NFC_PROTO_NFC_DEP_MASK) {
		r = nfc_hci_set_param(hdev, MICROREAD_GATE_ID_P2P_TARGET,
				      MICROREAD_PAR_P2P_TARGET_GT,
				      hdev->gb, hdev->gb_len);
		if (r)
			return r;

		mode = 0x02;
		r = nfc_hci_set_param(hdev, MICROREAD_GATE_ID_P2P_TARGET,
				      MICROREAD_PAR_P2P_TARGET_MODE, &mode, 1);
		if (r)
			return r;
	}

	return nfc_hci_send_event(hdev, MICROREAD_GATE_ID_MREAD_ISO_A,
				  MICROREAD_EVT_MREAD_DISCOVERY_START_SOME,
				  param, 2);
}

static int microread_dep_link_up(struct nfc_hci_dev *hdev,
				struct nfc_target *target, u8 comm_mode,
				u8 *gb, size_t gb_len)
{
	struct sk_buff *rgb_skb = NULL;
	int r;

	r = nfc_hci_get_param(hdev, target->hci_reader_gate,
			      MICROREAD_PAR_P2P_INITIATOR_GT, &rgb_skb);
	if (r < 0)
		return r;

	if (rgb_skb->len == 0 || rgb_skb->len > NFC_GB_MAXSIZE) {
		r = -EPROTO;
		goto exit;
	}

	r = nfc_set_remote_general_bytes(hdev->ndev, rgb_skb->data,
					 rgb_skb->len);
	if (r == 0)
		r = nfc_dep_link_is_up(hdev->ndev, target->idx, comm_mode,
				       NFC_RF_INITIATOR);
exit:
	kfree_skb(rgb_skb);

	return r;
}

static int microread_dep_link_down(struct nfc_hci_dev *hdev)
{
	return nfc_hci_send_event(hdev, MICROREAD_GATE_ID_P2P_INITIATOR,
				  MICROREAD_EVT_MREAD_DISCOVERY_STOP, NULL, 0);
}

static int microread_target_from_gate(struct nfc_hci_dev *hdev, u8 gate,
				      struct nfc_target *target)
{
	switch (gate) {
	case MICROREAD_GATE_ID_P2P_INITIATOR:
		target->supported_protocols = NFC_PROTO_NFC_DEP_MASK;
		break;
	default:
		return -EPROTO;
	}

	return 0;
}

static int microread_complete_target_discovered(struct nfc_hci_dev *hdev,
						u8 gate,
						struct nfc_target *target)
{
	return 0;
}

#define MICROREAD_CB_TYPE_READER_ALL 1

static void microread_im_transceive_cb(void *context, struct sk_buff *skb,
				       int err)
{
	struct microread_info *info = context;

	switch (info->async_cb_type) {
	case MICROREAD_CB_TYPE_READER_ALL:
		if (err == 0) {
			if (skb->len == 0) {
				err = -EPROTO;
				kfree_skb(skb);
				info->async_cb(info->async_cb_context, NULL,
					       -EPROTO);
				return;
			}

			if (skb->data[skb->len - 1] != 0) {
				err = nfc_hci_result_to_errno(
						       skb->data[skb->len - 1]);
				kfree_skb(skb);
				info->async_cb(info->async_cb_context, NULL,
					       err);
				return;
			}

			skb_trim(skb, skb->len - 1);	/* RF Error ind. */
		}
		info->async_cb(info->async_cb_context, skb, err);
		break;
	default:
		if (err == 0)
			kfree_skb(skb);
		break;
	}
}

/*
 * Returns:
 * <= 0: driver handled the data exchange
 *    1: driver doesn't especially handle, please do standard processing
 */
static int microread_im_transceive(struct nfc_hci_dev *hdev,
				   struct nfc_target *target,
				   struct sk_buff *skb, data_exchange_cb_t cb,
				   void *cb_context)
{
	struct microread_info *info = nfc_hci_get_clientdata(hdev);
	u8 control_bits;
	u16 crc;

	pr_info("data exchange to gate 0x%x\n", target->hci_reader_gate);

	if (target->hci_reader_gate == MICROREAD_GATE_ID_P2P_INITIATOR) {
		*skb_push(skb, 1) = 0;

		return nfc_hci_send_event(hdev, target->hci_reader_gate,
				     MICROREAD_EVT_P2P_INITIATOR_EXCHANGE_TO_RF,
				     skb->data, skb->len);
	}

	switch (target->hci_reader_gate) {
	case MICROREAD_GATE_ID_MREAD_ISO_A:
		control_bits = 0xCB;
		break;
	case MICROREAD_GATE_ID_MREAD_ISO_A_3:
		control_bits = 0xCB;
		break;
	case MICROREAD_GATE_ID_MREAD_ISO_B:
		control_bits = 0xCB;
		break;
	case MICROREAD_GATE_ID_MREAD_NFC_T1:
		control_bits = 0x1B;

		crc = crc_ccitt(0xffff, skb->data, skb->len);
		crc = ~crc;
		*skb_put(skb, 1) = crc & 0xff;
		*skb_put(skb, 1) = crc >> 8;
		break;
	case MICROREAD_GATE_ID_MREAD_NFC_T3:
		control_bits = 0xDB;
		break;
	default:
		pr_info("Abort im_transceive to invalid gate 0x%x\n",
			target->hci_reader_gate);
		return 1;
	}

	*skb_push(skb, 1) = control_bits;

	info->async_cb_type = MICROREAD_CB_TYPE_READER_ALL;
	info->async_cb = cb;
	info->async_cb_context = cb_context;

	return nfc_hci_send_cmd_async(hdev, target->hci_reader_gate,
				      MICROREAD_CMD_MREAD_EXCHANGE,
				      skb->data, skb->len,
				      microread_im_transceive_cb, info);
}

static int microread_tm_send(struct nfc_hci_dev *hdev, struct sk_buff *skb)
{
	int r;

	r = nfc_hci_send_event(hdev, MICROREAD_GATE_ID_P2P_TARGET,
			       MICROREAD_EVT_MCARD_EXCHANGE,
			       skb->data, skb->len);

	kfree_skb(skb);

	return r;
}

static void microread_target_discovered(struct nfc_hci_dev *hdev, u8 gate,
					struct sk_buff *skb)
{
	struct nfc_target *targets;
	int r = 0;

	pr_info("target discovered to gate 0x%x\n", gate);

	targets = kzalloc(sizeof(struct nfc_target), GFP_KERNEL);
	if (targets == NULL) {
		r = -ENOMEM;
		goto exit;
	}

	targets->hci_reader_gate = gate;

	switch (gate) {
	case MICROREAD_GATE_ID_MREAD_ISO_A:
		targets->supported_protocols =
		      nfc_hci_sak_to_protocol(skb->data[MICROREAD_EMCF_A_SAK]);
		targets->sens_res =
			 be16_to_cpu(*(u16 *)&skb->data[MICROREAD_EMCF_A_ATQA]);
		targets->sel_res = skb->data[MICROREAD_EMCF_A_SAK];
		targets->nfcid1_len = skb->data[MICROREAD_EMCF_A_LEN];
		if (targets->nfcid1_len > sizeof(targets->nfcid1)) {
			r = -EINVAL;
			goto exit_free;
		}
		memcpy(targets->nfcid1, &skb->data[MICROREAD_EMCF_A_UID],
		       targets->nfcid1_len);
		break;
	case MICROREAD_GATE_ID_MREAD_ISO_A_3:
		targets->supported_protocols =
		      nfc_hci_sak_to_protocol(skb->data[MICROREAD_EMCF_A3_SAK]);
		targets->sens_res =
			 be16_to_cpu(*(u16 *)&skb->data[MICROREAD_EMCF_A3_ATQA]);
		targets->sel_res = skb->data[MICROREAD_EMCF_A3_SAK];
		targets->nfcid1_len = skb->data[MICROREAD_EMCF_A3_LEN];
		if (targets->nfcid1_len > sizeof(targets->nfcid1)) {
			r = -EINVAL;
			goto exit_free;
		}
		memcpy(targets->nfcid1, &skb->data[MICROREAD_EMCF_A3_UID],
		       targets->nfcid1_len);
		break;
	case MICROREAD_GATE_ID_MREAD_ISO_B:
		targets->supported_protocols = NFC_PROTO_ISO14443_B_MASK;
		memcpy(targets->nfcid1, &skb->data[MICROREAD_EMCF_B_UID], 4);
		targets->nfcid1_len = 4;
		break;
	case MICROREAD_GATE_ID_MREAD_NFC_T1:
		targets->supported_protocols = NFC_PROTO_JEWEL_MASK;
		targets->sens_res =
			le16_to_cpu(*(u16 *)&skb->data[MICROREAD_EMCF_T1_ATQA]);
		memcpy(targets->nfcid1, &skb->data[MICROREAD_EMCF_T1_UID], 4);
		targets->nfcid1_len = 4;
		break;
	case MICROREAD_GATE_ID_MREAD_NFC_T3:
		targets->supported_protocols = NFC_PROTO_FELICA_MASK;
		memcpy(targets->nfcid1, &skb->data[MICROREAD_EMCF_T3_UID], 8);
		targets->nfcid1_len = 8;
		break;
	default:
		pr_info("discard target discovered to gate 0x%x\n", gate);
		goto exit_free;
	}

	r = nfc_targets_found(hdev->ndev, targets, 1);

exit_free:
	kfree(targets);

exit:
	kfree_skb(skb);

	if (r)
		pr_err("Failed to handle discovered target err=%d\n", r);
}

static int microread_event_received(struct nfc_hci_dev *hdev, u8 gate,
				     u8 event, struct sk_buff *skb)
{
	int r;
	u8 mode;

	pr_info("Microread received event 0x%x to gate 0x%x\n", event, gate);

	switch (event) {
	case MICROREAD_EVT_MREAD_CARD_FOUND:
		microread_target_discovered(hdev, gate, skb);
		return 0;

	case MICROREAD_EVT_P2P_INITIATOR_EXCHANGE_FROM_RF:
		if (skb->len < 1) {
			kfree_skb(skb);
			return -EPROTO;
		}

		if (skb->data[skb->len - 1]) {
			kfree_skb(skb);
			return -EIO;
		}

		skb_trim(skb, skb->len - 1);

		r = nfc_tm_data_received(hdev->ndev, skb);
		break;

	case MICROREAD_EVT_MCARD_FIELD_ON:
	case MICROREAD_EVT_MCARD_FIELD_OFF:
		kfree_skb(skb);
		return 0;

	case MICROREAD_EVT_P2P_TARGET_ACTIVATED:
		r = nfc_tm_activated(hdev->ndev, NFC_PROTO_NFC_DEP_MASK,
				     NFC_COMM_PASSIVE, skb->data,
				     skb->len);

		kfree_skb(skb);
		break;

	case MICROREAD_EVT_MCARD_EXCHANGE:
		if (skb->len < 1) {
			kfree_skb(skb);
			return -EPROTO;
		}

		if (skb->data[skb->len-1]) {
			kfree_skb(skb);
			return -EIO;
		}

		skb_trim(skb, skb->len - 1);

		r = nfc_tm_data_received(hdev->ndev, skb);
		break;

	case MICROREAD_EVT_P2P_TARGET_DEACTIVATED:
		kfree_skb(skb);

		mode = 0xff;
		r = nfc_hci_set_param(hdev, MICROREAD_GATE_ID_P2P_TARGET,
				      MICROREAD_PAR_P2P_TARGET_MODE, &mode, 1);
		if (r)
			break;

		r = nfc_hci_send_event(hdev, gate,
				       MICROREAD_EVT_MREAD_DISCOVERY_STOP, NULL,
				       0);
		break;

	default:
		return 1;
	}

	return r;
}

static struct nfc_hci_ops microread_hci_ops = {
	.open = microread_open,
	.close = microread_close,
	.hci_ready = microread_hci_ready,
	.xmit = microread_xmit,
	.start_poll = microread_start_poll,
	.dep_link_up = microread_dep_link_up,
	.dep_link_down = microread_dep_link_down,
	.target_from_gate = microread_target_from_gate,
	.complete_target_discovered = microread_complete_target_discovered,
	.im_transceive = microread_im_transceive,
	.tm_send = microread_tm_send,
	.check_presence = NULL,
	.event_received = microread_event_received,
};

int microread_probe(void *phy_id, struct nfc_phy_ops *phy_ops, char *llc_name,
		    int phy_headroom, int phy_tailroom, int phy_payload,
		    struct nfc_hci_dev **hdev)
{
	struct microread_info *info;
	unsigned long quirks = 0;
	u32 protocols;
	struct nfc_hci_init_data init_data;
	int r;

	info = kzalloc(sizeof(struct microread_info), GFP_KERNEL);
	if (!info) {
		r = -ENOMEM;
		goto err_info_alloc;
	}

	info->phy_ops = phy_ops;
	info->phy_id = phy_id;

	init_data.gate_count = ARRAY_SIZE(microread_gates);
	memcpy(init_data.gates, microread_gates, sizeof(microread_gates));

	strcpy(init_data.session_id, "MICROREA");

	set_bit(NFC_HCI_QUIRK_SHORT_CLEAR, &quirks);

	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;

	info->hdev = nfc_hci_allocate_device(&microread_hci_ops, &init_data,
					     quirks, protocols, llc_name,
					     phy_headroom +
					     MICROREAD_CMDS_HEADROOM,
					     phy_tailroom +
					     MICROREAD_CMD_TAILROOM,
					     phy_payload);
	if (!info->hdev) {
		pr_err("Cannot allocate nfc hdev\n");
		r = -ENOMEM;
		goto err_alloc_hdev;
	}

	nfc_hci_set_clientdata(info->hdev, info);

	r = nfc_hci_register_device(info->hdev);
	if (r)
		goto err_regdev;

	*hdev = info->hdev;

	return 0;

err_regdev:
	nfc_hci_free_device(info->hdev);

err_alloc_hdev:
	kfree(info);

err_info_alloc:
	return r;
}
EXPORT_SYMBOL(microread_probe);

void microread_remove(struct nfc_hci_dev *hdev)
{
	struct microread_info *info = nfc_hci_get_clientdata(hdev);

	nfc_hci_unregister_device(hdev);
	nfc_hci_free_device(hdev);
	kfree(info);
}
EXPORT_SYMBOL(microread_remove);

MODULE_LICENSE("GPL");
MODULE_DESCRIPTION(DRIVER_DESC);
