// SPDX-License-Identifier: GPL-2.0-only
#include <linux/crc-ccitt.h>
#include <linux/delay.h>
#include <linux/gpio/consumer.h>
#include <linux/i2c.h>
#include <linux/ihex.h>
#include <linux/input.h>
#include <linux/input/mt.h>
#include <linux/input/touchscreen.h>
#include <linux/interrupt.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/sizes.h>
#include <linux/slab.h>
#include <linux/unaligned.h>

#define ILI2XXX_POLL_PERIOD	15

#define ILI210X_DATA_SIZE	64
#define ILI211X_DATA_SIZE	43
#define ILI251X_DATA_SIZE1	31
#define ILI251X_DATA_SIZE2	20

/* Touchscreen commands */
#define REG_TOUCHDATA		0x10
#define REG_PANEL_INFO		0x20
#define REG_FIRMWARE_VERSION	0x40
#define REG_PROTOCOL_VERSION	0x42
#define REG_KERNEL_VERSION	0x61
#define REG_IC_BUSY		0x80
#define REG_IC_BUSY_NOT_BUSY	0x50
#define REG_GET_MODE		0xc0
#define REG_GET_MODE_AP		0x5a
#define REG_GET_MODE_BL		0x55
#define REG_SET_MODE_AP		0xc1
#define REG_SET_MODE_BL		0xc2
#define REG_WRITE_DATA		0xc3
#define REG_WRITE_ENABLE	0xc4
#define REG_READ_DATA_CRC	0xc7
#define REG_CALIBRATE		0xcc

#define ILI251X_FW_FILENAME	"ilitek/ili251x.bin"

struct ili2xxx_chip {
	int (*read_reg)(struct i2c_client *client, u8 reg,
			void *buf, size_t len);
	int (*get_touch_data)(struct i2c_client *client, u8 *data);
	bool (*parse_touch_data)(const u8 *data, unsigned int finger,
				 unsigned int *x, unsigned int *y,
				 unsigned int *z);
	bool (*continue_polling)(const u8 *data, bool touch);
	unsigned int max_touches;
	unsigned int resolution;
	bool has_calibrate_reg;
	bool has_firmware_proto;
	bool has_pressure_reg;
};

struct ili210x {
	struct i2c_client *client;
	struct input_dev *input;
	struct gpio_desc *reset_gpio;
	struct touchscreen_properties prop;
	const struct ili2xxx_chip *chip;
	u8 version_firmware[8];
	u8 version_kernel[5];
	u8 version_proto[2];
	u8 ic_mode[2];
	bool stop;
};

static int ili210x_read_reg(struct i2c_client *client,
			    u8 reg, void *buf, size_t len)
{
	struct i2c_msg msg[] = {
		{
			.addr	= client->addr,
			.flags	= 0,
			.len	= 1,
			.buf	= &reg,
		},
		{
			.addr	= client->addr,
			.flags	= I2C_M_RD,
			.len	= len,
			.buf	= buf,
		}
	};
	int error, ret;

	ret = i2c_transfer(client->adapter, msg, ARRAY_SIZE(msg));
	if (ret != ARRAY_SIZE(msg)) {
		error = ret < 0 ? ret : -EIO;
		dev_err(&client->dev, "%s failed: %d\n", __func__, error);
		return error;
	}

	return 0;
}

static int ili210x_read_touch_data(struct i2c_client *client, u8 *data)
{
	return ili210x_read_reg(client, REG_TOUCHDATA,
				data, ILI210X_DATA_SIZE);
}

static bool ili210x_touchdata_to_coords(const u8 *touchdata,
					unsigned int finger,
					unsigned int *x, unsigned int *y,
					unsigned int *z)
{
	if (!(touchdata[0] & BIT(finger)))
		return false;

	*x = get_unaligned_be16(touchdata + 1 + (finger * 4) + 0);
	*y = get_unaligned_be16(touchdata + 1 + (finger * 4) + 2);

	return true;
}

static bool ili210x_check_continue_polling(const u8 *data, bool touch)
{
	return data[0] & 0xf3;
}

static const struct ili2xxx_chip ili210x_chip = {
	.read_reg		= ili210x_read_reg,
	.get_touch_data		= ili210x_read_touch_data,
	.parse_touch_data	= ili210x_touchdata_to_coords,
	.continue_polling	= ili210x_check_continue_polling,
	.max_touches		= 2,
	.has_calibrate_reg	= true,
};

