/*
 * Copyright (c) 2015 - 2016 Red Hat, Inc
 * Copyright (c) 2011, 2012 Synaptics Incorporated
 * Copyright (c) 2011 Unixphere
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 as published by
 * the Free Software Foundation.
 */

#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/i2c.h>
#include <linux/interrupt.h>
#include <linux/kconfig.h>
#include <linux/lockdep.h>
#include <linux/module.h>
#include <linux/pm.h>
#include <linux/rmi.h>
#include <linux/slab.h>
#include "rmi_driver.h"

#define SMB_PROTOCOL_VERSION_ADDRESS	0xfd
#define SMB_MAX_COUNT			32
#define RMI_SMB2_MAP_SIZE		8 /* 8 entry of 4 bytes each */
#define RMI_SMB2_MAP_FLAGS_WE		0x01

struct mapping_table_entry {
	__le16 rmiaddr;
	u8 readcount;
	u8 flags;
};

struct rmi_smb_xport {
	struct rmi_transport_dev xport;
	struct i2c_client *client;

	struct mutex page_mutex;
	int page;
	u8 table_index;
	struct mutex mappingtable_mutex;
	struct mapping_table_entry mapping_table[RMI_SMB2_MAP_SIZE];
};

static int rmi_smb_get_version(struct rmi_smb_xport *rmi_smb)
{
	struct i2c_client *client = rmi_smb->client;
	int retval;

	/* Check if for SMBus new version device by reading version byte. */
	retval = i2c_smbus_read_byte_data(client, SMB_PROTOCOL_VERSION_ADDRESS);
	if (retval < 0) {
		dev_err(&client->dev, "failed to get SMBus version number!\n");
		return retval;
	}
	return retval + 1;
}

/* SMB block write - wrapper over ic2_smb_write_block */
static int smb_block_write(struct rmi_transport_dev *xport,
			      u8 commandcode, const void *buf, size_t len)
{
	struct rmi_smb_xport *rmi_smb =
		container_of(xport, struct rmi_smb_xport, xport);
	struct i2c_client *client = rmi_smb->client;
	int retval;

	retval = i2c_smbus_write_block_data(client, commandcode, len, buf);

	rmi_dbg(RMI_DEBUG_XPORT, &client->dev,
		"wrote %zd bytes at %#04x: %d (%*ph)\n",
		len, commandcode, retval, (int)len, buf);

	return retval;
}

/*
 * The function to get command code for smbus operations and keeps
 * records to the driver mapping table
 */
static int rmi_smb_get_command_code(struct rmi_transport_dev *xport,
		u16 rmiaddr, int bytecount, bool isread, u8 *commandcode)
{
	struct rmi_smb_xport *rmi_smb =
		container_of(xport, struct rmi_smb_xport, xport);
	int i;
	int retval;
	struct mapping_table_entry mapping_data[1];

	mutex_lock(&rmi_smb->mappingtable_mutex);
	for (i = 0; i < RMI_SMB2_MAP_SIZE; i++) {
		if (rmi_smb->mapping_table[i].rmiaddr == rmiaddr) {
			if (isread) {
				if (rmi_smb->mapping_table[i].readcount
							== bytecount) {
					*commandcode = i;
					retval = 0;
					goto exit;
				}
			} else {
				if (rmi_smb->mapping_table[i].flags &
							RMI_SMB2_MAP_FLAGS_WE) {
					*commandcode = i;
					retval = 0;
					goto exit;
				}
			}
		}
	}
	i = rmi_smb->table_index;
	rmi_smb->table_index = (i + 1) % RMI_SMB2_MAP_SIZE;

	/* constructs mapping table data entry. 4 bytes each entry */
	memset(mapping_data, 0, sizeof(mapping_data));

	mapping_data[0].rmiaddr = cpu_to_le16(rmiaddr);
	mapping_data[0].readcount = bytecount;
	mapping_data[0].flags = !isread ? RMI_SMB2_MAP_FLAGS_WE : 0;

	retval = smb_block_write(xport, i + 0x80, mapping_data,
				 sizeof(mapping_data));

	if (retval < 0) {
		/*
		 * if not written to device mapping table
		 * clear the driver mapping table records
		 */
		rmi_smb->mapping_table[i].rmiaddr = 0x0000;
		rmi_smb->mapping_table[i].readcount = 0;
		rmi_smb->mapping_table[i].flags = 0;
		goto exit;
	}
	/* save to the driver level mapping table */
	rmi_smb->mapping_table[i].rmiaddr = rmiaddr;
	rmi_smb->mapping_table[i].readcount = bytecount;
	rmi_smb->mapping_table[i].flags = !isread ? RMI_SMB2_MAP_FLAGS_WE : 0;
	*commandcode = i;

exit:
	mutex_unlock(&rmi_smb->mappingtable_mutex);

	return retval;
}

