// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * mcs5000_ts.c - Touchscreen driver for MELFAS MCS-5000 controller
 *
 * Copyright (C) 2009 Samsung Electronics Co.Ltd
 * Author: Joonyoung Shim <jy0922.shim@samsung.com>
 *
 * Based on wm97xx-core.c
 */

#include <linux/module.h>
#include <linux/i2c.h>
#include <linux/interrupt.h>
#include <linux/input.h>
#include <linux/irq.h>
#include <linux/platform_data/mcs.h>
#include <linux/slab.h>

/* Registers */
#define MCS5000_TS_STATUS		0x00
#define STATUS_OFFSET			0
#define STATUS_NO			(0 << STATUS_OFFSET)
#define STATUS_INIT			(1 << STATUS_OFFSET)
#define STATUS_SENSING			(2 << STATUS_OFFSET)
#define STATUS_COORD			(3 << STATUS_OFFSET)
#define STATUS_GESTURE			(4 << STATUS_OFFSET)
#define ERROR_OFFSET			4
#define ERROR_NO			(0 << ERROR_OFFSET)
#define ERROR_POWER_ON_RESET		(1 << ERROR_OFFSET)
#define ERROR_INT_RESET			(2 << ERROR_OFFSET)
#define ERROR_EXT_RESET			(3 << ERROR_OFFSET)
#define ERROR_INVALID_REG_ADDRESS	(8 << ERROR_OFFSET)
#define ERROR_INVALID_REG_VALUE		(9 << ERROR_OFFSET)

#define MCS5000_TS_OP_MODE		0x01
#define RESET_OFFSET			0
#define RESET_NO			(0 << RESET_OFFSET)
#define RESET_EXT_SOFT			(1 << RESET_OFFSET)
#define OP_MODE_OFFSET			1
#define OP_MODE_SLEEP			(0 << OP_MODE_OFFSET)
#define OP_MODE_ACTIVE			(1 << OP_MODE_OFFSET)
#define GESTURE_OFFSET			4
#define GESTURE_DISABLE			(0 << GESTURE_OFFSET)
#define GESTURE_ENABLE			(1 << GESTURE_OFFSET)
#define PROXIMITY_OFFSET		5
#define PROXIMITY_DISABLE		(0 << PROXIMITY_OFFSET)
#define PROXIMITY_ENABLE		(1 << PROXIMITY_OFFSET)
#define SCAN_MODE_OFFSET		6
#define SCAN_MODE_INTERRUPT		(0 << SCAN_MODE_OFFSET)
#define SCAN_MODE_POLLING		(1 << SCAN_MODE_OFFSET)
#define REPORT_RATE_OFFSET		7
#define REPORT_RATE_40			(0 << REPORT_RATE_OFFSET)
#define REPORT_RATE_80			(1 << REPORT_RATE_OFFSET)

#define MCS5000_TS_SENS_CTL		0x02
#define MCS5000_TS_FILTER_CTL		0x03
#define PRI_FILTER_OFFSET		0
#define SEC_FILTER_OFFSET		4

#define MCS5000_TS_X_SIZE_UPPER		0x08
#define MCS5000_TS_X_SIZE_LOWER		0x09
#define MCS5000_TS_Y_SIZE_UPPER		0x0A
#define MCS5000_TS_Y_SIZE_LOWER		0x0B

#define MCS5000_TS_INPUT_INFO		0x10
#define INPUT_TYPE_OFFSET		0
#define INPUT_TYPE_NONTOUCH		(0 << INPUT_TYPE_OFFSET)
#define INPUT_TYPE_SINGLE		(1 << INPUT_TYPE_OFFSET)
#define INPUT_TYPE_DUAL			(2 << INPUT_TYPE_OFFSET)
#define INPUT_TYPE_PALM			(3 << INPUT_TYPE_OFFSET)
#define INPUT_TYPE_PROXIMITY		(7 << INPUT_TYPE_OFFSET)
#define GESTURE_CODE_OFFSET		3
#define GESTURE_CODE_NO			(0 << GESTURE_CODE_OFFSET)

#define MCS5000_TS_X_POS_UPPER		0x11
#define MCS5000_TS_X_POS_LOWER		0x12
#define MCS5000_TS_Y_POS_UPPER		0x13
#define MCS5000_TS_Y_POS_LOWER		0x14
#define MCS5000_TS_Z_POS		0x15
#define MCS5000_TS_WIDTH		0x16
#define MCS5000_TS_GESTURE_VAL		0x17
#define MCS5000_TS_MODULE_REV		0x20
#define MCS5000_TS_FIRMWARE_VER		0x21

/* Touchscreen absolute values */
#define MCS5000_MAX_XC			0x3ff
#define MCS5000_MAX_YC			0x3ff

enum mcs5000_ts_read_offset {
	READ_INPUT_INFO,
	READ_X_POS_UPPER,
	READ_X_POS_LOWER,
	READ_Y_POS_UPPER,
	READ_Y_POS_LOWER,
	READ_BLOCK_SIZE,
};

/* Each client has this additional data */
struct mcs5000_ts_data {
	struct i2c_client *client;
	struct input_dev *input_dev;
	const struct mcs_platform_data *platform_data;
};

