// SPDX-License-Identifier: GPL-2.0-only
/*
 * Marvell NFC-over-I2C driver: I2C interface related functions
 *
 * Copyright (C) 2015, Marvell International Ltd.
 */

#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/i2c.h>
#include <linux/nfc.h>
#include <linux/delay.h>
#include <linux/of_irq.h>
#include <net/nfc/nci.h>
#include <net/nfc/nci_core.h>
#include "nfcmrvl.h"

struct nfcmrvl_i2c_drv_data {
	unsigned long flags;
	struct device *dev;
	struct i2c_client *i2c;
	struct nfcmrvl_private *priv;
};

static int nfcmrvl_i2c_read(struct nfcmrvl_i2c_drv_data *drv_data,
			    struct sk_buff **skb)
{
	int ret;
	struct nci_ctrl_hdr nci_hdr;

	/* Read NCI header to know the payload size */
	ret = i2c_master_recv(drv_data->i2c, (u8 *)&nci_hdr, NCI_CTRL_HDR_SIZE);
	if (ret != NCI_CTRL_HDR_SIZE) {
		nfc_err(&drv_data->i2c->dev, "cannot read NCI header\n");
		return -EBADMSG;
	}

	*skb = nci_skb_alloc(drv_data->priv->ndev,
			     nci_hdr.plen + NCI_CTRL_HDR_SIZE, GFP_KERNEL);
	if (!*skb)
		return -ENOMEM;

	/* Copy NCI header into the SKB */
	skb_put_data(*skb, &nci_hdr, NCI_CTRL_HDR_SIZE);

	if (nci_hdr.plen) {
		/* Read the NCI payload */
		ret = i2c_master_recv(drv_data->i2c,
				      skb_put(*skb, nci_hdr.plen),
				      nci_hdr.plen);

		if (ret != nci_hdr.plen) {
			nfc_err(&drv_data->i2c->dev,
				"Invalid frame payload length: %u (expected %u)\n",
				ret, nci_hdr.plen);
			kfree_skb(*skb);
			return -EBADMSG;
		}
	}

	return 0;
}

static irqreturn_t nfcmrvl_i2c_int_irq_thread_fn(int irq, void *drv_data_ptr)
{
	struct nfcmrvl_i2c_drv_data *drv_data = drv_data_ptr;
	struct sk_buff *skb = NULL;
	int ret;

	if (!drv_data->priv)
		return IRQ_HANDLED;

	if (test_bit(NFCMRVL_PHY_ERROR, &drv_data->priv->flags))
		return IRQ_HANDLED;

	ret = nfcmrvl_i2c_read(drv_data, &skb);

	switch (ret) {
	case -EREMOTEIO:
		set_bit(NFCMRVL_PHY_ERROR, &drv_data->priv->flags);
		break;
	case -ENOMEM:
	case -EBADMSG:
		nfc_err(&drv_data->i2c->dev, "read failed %d\n", ret);
		break;
	default:
		if (nfcmrvl_nci_recv_frame(drv_data->priv, skb) < 0)
			nfc_err(&drv_data->i2c->dev, "corrupted RX packet\n");
		break;
	}
	return IRQ_HANDLED;
}

static int nfcmrvl_i2c_nci_open(struct nfcmrvl_private *priv)
{
	struct nfcmrvl_i2c_drv_data *drv_data = priv->drv_data;

	if (!drv_data)
		return -ENODEV;

	return 0;
}

static int nfcmrvl_i2c_nci_close(struct nfcmrvl_private *priv)
{
	return 0;
}

static int nfcmrvl_i2c_nci_send(struct nfcmrvl_private *priv,
				struct sk_buff *skb)
{
	struct nfcmrvl_i2c_drv_data *drv_data = priv->drv_data;
	int ret;

	if (test_bit(NFCMRVL_PHY_ERROR, &priv->flags)) {
		kfree_skb(skb);
		return -EREMOTEIO;
	}

	ret = i2c_master_send(drv_data->i2c, skb->data, skb->len);

	/* Retry if chip was in standby */
	if (ret == -EREMOTEIO) {
		nfc_info(drv_data->dev, "chip may sleep, retry\n");
		usleep_range(6000, 10000);
		ret = i2c_master_send(drv_data->i2c, skb->data, skb->len);
	}

