// SPDX-License-Identifier: GPL-2.0
/*
 * ILITEK Touch IC driver for 23XX, 25XX and Lego series
 *
 * Copyright (C) 2011 ILI Technology Corporation.
 * Copyright (C) 2020 Luca Hsu <luca_hsu@ilitek.com>
 * Copyright (C) 2021 Joe Hung <joe_hung@ilitek.com>
 */

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/input.h>
#include <linux/input/mt.h>
#include <linux/i2c.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/gpio/consumer.h>
#include <linux/errno.h>
#include <linux/acpi.h>
#include <linux/input/touchscreen.h>
#include <linux/unaligned.h>


#define ILITEK_TS_NAME					"ilitek_ts"
#define BL_V1_8						0x108
#define BL_V1_7						0x107
#define BL_V1_6						0x106

#define ILITEK_TP_CMD_GET_TP_RES			0x20
#define ILITEK_TP_CMD_GET_SCRN_RES			0x21
#define ILITEK_TP_CMD_SET_IC_SLEEP			0x30
#define ILITEK_TP_CMD_SET_IC_WAKE			0x31
#define ILITEK_TP_CMD_GET_FW_VER			0x40
#define ILITEK_TP_CMD_GET_PRL_VER			0x42
#define ILITEK_TP_CMD_GET_MCU_VER			0x61
#define ILITEK_TP_CMD_GET_IC_MODE			0xC0

#define ILITEK_TP_I2C_REPORT_ID				0x48

#define REPORT_COUNT_ADDRESS				61
#define ILITEK_SUPPORT_MAX_POINT			40

struct ilitek_protocol_info {
	u16 ver;
	u8 ver_major;
};

struct ilitek_ts_data {
	struct i2c_client		*client;
	struct gpio_desc		*reset_gpio;
	struct input_dev		*input_dev;
	struct touchscreen_properties	prop;

	const struct ilitek_protocol_map *ptl_cb_func;
	struct ilitek_protocol_info	ptl;

	char				product_id[30];
	u16				mcu_ver;
	u8				ic_mode;
	u8				firmware_ver[8];

	s32				reset_time;
	s32				screen_max_x;
	s32				screen_max_y;
	s32				screen_min_x;
	s32				screen_min_y;
	s32				max_tp;
};

struct ilitek_protocol_map {
	u16 cmd;
	const char *name;
	int (*func)(struct ilitek_ts_data *ts, u16 cmd, u8 *inbuf, u8 *outbuf);
};

enum ilitek_cmds {
	/* common cmds */
	GET_PTL_VER = 0,
	GET_FW_VER,
	GET_SCRN_RES,
	GET_TP_RES,
	GET_IC_MODE,
	GET_MCU_VER,
	SET_IC_SLEEP,
	SET_IC_WAKE,

	/* ALWAYS keep at the end */
	MAX_CMD_CNT
};

/* ILITEK I2C R/W APIs */
static int ilitek_i2c_write_and_read(struct ilitek_ts_data *ts,
				     u8 *cmd, int write_len, int delay,
				     u8 *data, int read_len)
{
	int error;
	struct i2c_client *client = ts->client;
	struct i2c_msg msgs[] = {
		{
			.addr = client->addr,
			.flags = 0,
			.len = write_len,
			.buf = cmd,
		},
		{
			.addr = client->addr,
			.flags = I2C_M_RD,
			.len = read_len,
			.buf = data,
		},
	};

	if (delay == 0 && write_len > 0 && read_len > 0) {
		error = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
		if (error < 0)
			return error;
	} else {
		if (write_len > 0) {
			error = i2c_transfer(client->adapter, msgs, 1);
			if (error < 0)
				return error;
		}
		if (delay > 0)
			mdelay(delay);

		if (read_len > 0) {
			error = i2c_transfer(client->adapter, msgs + 1, 1);
			if (error < 0)
				return error;
		}
	}

	return 0;
}

/* ILITEK ISR APIs */
static void ilitek_touch_down(struct ilitek_ts_data *ts, unsigned int id,
			      unsigned int x, unsigned int y)
{
	struct input_dev *input = ts->input_dev;

	input_mt_slot(input, id);
	input_mt_report_slot_state(input, MT_TOOL_FINGER, true);

	touchscreen_report_pos(input, &ts->prop, x, y, true);
}