static int ili211x_read_touch_data(struct i2c_client *client, u8 *data)
{
	s16 sum = 0;
	int error;
	int ret;
	int i;

	ret = i2c_master_recv(client, data, ILI211X_DATA_SIZE);
	if (ret != ILI211X_DATA_SIZE) {
		error = ret < 0 ? ret : -EIO;
		dev_err(&client->dev, "%s failed: %d\n", __func__, error);
		return error;
	}

	/* This chip uses custom checksum at the end of data */
	for (i = 0; i < ILI211X_DATA_SIZE - 1; i++)
		sum = (sum + data[i]) & 0xff;

	if ((-sum & 0xff) != data[ILI211X_DATA_SIZE - 1]) {
		dev_err(&client->dev,
			"CRC error (crc=0x%02x expected=0x%02x)\n",
			sum, data[ILI211X_DATA_SIZE - 1]);
		return -EIO;
	}

	return 0;
}

static bool ili211x_touchdata_to_coords(const u8 *touchdata,
					unsigned int finger,
					unsigned int *x, unsigned int *y,
					unsigned int *z)
{
	u32 data;

	data = get_unaligned_be32(touchdata + 1 + (finger * 4) + 0);
	if (data == 0xffffffff)	/* Finger up */
		return false;

	*x = ((touchdata[1 + (finger * 4) + 0] & 0xf0) << 4) |
	     touchdata[1 + (finger * 4) + 1];
	*y = ((touchdata[1 + (finger * 4) + 0] & 0x0f) << 8) |
	     touchdata[1 + (finger * 4) + 2];

	return true;
}

static bool ili211x_decline_polling(const u8 *data, bool touch)
{
	return false;
}

static const struct ili2xxx_chip ili211x_chip = {
	.read_reg		= ili210x_read_reg,
	.get_touch_data		= ili211x_read_touch_data,
	.parse_touch_data	= ili211x_touchdata_to_coords,
	.continue_polling	= ili211x_decline_polling,
	.max_touches		= 10,
	.resolution		= 2048,
};

static bool ili212x_touchdata_to_coords(const u8 *touchdata,
					unsigned int finger,
					unsigned int *x, unsigned int *y,
					unsigned int *z)
{
	u16 val;

	val = get_unaligned_be16(touchdata + 3 + (finger * 5) + 0);
	if (!(val & BIT(15)))	/* Touch indication */
		return false;

	*x = val & 0x3fff;
	*y = get_unaligned_be16(touchdata + 3 + (finger * 5) + 2);

	return true;
}

static bool ili212x_check_continue_polling(const u8 *data, bool touch)
{
	return touch;
}

static const struct ili2xxx_chip ili212x_chip = {
	.read_reg		= ili210x_read_reg,
	.get_touch_data		= ili210x_read_touch_data,
	.parse_touch_data	= ili212x_touchdata_to_coords,
	.continue_polling	= ili212x_check_continue_polling,
	.max_touches		= 10,
	.has_calibrate_reg	= true,
};

static int ili251x_read_reg_common(struct i2c_client *client,
				   u8 reg, void *buf, size_t len,
				   unsigned int delay)
{
	int error;
	int ret;

	ret = i2c_master_send(client, &reg, 1);
	if (ret == 1) {
		if (delay)
			usleep_range(delay, delay + 500);

		ret = i2c_master_recv(client, buf, len);
		if (ret == len)
			return 0;
	}

	error = ret < 0 ? ret : -EIO;
	dev_err(&client->dev, "%s failed: %d\n", __func__, error);
	return ret;
}

static int ili251x_read_reg(struct i2c_client *client,
			    u8 reg, void *buf, size_t len)
{
	return ili251x_read_reg_common(client, reg, buf, len, 5000);
}

static int ili251x_read_touch_data(struct i2c_client *client, u8 *data)
{
	int error;

	error = ili251x_read_reg_common(client, REG_TOUCHDATA,
					data, ILI251X_DATA_SIZE1, 0);
	if (!error && data[0] == 2) {
		error = i2c_master_recv(client, data + ILI251X_DATA_SIZE1,
					ILI251X_DATA_SIZE2);
		if (error >= 0)
			error = error == ILI251X_DATA_SIZE2 ? 0 : -EIO;
	}

	return error;
}