static irqreturn_t mcs5000_ts_interrupt(int irq, void *dev_id)
{
	struct mcs5000_ts_data *data = dev_id;
	struct i2c_client *client = data->client;
	u8 buffer[READ_BLOCK_SIZE];
	int err;
	int x;
	int y;

	err = i2c_smbus_read_i2c_block_data(client, MCS5000_TS_INPUT_INFO,
			READ_BLOCK_SIZE, buffer);
	if (err < 0) {
		dev_err(&client->dev, "%s, err[%d]\n", __func__, err);
		goto out;
	}

	switch (buffer[READ_INPUT_INFO]) {
	case INPUT_TYPE_NONTOUCH:
		input_report_key(data->input_dev, BTN_TOUCH, 0);
		input_sync(data->input_dev);
		break;

	case INPUT_TYPE_SINGLE:
		x = (buffer[READ_X_POS_UPPER] << 8) | buffer[READ_X_POS_LOWER];
		y = (buffer[READ_Y_POS_UPPER] << 8) | buffer[READ_Y_POS_LOWER];

		input_report_key(data->input_dev, BTN_TOUCH, 1);
		input_report_abs(data->input_dev, ABS_X, x);
		input_report_abs(data->input_dev, ABS_Y, y);
		input_sync(data->input_dev);
		break;

	case INPUT_TYPE_DUAL:
		/* TODO */
		break;

	case INPUT_TYPE_PALM:
		/* TODO */
		break;

	case INPUT_TYPE_PROXIMITY:
		/* TODO */
		break;

	default:
		dev_err(&client->dev, "Unknown ts input type %d\n",
				buffer[READ_INPUT_INFO]);
		break;
	}

 out:
	return IRQ_HANDLED;
}

static void mcs5000_ts_phys_init(struct mcs5000_ts_data *data,
				 const struct mcs_platform_data *platform_data)
{
	struct i2c_client *client = data->client;

	/* Touch reset & sleep mode */
	i2c_smbus_write_byte_data(client, MCS5000_TS_OP_MODE,
			RESET_EXT_SOFT | OP_MODE_SLEEP);

	/* Touch size */
	i2c_smbus_write_byte_data(client, MCS5000_TS_X_SIZE_UPPER,
			platform_data->x_size >> 8);
	i2c_smbus_write_byte_data(client, MCS5000_TS_X_SIZE_LOWER,
			platform_data->x_size & 0xff);
	i2c_smbus_write_byte_data(client, MCS5000_TS_Y_SIZE_UPPER,
			platform_data->y_size >> 8);
	i2c_smbus_write_byte_data(client, MCS5000_TS_Y_SIZE_LOWER,
			platform_data->y_size & 0xff);

	/* Touch active mode & 80 report rate */
	i2c_smbus_write_byte_data(data->client, MCS5000_TS_OP_MODE,
			OP_MODE_ACTIVE | REPORT_RATE_80);
}

static int mcs5000_ts_probe(struct i2c_client *client,
			    const struct i2c_device_id *id)
{
	const struct mcs_platform_data *pdata;
	struct mcs5000_ts_data *data;
	struct input_dev *input_dev;
	int error;

	pdata = dev_get_platdata(&client->dev);
	if (!pdata)
		return -EINVAL;

	data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL);
	if (!data) {
		dev_err(&client->dev, "Failed to allocate memory\n");
		return -ENOMEM;
	}

	data->client = client;

	input_dev = devm_input_allocate_device(&client->dev);
	if (!input_dev) {
		dev_err(&client->dev, "Failed to allocate input device\n");
		return -ENOMEM;
	}

	input_dev->name = "MELFAS MCS-5000 Touchscreen";
	input_dev->id.bustype = BUS_I2C;
	input_dev->dev.parent = &client->dev;

	__set_bit(EV_ABS, input_dev->evbit);
	__set_bit(EV_KEY, input_dev->evbit);
	__set_bit(BTN_TOUCH, input_dev->keybit);
	input_set_abs_params(input_dev, ABS_X, 0, MCS5000_MAX_XC, 0, 0);
	input_set_abs_params(input_dev, ABS_Y, 0, MCS5000_MAX_YC, 0, 0);

	data->input_dev = input_dev;

	if (pdata->cfg_pin)
		pdata->cfg_pin();

	error = devm_request_threaded_irq(&client->dev, client->irq,
					  NULL, mcs5000_ts_interrupt,
					  IRQF_TRIGGER_LOW | IRQF_ONESHOT,
					  "mcs5000_ts", data);
	if (error) {
		dev_err(&client->dev, "Failed to register interrupt\n");
		return error;
	}

	error = input_register_device(data->input_dev);
	if (error) {
		dev_err(&client->dev, "Failed to register input device\n");
		return error;
	}

	mcs5000_ts_phys_init(data, pdata);
	i2c_set_clientdata(client, data);

	return 0;
}

static int __maybe_unused mcs5000_ts_suspend(struct device *dev)
{
	struct i2c_client *client = to_i2c_client(dev);

	/* Touch sleep mode */
	i2c_smbus_write_byte_data(client, MCS5000_TS_OP_MODE, OP_MODE_SLEEP);

	return 0;
}

static int __maybe_unused mcs5000_ts_resume(struct device *dev)
{
	struct i2c_client *client = to_i2c_client(dev);
	struct mcs5000_ts_data *data = i2c_get_clientdata(client);
	const struct mcs_platform_data *pdata = dev_get_platdata(dev);

	mcs5000_ts_phys_init(data, pdata);

	return 0;
}

static SIMPLE_DEV_PM_OPS(mcs5000_ts_pm, mcs5000_ts_suspend, mcs5000_ts_resume);

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

static struct i2c_driver mcs5000_ts_driver = {
	.probe		= mcs5000_ts_probe,
	.driver = {
		.name = "mcs5000_ts",
		.pm   = &mcs5000_ts_pm,
	},
	.id_table	= mcs5000_ts_id,
};

module_i2c_driver(mcs5000_ts_driver);

/* Module information */
MODULE_AUTHOR("Joonyoung Shim <jy0922.shim@samsung.com>");
MODULE_DESCRIPTION("Touchscreen driver for MELFAS MCS-5000 controller");
MODULE_LICENSE("GPL");