static int rmi_smb_write_block(struct rmi_transport_dev *xport, u16 rmiaddr,
				const void *databuff, size_t len)
{
	int retval = 0;
	u8 commandcode;
	struct rmi_smb_xport *rmi_smb =
		container_of(xport, struct rmi_smb_xport, xport);
	int cur_len = (int)len;

	mutex_lock(&rmi_smb->page_mutex);

	while (cur_len > 0) {
		/*
		 * break into 32 bytes chunks to write get command code
		 */
		int block_len = min_t(int, len, SMB_MAX_COUNT);

		retval = rmi_smb_get_command_code(xport, rmiaddr, block_len,
						  false, &commandcode);
		if (retval < 0)
			goto exit;

		retval = smb_block_write(xport, commandcode,
					 databuff, block_len);
		if (retval < 0)
			goto exit;

		/* prepare to write next block of bytes */
		cur_len -= SMB_MAX_COUNT;
		databuff += SMB_MAX_COUNT;
		rmiaddr += SMB_MAX_COUNT;
	}
exit:
	mutex_unlock(&rmi_smb->page_mutex);
	return retval;
}

/* SMB block read - wrapper over ic2_smb_read_block */
static int smb_block_read(struct rmi_transport_dev *xport,
			     u8 commandcode, void *buf, size_t len)
{
	struct rmi_smb_xport *rmi_smb =
		container_of(xport, struct rmi_smb_xport, xport);
	struct i2c_client *client = rmi_smb->client;
	int retval;

	retval = i2c_smbus_read_block_data(client, commandcode, buf);
	if (retval < 0)
		return retval;

	return retval;
}

static int rmi_smb_read_block(struct rmi_transport_dev *xport, u16 rmiaddr,
			      void *databuff, size_t len)
{
	struct rmi_smb_xport *rmi_smb =
		container_of(xport, struct rmi_smb_xport, xport);
	int retval;
	u8 commandcode;
	int cur_len = (int)len;

	mutex_lock(&rmi_smb->page_mutex);
	memset(databuff, 0, len);

	while (cur_len > 0) {
		/* break into 32 bytes chunks to write get command code */
		int block_len =  min_t(int, cur_len, SMB_MAX_COUNT);

		retval = rmi_smb_get_command_code(xport, rmiaddr, block_len,
						  true, &commandcode);
		if (retval < 0)
			goto exit;

		retval = smb_block_read(xport, commandcode,
					databuff, block_len);
		if (retval < 0)
			goto exit;

		/* prepare to read next block of bytes */
		cur_len -= SMB_MAX_COUNT;
		databuff += SMB_MAX_COUNT;
		rmiaddr += SMB_MAX_COUNT;
	}

	retval = 0;

exit:
	mutex_unlock(&rmi_smb->page_mutex);
	return retval;
}

static void rmi_smb_clear_state(struct rmi_smb_xport *rmi_smb)
{
	/* the mapping table has been flushed, discard the current one */
	mutex_lock(&rmi_smb->mappingtable_mutex);
	memset(rmi_smb->mapping_table, 0, sizeof(rmi_smb->mapping_table));
	mutex_unlock(&rmi_smb->mappingtable_mutex);
}

static int rmi_smb_enable_smbus_mode(struct rmi_smb_xport *rmi_smb)
{
	int retval;

	/* we need to get the smbus version to activate the touchpad */
	retval = rmi_smb_get_version(rmi_smb);
	if (retval < 0)
		return retval;

	return 0;
}

static int rmi_smb_reset(struct rmi_transport_dev *xport, u16 reset_addr)
{
	struct rmi_smb_xport *rmi_smb =
		container_of(xport, struct rmi_smb_xport, xport);

	rmi_smb_clear_state(rmi_smb);

	/*
	 * we do not call the actual reset command, it has to be handled in
	 * PS/2 or there will be races between PS/2 and SMBus.
	 * PS/2 should ensure that a psmouse_reset is called before
	 * intializing the device and after it has been removed to be in a known
	 * state.
	 */
	return rmi_smb_enable_smbus_mode(rmi_smb);
}

static const struct rmi_transport_ops rmi_smb_ops = {
	.write_block	= rmi_smb_write_block,
	.read_block	= rmi_smb_read_block,
	.reset		= rmi_smb_reset,
};