static bool ili251x_touchdata_to_coords(const u8 *touchdata,
					unsigned int finger,
					unsigned int *x, unsigned int *y,
					unsigned int *z)
{
	u16 val;

	val = get_unaligned_be16(touchdata + 1 + (finger * 5) + 0);
	if (!(val & BIT(15)))	/* Touch indication */
		return false;

	*x = val & 0x3fff;
	*y = get_unaligned_be16(touchdata + 1 + (finger * 5) + 2);
	*z = touchdata[1 + (finger * 5) + 4];

	return true;
}

static bool ili251x_check_continue_polling(const u8 *data, bool touch)
{
	return touch;
}

static const struct ili2xxx_chip ili251x_chip = {
	.read_reg		= ili251x_read_reg,
	.get_touch_data		= ili251x_read_touch_data,
	.parse_touch_data	= ili251x_touchdata_to_coords,
	.continue_polling	= ili251x_check_continue_polling,
	.max_touches		= 10,
	.has_calibrate_reg	= true,
	.has_firmware_proto	= true,
	.has_pressure_reg	= true,
};

static bool ili210x_report_events(struct ili210x *priv, u8 *touchdata)
{
	struct input_dev *input = priv->input;
	int i;
	bool contact = false, touch;
	unsigned int x = 0, y = 0, z = 0;

	for (i = 0; i < priv->chip->max_touches; i++) {
		touch = priv->chip->parse_touch_data(touchdata, i, &x, &y, &z);

		input_mt_slot(input, i);
		if (input_mt_report_slot_state(input, MT_TOOL_FINGER, touch)) {
			touchscreen_report_pos(input, &priv->prop, x, y, true);
			if (priv->chip->has_pressure_reg)
				input_report_abs(input, ABS_MT_PRESSURE, z);
			contact = true;
		}
	}

	input_mt_report_pointer_emulation(input, false);
	input_sync(input);

	return contact;
}

static irqreturn_t ili210x_irq(int irq, void *irq_data)
{
	struct ili210x *priv = irq_data;
	struct i2c_client *client = priv->client;
	const struct ili2xxx_chip *chip = priv->chip;
	u8 touchdata[ILI210X_DATA_SIZE] = { 0 };
	bool keep_polling;
	ktime_t time_next;
	s64 time_delta;
	bool touch;
	int error;

	do {
		time_next = ktime_add_ms(ktime_get(), ILI2XXX_POLL_PERIOD);
		error = chip->get_touch_data(client, touchdata);
		if (error) {
			dev_err(&client->dev,
				"Unable to get touch data: %d\n", error);
			break;
		}

		touch = ili210x_report_events(priv, touchdata);
		keep_polling = chip->continue_polling(touchdata, touch);
		if (keep_polling) {
			time_delta = ktime_us_delta(time_next, ktime_get());
			if (time_delta > 0)
				usleep_range(time_delta, time_delta + 1000);
		}
	} while (!priv->stop && keep_polling);

	return IRQ_HANDLED;
}

static int ili251x_firmware_update_resolution(struct device *dev)
{
	struct i2c_client *client = to_i2c_client(dev);
	struct ili210x *priv = i2c_get_clientdata(client);
	u16 resx, resy;
	u8 rs[10];
	int error;

	/* The firmware update blob might have changed the resolution. */
	error = priv->chip->read_reg(client, REG_PANEL_INFO, &rs, sizeof(rs));
	if (!error) {
		resx = le16_to_cpup((__le16 *)rs);
		resy = le16_to_cpup((__le16 *)(rs + 2));

		/* The value reported by the firmware is invalid. */
		if (!resx || resx == 0xffff || !resy || resy == 0xffff)
			error = -EINVAL;
	}

	/*
	 * In case of error, the firmware might be stuck in bootloader mode,
	 * e.g. after a failed firmware update. Set maximum resolution, but
	 * do not fail to probe, so the user can re-trigger the firmware
	 * update and recover the touch controller.
	 */
	if (error) {
		dev_warn(dev, "Invalid resolution reported by controller.\n");
		resx = 16384;
		resy = 16384;
	}

	input_abs_set_max(priv->input, ABS_X, resx - 1);
	input_abs_set_max(priv->input, ABS_Y, resy - 1);
	input_abs_set_max(priv->input, ABS_MT_POSITION_X, resx - 1);
	input_abs_set_max(priv->input, ABS_MT_POSITION_Y, resy - 1);

	return error;
}