	if (ret >= 0) {
		if (ret != skb->len) {
			nfc_err(drv_data->dev,
				"Invalid length sent: %u (expected %u)\n",
				ret, skb->len);
			ret = -EREMOTEIO;
		} else
			ret = 0;
	}

	if (ret) {
		kfree_skb(skb);
		return ret;
	}

	consume_skb(skb);
	return 0;
}

static void nfcmrvl_i2c_nci_update_config(struct nfcmrvl_private *priv,
					  const void *param)
{
}

static const struct nfcmrvl_if_ops i2c_ops = {
	.nci_open = nfcmrvl_i2c_nci_open,
	.nci_close = nfcmrvl_i2c_nci_close,
	.nci_send = nfcmrvl_i2c_nci_send,
	.nci_update_config = nfcmrvl_i2c_nci_update_config,
};

static int nfcmrvl_i2c_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;
	}

	if (of_find_property(node, "i2c-int-falling", NULL))
		pdata->irq_polarity = IRQF_TRIGGER_FALLING;
	else
		pdata->irq_polarity = IRQF_TRIGGER_RISING;

	ret = irq_of_parse_and_map(node, 0);
	if (!ret) {
		pr_err("Unable to get irq\n");
		return -EINVAL;
	}
	pdata->irq = ret;

	return 0;
}

static int nfcmrvl_i2c_probe(struct i2c_client *client)
{
	const struct nfcmrvl_platform_data *pdata;
	struct nfcmrvl_i2c_drv_data *drv_data;
	struct nfcmrvl_platform_data config;
	int ret;

	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
		nfc_err(&client->dev, "Need I2C_FUNC_I2C\n");
		return -ENODEV;
	}

	drv_data = devm_kzalloc(&client->dev, sizeof(*drv_data), GFP_KERNEL);
	if (!drv_data)
		return -ENOMEM;

	drv_data->i2c = client;
	drv_data->dev = &client->dev;
	drv_data->priv = NULL;

	i2c_set_clientdata(client, drv_data);

	pdata = client->dev.platform_data;

	if (!pdata && client->dev.of_node)
		if (nfcmrvl_i2c_parse_dt(client->dev.of_node, &config) == 0)
			pdata = &config;

	if (!pdata)
		return -EINVAL;

	/* Request the read IRQ */
	ret = devm_request_threaded_irq(&drv_data->i2c->dev, pdata->irq,
					NULL, nfcmrvl_i2c_int_irq_thread_fn,
					pdata->irq_polarity | IRQF_ONESHOT,
					"nfcmrvl_i2c_int", drv_data);
	if (ret < 0) {
		nfc_err(&drv_data->i2c->dev,
			"Unable to register IRQ handler\n");
		return ret;
	}

	drv_data->priv = nfcmrvl_nci_register_dev(NFCMRVL_PHY_I2C,
						  drv_data, &i2c_ops,
						  &drv_data->i2c->dev, pdata);

	if (IS_ERR(drv_data->priv))
		return PTR_ERR(drv_data->priv);

	drv_data->priv->support_fw_dnld = true;

	return 0;
}

static void nfcmrvl_i2c_remove(struct i2c_client *client)
{
	struct nfcmrvl_i2c_drv_data *drv_data = i2c_get_clientdata(client);

	nfcmrvl_nci_unregister_dev(drv_data->priv);
}


static const struct of_device_id of_nfcmrvl_i2c_match[] __maybe_unused = {
	{ .compatible = "marvell,nfc-i2c", },
	{},
};
MODULE_DEVICE_TABLE(of, of_nfcmrvl_i2c_match);

static const struct i2c_device_id nfcmrvl_i2c_id_table[] = {
	{ "nfcmrvl_i2c", 0 },
	{}
};
MODULE_DEVICE_TABLE(i2c, nfcmrvl_i2c_id_table);

static struct i2c_driver nfcmrvl_i2c_driver = {
	.probe_new = nfcmrvl_i2c_probe,
	.id_table = nfcmrvl_i2c_id_table,
	.remove = nfcmrvl_i2c_remove,
	.driver = {
		.name		= "nfcmrvl_i2c",
		.of_match_table	= of_match_ptr(of_nfcmrvl_i2c_match),
	},
};

module_i2c_driver(nfcmrvl_i2c_driver);

MODULE_AUTHOR("Marvell International Ltd.");
MODULE_DESCRIPTION("Marvell NFC-over-I2C driver");
MODULE_LICENSE("GPL v2");
