/*
 * 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) {
		*(u8 *)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_u8(skb, crc & 0xff);
		skb_put_u8(skb, 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;
	}

	*(u8 *)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 pipe,
				     u8 event, struct sk_buff *skb)
{
	int r;
	u8 gate = hdev->pipes[pipe].gate;
	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);