static ssize_t ili251x_firmware_update_firmware_version(struct device *dev)
{
	struct i2c_client *client = to_i2c_client(dev);
	struct ili210x *priv = i2c_get_clientdata(client);
	int error;
	u8 fw[8];

	/* Get firmware version */
	error = priv->chip->read_reg(client, REG_FIRMWARE_VERSION,
				     &fw, sizeof(fw));
	if (!error)
		memcpy(priv->version_firmware, fw, sizeof(fw));

	return error;
}

static ssize_t ili251x_firmware_update_kernel_version(struct device *dev)
{
	struct i2c_client *client = to_i2c_client(dev);
	struct ili210x *priv = i2c_get_clientdata(client);
	int error;
	u8 kv[5];

	/* Get kernel version */
	error = priv->chip->read_reg(client, REG_KERNEL_VERSION,
				     &kv, sizeof(kv));
	if (!error)
		memcpy(priv->version_kernel, kv, sizeof(kv));

	return error;
}

static ssize_t ili251x_firmware_update_protocol_version(struct device *dev)
{
	struct i2c_client *client = to_i2c_client(dev);
	struct ili210x *priv = i2c_get_clientdata(client);
	int error;
	u8 pv[2];

	/* Get protocol version */
	error = priv->chip->read_reg(client, REG_PROTOCOL_VERSION,
				     &pv, sizeof(pv));
	if (!error)
		memcpy(priv->version_proto, pv, sizeof(pv));

	return error;
}

static ssize_t ili251x_firmware_update_ic_mode(struct device *dev)
{
	struct i2c_client *client = to_i2c_client(dev);
	struct ili210x *priv = i2c_get_clientdata(client);
	int error;
	u8 md[2];

	/* Get chip boot mode */
	error = priv->chip->read_reg(client, REG_GET_MODE, &md, sizeof(md));
	if (!error)
		memcpy(priv->ic_mode, md, sizeof(md));

	return error;
}

static int ili251x_firmware_update_cached_state(struct device *dev)
{
	struct i2c_client *client = to_i2c_client(dev);
	struct ili210x *priv = i2c_get_clientdata(client);
	int error;

	if (!priv->chip->has_firmware_proto)
		return 0;

	/* Wait for firmware to boot and stabilize itself. */
	msleep(200);

	/* Firmware does report valid information. */
	error = ili251x_firmware_update_resolution(dev);
	if (error)
		return error;

	error = ili251x_firmware_update_firmware_version(dev);
	if (error)
		return error;

	error = ili251x_firmware_update_kernel_version(dev);
	if (error)
		return error;

	error = ili251x_firmware_update_protocol_version(dev);
	if (error)
		return error;

	error = ili251x_firmware_update_ic_mode(dev);
	if (error)
		return error;

	return 0;
}

static ssize_t ili251x_firmware_version_show(struct device *dev,
					     struct device_attribute *attr,
					     char *buf)
{
	struct i2c_client *client = to_i2c_client(dev);
	struct ili210x *priv = i2c_get_clientdata(client);
	u8 *fw = priv->version_firmware;

	return sysfs_emit(buf, "%02x%02x.%02x%02x.%02x%02x.%02x%02x\n",
			  fw[0], fw[1], fw[2], fw[3],
			  fw[4], fw[5], fw[6], fw[7]);
}
static DEVICE_ATTR(firmware_version, 0444, ili251x_firmware_version_show, NULL);

static ssize_t ili251x_kernel_version_show(struct device *dev,
					   struct device_attribute *attr,
					   char *buf)
{
	struct i2c_client *client = to_i2c_client(dev);
	struct ili210x *priv = i2c_get_clientdata(client);
	u8 *kv = priv->version_kernel;

	return sysfs_emit(buf, "%02x.%02x.%02x.%02x.%02x\n",
			  kv[0], kv[1], kv[2], kv[3], kv[4]);
}
static DEVICE_ATTR(kernel_version, 0444, ili251x_kernel_version_show, NULL);

static ssize_t ili251x_protocol_version_show(struct device *dev,
					     struct device_attribute *attr,
					     char *buf)
{
	struct i2c_client *client = to_i2c_client(dev);
	struct ili210x *priv = i2c_get_clientdata(client);
	u8 *pv = priv->version_proto;

	return sysfs_emit(buf, "%02x.%02x\n", pv[0], pv[1]);
}
static DEVICE_ATTR(protocol_version, 0444, ili251x_protocol_version_show, NULL);