static int ilitek_process_and_report_v6(struct ilitek_ts_data *ts)
{
	int error = 0;
	u8 buf[512];
	int packet_len = 5;
	int packet_max_point = 10;
	int report_max_point;
	int i, count;
	struct input_dev *input = ts->input_dev;
	struct device *dev = &ts->client->dev;
	unsigned int x, y, status, id;

	error = ilitek_i2c_write_and_read(ts, NULL, 0, 0, buf, 64);
	if (error) {
		dev_err(dev, "get touch info failed, err:%d\n", error);
		return error;
	}

	if (buf[0] != ILITEK_TP_I2C_REPORT_ID) {
		dev_err(dev, "get touch info failed. Wrong id: 0x%02X\n", buf[0]);
		return -EINVAL;
	}

	report_max_point = buf[REPORT_COUNT_ADDRESS];
	if (report_max_point > ts->max_tp) {
		dev_err(dev, "FW report max point:%d > panel info. max:%d\n",
			report_max_point, ts->max_tp);
		return -EINVAL;
	}

	count = DIV_ROUND_UP(report_max_point, packet_max_point);
	for (i = 1; i < count; i++) {
		error = ilitek_i2c_write_and_read(ts, NULL, 0, 0,
						  buf + i * 64, 64);
		if (error) {
			dev_err(dev, "get touch info. failed, cnt:%d, err:%d\n",
				count, error);
			return error;
		}
	}

	for (i = 0; i < report_max_point; i++) {
		status = buf[i * packet_len + 1] & 0x40;
		if (!status)
			continue;

		id = buf[i * packet_len + 1] & 0x3F;

		x = get_unaligned_le16(buf + i * packet_len + 2);
		y = get_unaligned_le16(buf + i * packet_len + 4);

		if (x > ts->screen_max_x || x < ts->screen_min_x ||
		    y > ts->screen_max_y || y < ts->screen_min_y) {
			dev_warn(dev, "invalid position, X[%d,%u,%d], Y[%d,%u,%d]\n",
				 ts->screen_min_x, x, ts->screen_max_x,
				 ts->screen_min_y, y, ts->screen_max_y);
			continue;
		}

		ilitek_touch_down(ts, id, x, y);
	}

	input_mt_sync_frame(input);
	input_sync(input);

	return 0;
}

/* APIs of cmds for ILITEK Touch IC */
static int api_protocol_set_cmd(struct ilitek_ts_data *ts,
				u16 idx, u8 *inbuf, u8 *outbuf)
{
	u16 cmd;
	int error;

	if (idx >= MAX_CMD_CNT)
		return -EINVAL;

	cmd = ts->ptl_cb_func[idx].cmd;
	error = ts->ptl_cb_func[idx].func(ts, cmd, inbuf, outbuf);
	if (error)
		return error;

	return 0;
}

static int api_protocol_get_ptl_ver(struct ilitek_ts_data *ts,
				    u16 cmd, u8 *inbuf, u8 *outbuf)
{
	int error;
	u8 buf[64];

	buf[0] = cmd;
	error = ilitek_i2c_write_and_read(ts, buf, 1, 5, outbuf, 3);
	if (error)
		return error;

	ts->ptl.ver = get_unaligned_be16(outbuf);
	ts->ptl.ver_major = outbuf[0];

	return 0;
}

static int api_protocol_get_mcu_ver(struct ilitek_ts_data *ts,
				    u16 cmd, u8 *inbuf, u8 *outbuf)
{
	int error;
	u8 buf[64];

	buf[0] = cmd;
	error = ilitek_i2c_write_and_read(ts, buf, 1, 5, outbuf, 32);
	if (error)
		return error;

	ts->mcu_ver = get_unaligned_le16(outbuf);
	memset(ts->product_id, 0, sizeof(ts->product_id));
	memcpy(ts->product_id, outbuf + 6, 26);

	return 0;
}

static int api_protocol_get_fw_ver(struct ilitek_ts_data *ts,
				   u16 cmd, u8 *inbuf, u8 *outbuf)
{
	int error;
	u8 buf[64];

	buf[0] = cmd;
	error = ilitek_i2c_write_and_read(ts, buf, 1, 5, outbuf, 8);
	if (error)
		return error;

	memcpy(ts->firmware_ver, outbuf, 8);

	return 0;
}

