/**
 * 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,
};

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;
}

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;

	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(NFCMRVL_PHY_SPI,
						  drv_data, &spi_ops,
						  &drv_data->spi->dev,
						  pdata);
	if (IS_ERR(drv_data->priv))
		return PTR_ERR(drv_data->priv);

	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 = "marvell,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");