static ssize_t ili251x_mode_show(struct device *dev,
				 struct device_attribute *attr, char *buf)
{
	struct i2c_client *client = to_i2c_client(dev);
	struct ili210x *priv = i2c_get_clientdata(client);
	u8 *md = priv->ic_mode;
	char *mode = "AP";

	if (md[0] == REG_GET_MODE_AP)		/* Application Mode */
		mode = "AP";
	else if (md[0] == REG_GET_MODE_BL)	/* BootLoader Mode */
		mode = "BL";
	else					/* Unknown Mode */
		mode = "??";

	return sysfs_emit(buf, "%02x.%02x:%s\n", md[0], md[1], mode);
}
static DEVICE_ATTR(mode, 0444, ili251x_mode_show, NULL);

static ssize_t ili210x_calibrate(struct device *dev,
				 struct device_attribute *attr,
				 const char *buf, size_t count)
{
	struct i2c_client *client = to_i2c_client(dev);
	struct ili210x *priv = i2c_get_clientdata(client);
	unsigned long calibrate;
	int rc;
	u8 cmd = REG_CALIBRATE;

	if (kstrtoul(buf, 10, &calibrate))
		return -EINVAL;

	if (calibrate > 1)
		return -EINVAL;

	if (calibrate) {
		rc = i2c_master_send(priv->client, &cmd, sizeof(cmd));
		if (rc != sizeof(cmd))
			return -EIO;
	}

	return count;
}
static DEVICE_ATTR(calibrate, S_IWUSR, NULL, ili210x_calibrate);

static const u8 *ili251x_firmware_to_buffer(const struct firmware *fw,
					    u16 *ac_end, u16 *df_end)
{
	const struct ihex_binrec *rec;
	u32 fw_addr, fw_last_addr = 0;
	u16 fw_len;

	/*
	 * The firmware ihex blob can never be bigger than 64 kiB, so make this
	 * simple -- allocate a 64 kiB buffer, iterate over the ihex blob records
	 * once, copy them all into this buffer at the right locations, and then
	 * do all operations on this linear buffer.
	 */
	u8* fw_buf __free(kvfree) = kvmalloc(SZ_64K, GFP_KERNEL);
	if (!fw_buf)
		return ERR_PTR(-ENOMEM);

	rec = (const struct ihex_binrec *)fw->data;
	while (rec) {
		fw_addr = be32_to_cpu(rec->addr);
		fw_len = be16_to_cpu(rec->len);

		/* The last 32 Byte firmware block can be 0xffe0 */
		if (fw_addr + fw_len > SZ_64K || fw_addr > SZ_64K - 32)
			return ERR_PTR(-EFBIG);

		/* Find the last address before DF start address, that is AC end */
		if (fw_addr == 0xf000)
			*ac_end = fw_last_addr;
		fw_last_addr = fw_addr + fw_len;

		memcpy(fw_buf + fw_addr, rec->data, fw_len);
		rec = ihex_next_binrec(rec);
	}

	/* DF end address is the last address in the firmware blob */
	*df_end = fw_addr + fw_len;

	return_ptr(fw_buf);
}

/* Switch mode between Application and BootLoader */
static int ili251x_switch_ic_mode(struct i2c_client *client, u8 cmd_mode)
{
	struct ili210x *priv = i2c_get_clientdata(client);
	u8 cmd_wren[3] = { REG_WRITE_ENABLE, 0x5a, 0xa5 };
	u8 md[2];
	int error;

	error = priv->chip->read_reg(client, REG_GET_MODE, md, sizeof(md));
	if (error)
		return error;
	/* Mode already set */
	if ((cmd_mode == REG_SET_MODE_AP && md[0] == REG_GET_MODE_AP) ||
	    (cmd_mode == REG_SET_MODE_BL && md[0] == REG_GET_MODE_BL))
		return 0;

	/* Unlock writes */
	error = i2c_master_send(client, cmd_wren, sizeof(cmd_wren));
	if (error != sizeof(cmd_wren))
		return -EINVAL;

	mdelay(20);

	/* Select mode (BootLoader or Application) */
	error = i2c_master_send(client, &cmd_mode, 1);
	if (error != 1)
		return -EINVAL;

	mdelay(200);	/* Reboot into bootloader takes a lot of time ... */

	/* Read back mode */
	error = priv->chip->read_reg(client, REG_GET_MODE, md, sizeof(md));
	if (error)
		return error;
	/* Check if mode is correct now. */
	if ((cmd_mode == REG_SET_MODE_AP && md[0] == REG_GET_MODE_AP) ||
	    (cmd_mode == REG_SET_MODE_BL && md[0] == REG_GET_MODE_BL))
		return 0;

	return -EINVAL;
}