static int api_protocol_get_scrn_res(struct ilitek_ts_data *ts,
				     u16 cmd, u8 *inbuf, u8 *outbuf)
{
	int error;
	u8 buf[64];

	buf[0] = cmd;
	error = ilitek_i2c_write_and_read(ts, buf, 1, 5, outbuf, 8);
	if (error)
		return error;

	ts->screen_min_x = get_unaligned_le16(outbuf);
	ts->screen_min_y = get_unaligned_le16(outbuf + 2);
	ts->screen_max_x = get_unaligned_le16(outbuf + 4);
	ts->screen_max_y = get_unaligned_le16(outbuf + 6);

	return 0;
}

static int api_protocol_get_tp_res(struct ilitek_ts_data *ts,
				   u16 cmd, u8 *inbuf, u8 *outbuf)
{
	int error;
	u8 buf[64];

	buf[0] = cmd;
	error = ilitek_i2c_write_and_read(ts, buf, 1, 5, outbuf, 15);
	if (error)
		return error;

	ts->max_tp = outbuf[8];
	if (ts->max_tp > ILITEK_SUPPORT_MAX_POINT) {
		dev_err(&ts->client->dev, "Invalid MAX_TP:%d from FW\n",
			ts->max_tp);
		return -EINVAL;
	}

	return 0;
}

static int api_protocol_get_ic_mode(struct ilitek_ts_data *ts,
				    u16 cmd, u8 *inbuf, u8 *outbuf)
{
	int error;
	u8 buf[64];

	buf[0] = cmd;
	error = ilitek_i2c_write_and_read(ts, buf, 1, 5, outbuf, 2);
	if (error)
		return error;

	ts->ic_mode = outbuf[0];
	return 0;
}

static int api_protocol_set_ic_sleep(struct ilitek_ts_data *ts,
				     u16 cmd, u8 *inbuf, u8 *outbuf)
{
	u8 buf[64];

	buf[0] = cmd;
	return ilitek_i2c_write_and_read(ts, buf, 1, 0, NULL, 0);
}

static int api_protocol_set_ic_wake(struct ilitek_ts_data *ts,
				    u16 cmd, u8 *inbuf, u8 *outbuf)
{
	u8 buf[64];

	buf[0] = cmd;
	return ilitek_i2c_write_and_read(ts, buf, 1, 0, NULL, 0);
}

static const struct ilitek_protocol_map ptl_func_map[] = {
	/* common cmds */
	[GET_PTL_VER] = {
		ILITEK_TP_CMD_GET_PRL_VER, "GET_PTL_VER",
		api_protocol_get_ptl_ver
	},
	[GET_FW_VER] = {
		ILITEK_TP_CMD_GET_FW_VER, "GET_FW_VER",
		api_protocol_get_fw_ver
	},
	[GET_SCRN_RES] = {
		ILITEK_TP_CMD_GET_SCRN_RES, "GET_SCRN_RES",
		api_protocol_get_scrn_res
	},
	[GET_TP_RES] = {
		ILITEK_TP_CMD_GET_TP_RES, "GET_TP_RES",
		api_protocol_get_tp_res
	},
	[GET_IC_MODE] = {
		ILITEK_TP_CMD_GET_IC_MODE, "GET_IC_MODE",
			   api_protocol_get_ic_mode
	},
	[GET_MCU_VER] = {
		ILITEK_TP_CMD_GET_MCU_VER, "GET_MOD_VER",
			   api_protocol_get_mcu_ver
	},
	[SET_IC_SLEEP] = {
		ILITEK_TP_CMD_SET_IC_SLEEP, "SET_IC_SLEEP",
		api_protocol_set_ic_sleep
	},
	[SET_IC_WAKE] = {
		ILITEK_TP_CMD_SET_IC_WAKE, "SET_IC_WAKE",
		api_protocol_set_ic_wake
	},
};

/* Probe APIs */
static void ilitek_reset(struct ilitek_ts_data *ts, int delay)
{
	if (ts->reset_gpio) {
		gpiod_set_value(ts->reset_gpio, 1);
		mdelay(10);
		gpiod_set_value(ts->reset_gpio, 0);
		mdelay(delay);
	}
}

