// 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)
			fsleep(delay * 1000);

		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_cansleep(ts->reset_gpio, 1);
		fsleep(10000);
		gpiod_set_value_cansleep(ts->reset_gpio, 0);
		fsleep(delay * 1000);
	}
}

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");