static int ili251x_firmware_busy(struct i2c_client *client)
{
	struct ili210x *priv = i2c_get_clientdata(client);
	int error, i = 0;
	u8 data;

	do {
		/* The read_reg already contains suitable delay */
		error = priv->chip->read_reg(client, REG_IC_BUSY, &data, 1);
		if (error)
			return error;
		if (i++ == 100000)
			return -ETIMEDOUT;
	} while (data != REG_IC_BUSY_NOT_BUSY);

	return 0;
}

static int ili251x_firmware_write_to_ic(struct device *dev, const u8 *fwbuf,
					u16 start, u16 end, u8 dataflash)
{
	struct i2c_client *client = to_i2c_client(dev);
	struct ili210x *priv = i2c_get_clientdata(client);
	u8 cmd_crc = REG_READ_DATA_CRC;
	u8 crcrb[4] = { 0 };
	u8 fw_data[33];
	u16 fw_addr;
	int error;

	/*
	 * The DF (dataflash) needs 2 bytes offset for unknown reasons,
	 * the AC (application) has 2 bytes CRC16-CCITT at the end.
	 */
	u16 crc = crc_ccitt(0, fwbuf + start + (dataflash ? 2 : 0),
			    end - start - 2);

	/* Unlock write to either AC (application) or DF (dataflash) area */
	u8 cmd_wr[10] = {
		REG_WRITE_ENABLE, 0x5a, 0xa5, dataflash,
		(end >> 16) & 0xff, (end >> 8) & 0xff, end & 0xff,
		(crc >> 16) & 0xff, (crc >> 8) & 0xff, crc & 0xff
	};

	error = i2c_master_send(client, cmd_wr, sizeof(cmd_wr));
	if (error != sizeof(cmd_wr))
		return -EINVAL;

	error = ili251x_firmware_busy(client);
	if (error)
		return error;

	for (fw_addr = start; fw_addr < end; fw_addr += 32) {
		fw_data[0] = REG_WRITE_DATA;
		memcpy(&(fw_data[1]), fwbuf + fw_addr, 32);
		error = i2c_master_send(client, fw_data, 33);
		if (error != sizeof(fw_data))
			return error;
		error = ili251x_firmware_busy(client);
		if (error)
			return error;
	}

	error = i2c_master_send(client, &cmd_crc, 1);
	if (error != 1)
		return -EINVAL;

	error = ili251x_firmware_busy(client);
	if (error)
		return error;

	error = priv->chip->read_reg(client, REG_READ_DATA_CRC,
				   &crcrb, sizeof(crcrb));
	if (error)
		return error;

	/* Check CRC readback */
	if ((crcrb[0] != (crc & 0xff)) || crcrb[1] != ((crc >> 8) & 0xff))
		return -EINVAL;

	return 0;
}

static int ili251x_firmware_reset(struct i2c_client *client)
{
	u8 cmd_reset[2] = { 0xf2, 0x01 };
	int error;

	error = i2c_master_send(client, cmd_reset, sizeof(cmd_reset));
	if (error != sizeof(cmd_reset))
		return -EINVAL;

	return ili251x_firmware_busy(client);
}

static void ili210x_hardware_reset(struct gpio_desc *reset_gpio)
{
	/* Reset the controller */
	gpiod_set_value_cansleep(reset_gpio, 1);
	usleep_range(12000, 15000);
	gpiod_set_value_cansleep(reset_gpio, 0);
	msleep(300);
}