static int ilitek_protocol_init(struct ilitek_ts_data *ts)
{
	int error;
	u8 outbuf[64];

	ts->ptl_cb_func = ptl_func_map;
	ts->reset_time = 600;

	error = api_protocol_set_cmd(ts, GET_PTL_VER, NULL, outbuf);
	if (error)
		return error;

	/* Protocol v3 is not support currently */
	if (ts->ptl.ver_major == 0x3 ||
	    ts->ptl.ver == BL_V1_6 ||
	    ts->ptl.ver == BL_V1_7)
		return -EINVAL;

	return 0;
}

static int ilitek_read_tp_info(struct ilitek_ts_data *ts, bool boot)
{
	u8 outbuf[256];
	int error;

	error = api_protocol_set_cmd(ts, GET_PTL_VER, NULL, outbuf);
	if (error)
		return error;

	error = api_protocol_set_cmd(ts, GET_MCU_VER, NULL, outbuf);
	if (error)
		return error;

	error = api_protocol_set_cmd(ts, GET_FW_VER, NULL, outbuf);
	if (error)
		return error;

	if (boot) {
		error = api_protocol_set_cmd(ts, GET_SCRN_RES, NULL,
					     outbuf);
		if (error)
			return error;
	}

	error = api_protocol_set_cmd(ts, GET_TP_RES, NULL, outbuf);
	if (error)
		return error;

	error = api_protocol_set_cmd(ts, GET_IC_MODE, NULL, outbuf);
	if (error)
		return error;

	return 0;
}

static int ilitek_input_dev_init(struct device *dev, struct ilitek_ts_data *ts)
{
	int error;
	struct input_dev *input;

	input = devm_input_allocate_device(dev);
	if (!input)
		return -ENOMEM;

	ts->input_dev = input;
	input->name = ILITEK_TS_NAME;
	input->id.bustype = BUS_I2C;

	__set_bit(INPUT_PROP_DIRECT, input->propbit);

	input_set_abs_params(input, ABS_MT_POSITION_X,
			     ts->screen_min_x, ts->screen_max_x, 0, 0);
	input_set_abs_params(input, ABS_MT_POSITION_Y,
			     ts->screen_min_y, ts->screen_max_y, 0, 0);

	touchscreen_parse_properties(input, true, &ts->prop);

	error = input_mt_init_slots(input, ts->max_tp,
				    INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED);
	if (error) {
		dev_err(dev, "initialize MT slots failed, err:%d\n", error);
		return error;
	}

	error = input_register_device(input);
	if (error) {
		dev_err(dev, "register input device failed, err:%d\n", error);
		return error;
	}

	return 0;
}

static irqreturn_t ilitek_i2c_isr(int irq, void *dev_id)
{
	struct ilitek_ts_data *ts = dev_id;
	int error;

	error = ilitek_process_and_report_v6(ts);
	if (error < 0) {
		dev_err(&ts->client->dev, "[%s] err:%d\n", __func__, error);
		return IRQ_NONE;
	}

	return IRQ_HANDLED;
}

static ssize_t firmware_version_show(struct device *dev,
				     struct device_attribute *attr, char *buf)
{
	struct i2c_client *client = to_i2c_client(dev);
	struct ilitek_ts_data *ts = i2c_get_clientdata(client);

	return sysfs_emit(buf,
			  "fw version: [%02X%02X.%02X%02X.%02X%02X.%02X%02X]\n",
			  ts->firmware_ver[0], ts->firmware_ver[1],
			  ts->firmware_ver[2], ts->firmware_ver[3],
			  ts->firmware_ver[4], ts->firmware_ver[5],
			  ts->firmware_ver[6], ts->firmware_ver[7]);
}
static DEVICE_ATTR_RO(firmware_version);

static ssize_t product_id_show(struct device *dev,
			       struct device_attribute *attr, char *buf)
{
	struct i2c_client *client = to_i2c_client(dev);
	struct ilitek_ts_data *ts = i2c_get_clientdata(client);

	return sysfs_emit(buf, "product id: [%04X], module: [%s]\n",
			  ts->mcu_ver, ts->product_id);
}
static DEVICE_ATTR_RO(product_id);

static struct attribute *ilitek_sysfs_attrs[] = {
	&dev_attr_firmware_version.attr,
	&dev_attr_product_id.attr,
	NULL
};
ATTRIBUTE_GROUPS(ilitek_sysfs);

