/*
 * 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, write to the
 * Free Software Foundation, Inc.,
 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */

#include <linux/module.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/gpio.h>
#include <linux/mei_cl_bus.h>

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

#include "microread.h"

#define MICROREAD_DRIVER_NAME "microread"

struct mei_nfc_hdr {
	u8 cmd;
	u8 status;
	u16 req_id;
	u32 reserved;
	u16 data_size;
} __attribute__((packed));

#define MEI_NFC_HEADER_SIZE 10
#define MEI_NFC_MAX_HCI_PAYLOAD 300
#define MEI_NFC_MAX_READ (MEI_NFC_HEADER_SIZE + MEI_NFC_MAX_HCI_PAYLOAD)

struct microread_mei_phy {
	struct mei_cl_device *device;
	struct nfc_hci_dev *hdev;

	int powered;

	int hard_fault;		/*
				 * < 0 if hardware error occured (e.g. i2c err)
				 * and prevents normal operation.
				 */
};

#define MEI_DUMP_SKB_IN(info, skb)					\
do {								\
	pr_debug("%s:\n", info);				\
	print_hex_dump(KERN_DEBUG, "mei in : ", DUMP_PREFIX_OFFSET,	\
		       16, 1, (skb)->data, (skb)->len, 0);	\
} while (0)

#define MEI_DUMP_SKB_OUT(info, skb)					\
do {								\
	pr_debug("%s:\n", info);				\
	print_hex_dump(KERN_DEBUG, "mei out: ", DUMP_PREFIX_OFFSET,	\
		       16, 1, (skb)->data, (skb)->len, 0);	\
} while (0)

static int microread_mei_enable(void *phy_id)
{
	struct microread_mei_phy *phy = phy_id;

	pr_info(DRIVER_DESC ": %s\n", __func__);

	phy->powered = 1;

	return 0;
}

static void microread_mei_disable(void *phy_id)
{
	struct microread_mei_phy *phy = phy_id;

	pr_info(DRIVER_DESC ": %s\n", __func__);

	phy->powered = 0;
}

/*
 * Writing a frame must not return the number of written bytes.
 * It must return either zero for success, or <0 for error.
 * In addition, it must not alter the skb
 */
static int microread_mei_write(void *phy_id, struct sk_buff *skb)
{
	struct microread_mei_phy *phy = phy_id;
	int r;

	MEI_DUMP_SKB_OUT("mei frame sent", skb);

	r = mei_cl_send(phy->device, skb->data, skb->len);
	if (r > 0)
		r = 0;

	return r;
}

static void microread_event_cb(struct mei_cl_device *device, u32 events,
			       void *context)
{
	struct microread_mei_phy *phy = context;

	if (phy->hard_fault != 0)
		return;

	if (events & BIT(MEI_CL_EVENT_RX)) {
		struct sk_buff *skb;
		int reply_size;

		skb = alloc_skb(MEI_NFC_MAX_READ, GFP_KERNEL);
		if (!skb)
			return;

		reply_size = mei_cl_recv(device, skb->data, MEI_NFC_MAX_READ);
		if (reply_size < MEI_NFC_HEADER_SIZE) {
			kfree(skb);
			return;
		}

		skb_put(skb, reply_size);
		skb_pull(skb, MEI_NFC_HEADER_SIZE);

		MEI_DUMP_SKB_IN("mei frame read", skb);

		nfc_hci_recv_frame(phy->hdev, skb);
	}
}

static struct nfc_phy_ops mei_phy_ops = {
	.write = microread_mei_write,
	.enable = microread_mei_enable,
	.disable = microread_mei_disable,
};

static int microread_mei_probe(struct mei_cl_device *device,
			       const struct mei_cl_device_id *id)
{
	struct microread_mei_phy *phy;
	int r;

	pr_info("Probing NFC microread\n");

	phy = kzalloc(sizeof(struct microread_mei_phy), GFP_KERNEL);
	if (!phy) {
		pr_err("Cannot allocate memory for microread mei phy.\n");
		return -ENOMEM;
	}

	phy->device = device;
	mei_cl_set_drvdata(device, phy);

	r = mei_cl_register_event_cb(device, microread_event_cb, phy);
	if (r) {
		pr_err(MICROREAD_DRIVER_NAME ": event cb registration failed\n");
		goto err_out;
	}

	r = microread_probe(phy, &mei_phy_ops, LLC_NOP_NAME,
			    MEI_NFC_HEADER_SIZE, 0, MEI_NFC_MAX_HCI_PAYLOAD,
			    &phy->hdev);
	if (r < 0)
		goto err_out;

	return 0;

err_out:
	kfree(phy);

	return r;
}

static int microread_mei_remove(struct mei_cl_device *device)
{
	struct microread_mei_phy *phy = mei_cl_get_drvdata(device);

	pr_info("Removing microread\n");

	microread_remove(phy->hdev);

	if (phy->powered)
		microread_mei_disable(phy);

	kfree(phy);

	return 0;
}

static struct mei_cl_device_id microread_mei_tbl[] = {
	{ MICROREAD_DRIVER_NAME },

	/* required last entry */
	{ }
};
MODULE_DEVICE_TABLE(mei, microread_mei_tbl);

static struct mei_cl_driver microread_driver = {
	.id_table = microread_mei_tbl,
	.name = MICROREAD_DRIVER_NAME,

	.probe = microread_mei_probe,
	.remove = microread_mei_remove,
};

static int microread_mei_init(void)
{
	int r;

	pr_debug(DRIVER_DESC ": %s\n", __func__);

	r = mei_cl_driver_register(&microread_driver);
	if (r) {
		pr_err(MICROREAD_DRIVER_NAME ": driver registration failed\n");
		return r;
	}

	return 0;
}

static void microread_mei_exit(void)
{
	mei_cl_driver_unregister(&microread_driver);
}

module_init(microread_mei_init);
module_exit(microread_mei_exit);

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