static int ili210x_do_firmware_update(struct ili210x *priv,
				      const u8 *fwbuf, u16 ac_end, u16 df_end)
{
	struct i2c_client *client = priv->client;
	struct device *dev = &client->dev;
	int error;
	int i;

	error = ili251x_firmware_reset(client);
	if (error)
		return error;

	/* This may not succeed on first try, so re-try a few times. */
	for (i = 0; i < 5; i++) {
		error = ili251x_switch_ic_mode(client, REG_SET_MODE_BL);
		if (!error)
			break;
	}

	if (error)
		return error;

	dev_dbg(dev, "IC is now in BootLoader mode\n");

	msleep(200);	/* The bootloader seems to need some time too. */

	error = ili251x_firmware_write_to_ic(dev, fwbuf, 0xf000, df_end, 1);
	if (error) {
		dev_err(dev, "DF firmware update failed, error=%d\n", error);
		return error;
	}

	dev_dbg(dev, "DataFlash firmware written\n");

	error = ili251x_firmware_write_to_ic(dev, fwbuf, 0x2000, ac_end, 0);
	if (error) {
		dev_err(dev, "AC firmware update failed, error=%d\n", error);
		return error;
	}

	dev_dbg(dev, "Application firmware written\n");

	/* This may not succeed on first try, so re-try a few times. */
	for (i = 0; i < 5; i++) {
		error = ili251x_switch_ic_mode(client, REG_SET_MODE_AP);
		if (!error)
			break;
	}

	if (error)
		return error;

	dev_dbg(dev, "IC is now in Application mode\n");

	error = ili251x_firmware_update_cached_state(dev);
	if (error)
		return error;

	return 0;
}

static ssize_t ili210x_firmware_update_store(struct device *dev,
					     struct device_attribute *attr,
					     const char *buf, size_t count)
{
	struct i2c_client *client = to_i2c_client(dev);
	struct ili210x *priv = i2c_get_clientdata(client);
	const char *fwname = ILI251X_FW_FILENAME;
	u16 ac_end, df_end;
	int error;

	const struct firmware *fw __free(firmware) = NULL;
	error = request_ihex_firmware(&fw, fwname, dev);
	if (error) {
		dev_err(dev, "Failed to request firmware %s, error=%d\n",
			fwname, error);
		return error;
	}

	const u8* fwbuf __free(kvfree) =
			ili251x_firmware_to_buffer(fw, &ac_end, &df_end);
	error = PTR_ERR_OR_ZERO(fwbuf);
	if (error)
		return error;

	/*
	 * Disable touchscreen IRQ, so that we would not get spurious touch
	 * interrupt during firmware update, and so that the IRQ handler won't
	 * trigger and interfere with the firmware update. There is no bit in
	 * the touch controller to disable the IRQs during update, so we have
	 * to do it this way here.
	 */
	scoped_guard(disable_irq, &client->irq) {
		dev_dbg(dev, "Firmware update started, firmware=%s\n", fwname);

		ili210x_hardware_reset(priv->reset_gpio);

		error = ili210x_do_firmware_update(priv, fwbuf, ac_end, df_end);

		ili210x_hardware_reset(priv->reset_gpio);

		dev_dbg(dev, "Firmware update ended, error=%i\n", error);
	}

	return error ?: count;
}

static DEVICE_ATTR(firmware_update, 0200, NULL, ili210x_firmware_update_store);

static struct attribute *ili210x_attrs[] = {
	&dev_attr_calibrate.attr,
	&dev_attr_firmware_update.attr,
	&dev_attr_firmware_version.attr,
	&dev_attr_kernel_version.attr,
	&dev_attr_protocol_version.attr,
	&dev_attr_mode.attr,
	NULL,
};

static umode_t ili210x_attributes_visible(struct kobject *kobj,
					  struct attribute *attr, int index)
{
	struct device *dev = kobj_to_dev(kobj);
	struct i2c_client *client = to_i2c_client(dev);
	struct ili210x *priv = i2c_get_clientdata(client);

	/* Calibrate is present on all ILI2xxx which have calibrate register */
	if (attr == &dev_attr_calibrate.attr)
		return priv->chip->has_calibrate_reg ? attr->mode : 0;

	/* Firmware/Kernel/Protocol/BootMode is implememted only for ILI251x */
	if (!priv->chip->has_firmware_proto)
		return 0;

	return attr->mode;
}

static const struct attribute_group ili210x_group = {
	.attrs = ili210x_attrs,
	.is_visible = ili210x_attributes_visible,
};
__ATTRIBUTE_GROUPS(ili210x);

static void ili210x_power_down(void *data)
{
	struct gpio_desc *reset_gpio = data;

	gpiod_set_value_cansleep(reset_gpio, 1);
}