static int ilitek_ts_i2c_probe(struct i2c_client *client)
{
	struct ilitek_ts_data *ts;
	struct device *dev = &client->dev;
	int error;

	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
		dev_err(dev, "i2c check functionality failed\n");
		return -ENXIO;
	}

	ts = devm_kzalloc(dev, sizeof(*ts), GFP_KERNEL);
	if (!ts)
		return -ENOMEM;

	ts->client = client;
	i2c_set_clientdata(client, ts);

	ts->reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW);
	if (IS_ERR(ts->reset_gpio)) {
		error = PTR_ERR(ts->reset_gpio);
		dev_err(dev, "request gpiod failed: %d", error);
		return error;
	}

	ilitek_reset(ts, 1000);

	error = ilitek_protocol_init(ts);
	if (error) {
		dev_err(dev, "protocol init failed: %d", error);
		return error;
	}

	error = ilitek_read_tp_info(ts, true);
	if (error) {
		dev_err(dev, "read tp info failed: %d", error);
		return error;
	}

	error = ilitek_input_dev_init(dev, ts);
	if (error) {
		dev_err(dev, "input dev init failed: %d", error);
		return error;
	}

	error = devm_request_threaded_irq(dev, ts->client->irq,
					  NULL, ilitek_i2c_isr, IRQF_ONESHOT,
					  "ilitek_touch_irq", ts);
	if (error) {
		dev_err(dev, "request threaded irq failed: %d\n", error);
		return error;
	}

	return 0;
}

static int ilitek_suspend(struct device *dev)
{
	struct i2c_client *client = to_i2c_client(dev);
	struct ilitek_ts_data *ts = i2c_get_clientdata(client);
	int error;

	disable_irq(client->irq);

	if (!device_may_wakeup(dev)) {
		error = api_protocol_set_cmd(ts, SET_IC_SLEEP, NULL, NULL);
		if (error)
			return error;
	}

	return 0;
}

static int ilitek_resume(struct device *dev)
{
	struct i2c_client *client = to_i2c_client(dev);
	struct ilitek_ts_data *ts = i2c_get_clientdata(client);
	int error;

	if (!device_may_wakeup(dev)) {
		error = api_protocol_set_cmd(ts, SET_IC_WAKE, NULL, NULL);
		if (error)
			return error;

		ilitek_reset(ts, ts->reset_time);
	}

	enable_irq(client->irq);

	return 0;
}

static DEFINE_SIMPLE_DEV_PM_OPS(ilitek_pm_ops, ilitek_suspend, ilitek_resume);

static const struct i2c_device_id ilitek_ts_i2c_id[] = {
	{ ILITEK_TS_NAME },
	{ }
};
MODULE_DEVICE_TABLE(i2c, ilitek_ts_i2c_id);

#ifdef CONFIG_ACPI
static const struct acpi_device_id ilitekts_acpi_id[] = {
	{ "ILTK0001", 0 },
	{ },
};
MODULE_DEVICE_TABLE(acpi, ilitekts_acpi_id);
#endif

#ifdef CONFIG_OF
static const struct of_device_id ilitek_ts_i2c_match[] = {
	{.compatible = "ilitek,ili2130",},
	{.compatible = "ilitek,ili2131",},
	{.compatible = "ilitek,ili2132",},
	{.compatible = "ilitek,ili2316",},
	{.compatible = "ilitek,ili2322",},
	{.compatible = "ilitek,ili2323",},
	{.compatible = "ilitek,ili2326",},
	{.compatible = "ilitek,ili2520",},
	{.compatible = "ilitek,ili2521",},
	{ },
};
MODULE_DEVICE_TABLE(of, ilitek_ts_i2c_match);
#endif

static struct i2c_driver ilitek_ts_i2c_driver = {
	.driver = {
		.name = ILITEK_TS_NAME,
		.dev_groups = ilitek_sysfs_groups,
		.pm = pm_sleep_ptr(&ilitek_pm_ops),
		.of_match_table = of_match_ptr(ilitek_ts_i2c_match),
		.acpi_match_table = ACPI_PTR(ilitekts_acpi_id),
	},
	.probe = ilitek_ts_i2c_probe,
	.id_table = ilitek_ts_i2c_id,
};
module_i2c_driver(ilitek_ts_i2c_driver);

MODULE_AUTHOR("ILITEK");
MODULE_DESCRIPTION("ILITEK I2C Touchscreen Driver");
MODULE_LICENSE("GPL");