static int rmi_smb_probe(struct i2c_client *client,
			 const struct i2c_device_id *id)
{
	struct rmi_device_platform_data *pdata = dev_get_platdata(&client->dev);
	struct rmi_smb_xport *rmi_smb;
	int retval;
	int smbus_version;

	if (!i2c_check_functionality(client->adapter,
				     I2C_FUNC_SMBUS_READ_BLOCK_DATA |
				     I2C_FUNC_SMBUS_HOST_NOTIFY)) {
		dev_err(&client->dev,
			"adapter does not support required functionality.\n");
		return -ENODEV;
	}

	if (client->irq <= 0) {
		dev_err(&client->dev, "no IRQ provided, giving up.\n");
		return client->irq ? client->irq : -ENODEV;
	}

	rmi_smb = devm_kzalloc(&client->dev, sizeof(struct rmi_smb_xport),
				GFP_KERNEL);
	if (!rmi_smb)
		return -ENOMEM;

	if (!pdata) {
		dev_err(&client->dev, "no platform data, aborting\n");
		return -ENOMEM;
	}

	rmi_dbg(RMI_DEBUG_XPORT, &client->dev, "Probing %s.\n",
		dev_name(&client->dev));

	rmi_smb->client = client;
	mutex_init(&rmi_smb->page_mutex);
	mutex_init(&rmi_smb->mappingtable_mutex);

	rmi_smb->xport.dev = &client->dev;
	rmi_smb->xport.pdata = *pdata;
	rmi_smb->xport.pdata.irq = client->irq;
	rmi_smb->xport.proto_name = "smb2";
	rmi_smb->xport.ops = &rmi_smb_ops;

	retval = rmi_smb_get_version(rmi_smb);
	if (retval < 0)
		return retval;

	smbus_version = retval;
	rmi_dbg(RMI_DEBUG_XPORT, &client->dev, "Smbus version is %d",
		smbus_version);

	if (smbus_version != 2) {
		dev_err(&client->dev, "Unrecognized SMB version %d.\n",
				smbus_version);
		return -ENODEV;
	}

	i2c_set_clientdata(client, rmi_smb);

	retval = rmi_register_transport_device(&rmi_smb->xport);
	if (retval) {
		dev_err(&client->dev, "Failed to register transport driver at 0x%.2X.\n",
			client->addr);
		i2c_set_clientdata(client, NULL);
		return retval;
	}

	dev_info(&client->dev, "registered rmi smb driver at %#04x.\n",
			client->addr);
	return 0;

}

static int rmi_smb_remove(struct i2c_client *client)
{
	struct rmi_smb_xport *rmi_smb = i2c_get_clientdata(client);

	rmi_unregister_transport_device(&rmi_smb->xport);

	return 0;
}

static int __maybe_unused rmi_smb_suspend(struct device *dev)
{
	struct i2c_client *client = to_i2c_client(dev);
	struct rmi_smb_xport *rmi_smb = i2c_get_clientdata(client);
	int ret;

	ret = rmi_driver_suspend(rmi_smb->xport.rmi_dev, true);
	if (ret)
		dev_warn(dev, "Failed to suspend device: %d\n", ret);

	return ret;
}

static int __maybe_unused rmi_smb_runtime_suspend(struct device *dev)
{
	struct i2c_client *client = to_i2c_client(dev);
	struct rmi_smb_xport *rmi_smb = i2c_get_clientdata(client);
	int ret;

	ret = rmi_driver_suspend(rmi_smb->xport.rmi_dev, false);
	if (ret)
		dev_warn(dev, "Failed to suspend device: %d\n", ret);

	return ret;
}

static int __maybe_unused rmi_smb_resume(struct device *dev)
{
	struct i2c_client *client = container_of(dev, struct i2c_client, dev);
	struct rmi_smb_xport *rmi_smb = i2c_get_clientdata(client);
	struct rmi_device *rmi_dev = rmi_smb->xport.rmi_dev;
	int ret;

	rmi_smb_reset(&rmi_smb->xport, 0);

	rmi_reset(rmi_dev);

	ret = rmi_driver_resume(rmi_smb->xport.rmi_dev, true);
	if (ret)
		dev_warn(dev, "Failed to resume device: %d\n", ret);

	return 0;
}

static int __maybe_unused rmi_smb_runtime_resume(struct device *dev)
{
	struct i2c_client *client = to_i2c_client(dev);
	struct rmi_smb_xport *rmi_smb = i2c_get_clientdata(client);
	int ret;

	ret = rmi_driver_resume(rmi_smb->xport.rmi_dev, false);
	if (ret)
		dev_warn(dev, "Failed to resume device: %d\n", ret);

	return 0;
}

static const struct dev_pm_ops rmi_smb_pm = {
	SET_SYSTEM_SLEEP_PM_OPS(rmi_smb_suspend, rmi_smb_resume)
	SET_RUNTIME_PM_OPS(rmi_smb_runtime_suspend, rmi_smb_runtime_resume,
			   NULL)
};

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

static struct i2c_driver rmi_smb_driver = {
	.driver = {
		.name	= "rmi4_smbus",
		.pm	= &rmi_smb_pm,
	},
	.id_table	= rmi_id,
	.probe		= rmi_smb_probe,
	.remove		= rmi_smb_remove,
};

module_i2c_driver(rmi_smb_driver);

MODULE_AUTHOR("Andrew Duggan <aduggan@synaptics.com>");
MODULE_AUTHOR("Benjamin Tissoires <benjamin.tissoires@redhat.com>");
MODULE_DESCRIPTION("RMI4 SMBus driver");
MODULE_LICENSE("GPL");