static void ili210x_stop(void *data)
{
	struct ili210x *priv = data;

	/* Tell ISR to quit even if there is a contact. */
	priv->stop = true;
}

static int ili210x_i2c_probe(struct i2c_client *client)
{
	const struct i2c_device_id *id = i2c_client_get_device_id(client);
	struct device *dev = &client->dev;
	const struct ili2xxx_chip *chip;
	struct ili210x *priv;
	struct gpio_desc *reset_gpio;
	struct input_dev *input;
	int error;
	unsigned int max_xy;

	dev_dbg(dev, "Probing for ILI210X I2C Touschreen driver");

	chip = device_get_match_data(dev);
	if (!chip && id)
		chip = (const struct ili2xxx_chip *)id->driver_data;
	if (!chip) {
		dev_err(&client->dev, "unknown device model\n");
		return -ENODEV;
	}

	if (client->irq <= 0) {
		dev_err(dev, "No IRQ!\n");
		return -EINVAL;
	}

	reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH);
	if (IS_ERR(reset_gpio))
		return PTR_ERR(reset_gpio);

	if (reset_gpio) {
		error = devm_add_action_or_reset(dev, ili210x_power_down,
						 reset_gpio);
		if (error)
			return error;

		ili210x_hardware_reset(reset_gpio);
	}

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

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

	priv->client = client;
	priv->input = input;
	priv->reset_gpio = reset_gpio;
	priv->chip = chip;
	i2c_set_clientdata(client, priv);

	/* Setup input device */
	input->name = "ILI210x Touchscreen";
	input->id.bustype = BUS_I2C;

	/* Multi touch */
	max_xy = (chip->resolution ?: SZ_64K) - 1;
	input_set_abs_params(input, ABS_MT_POSITION_X, 0, max_xy, 0, 0);
	input_set_abs_params(input, ABS_MT_POSITION_Y, 0, max_xy, 0, 0);
	if (priv->chip->has_pressure_reg)
		input_set_abs_params(input, ABS_MT_PRESSURE, 0, 0xa, 0, 0);
	error = ili251x_firmware_update_cached_state(dev);
	if (error)
		dev_warn(dev, "Unable to cache firmware information, err: %d\n",
			 error);

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

	error = input_mt_init_slots(input, priv->chip->max_touches,
				    INPUT_MT_DIRECT);
	if (error) {
		dev_err(dev, "Unable to set up slots, err: %d\n", error);
		return error;
	}

	error = devm_request_threaded_irq(dev, client->irq, NULL, ili210x_irq,
					  IRQF_ONESHOT, client->name, priv);
	if (error) {
		dev_err(dev, "Unable to request touchscreen IRQ, err: %d\n",
			error);
		return error;
	}

	error = devm_add_action_or_reset(dev, ili210x_stop, priv);
	if (error)
		return error;

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

	return 0;
}

static const struct i2c_device_id ili210x_i2c_id[] = {
	{ "ili210x", (long)&ili210x_chip },
	{ "ili2117", (long)&ili211x_chip },
	{ "ili2120", (long)&ili212x_chip },
	{ "ili251x", (long)&ili251x_chip },
	{ }
};
MODULE_DEVICE_TABLE(i2c, ili210x_i2c_id);

static const struct of_device_id ili210x_dt_ids[] = {
	{ .compatible = "ilitek,ili210x", .data = &ili210x_chip },
	{ .compatible = "ilitek,ili2117", .data = &ili211x_chip },
	{ .compatible = "ilitek,ili2120", .data = &ili212x_chip },
	{ .compatible = "ilitek,ili251x", .data = &ili251x_chip },
	{ }
};
MODULE_DEVICE_TABLE(of, ili210x_dt_ids);

static struct i2c_driver ili210x_ts_driver = {
	.driver = {
		.name = "ili210x_i2c",
		.dev_groups = ili210x_groups,
		.of_match_table = ili210x_dt_ids,
	},
	.id_table = ili210x_i2c_id,
	.probe = ili210x_i2c_probe,
};

module_i2c_driver(ili210x_ts_driver);

MODULE_AUTHOR("Olivier Sobrie <olivier@sobrie.be>");
MODULE_DESCRIPTION("ILI210X I2C Touchscreen Driver");
MODULE_LICENSE("GPL");
