/*
 * Weida HiTech WDT87xx TouchScreen I2C driver
 *
 * Copyright (c) 2015  Weida Hi-Tech Co., Ltd.
 * HN Chen <hn.chen@weidahitech.com>
 *
 * This software is licensed under the terms of the GNU General Public
 * License, as published by the Free Software Foundation, and
 * may be copied, distributed, and modified under those terms.
 */

#include <linux/i2c.h>
#include <linux/input.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/irq.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/firmware.h>
#include <linux/input/mt.h>
#include <linux/acpi.h>
#include <asm/unaligned.h>

#define WDT87XX_NAME		"wdt87xx_i2c"
#define WDT87XX_DRV_VER		"0.9.6"
#define WDT87XX_FW_NAME		"wdt87xx_fw.bin"
#define WDT87XX_CFG_NAME	"wdt87xx_cfg.bin"

#define MODE_ACTIVE			0x01
#define MODE_READY			0x02
#define MODE_IDLE			0x03
#define MODE_SLEEP			0x04
#define MODE_STOP			0xFF

#define WDT_MAX_FINGER			10
#define WDT_RAW_BUF_COUNT		54
#define WDT_V1_RAW_BUF_COUNT		74
#define WDT_FIRMWARE_ID			0xa9e368f5

#define PG_SIZE				0x1000
#define MAX_RETRIES			3

#define MAX_UNIT_AXIS			0x7FFF

#define PKT_READ_SIZE			72
#define PKT_WRITE_SIZE			80

/* the finger definition of the report event */
#define FINGER_EV_OFFSET_ID		0
#define FINGER_EV_OFFSET_X		1
#define FINGER_EV_OFFSET_Y		3
#define FINGER_EV_SIZE			5

#define FINGER_EV_V1_OFFSET_ID		0
#define FINGER_EV_V1_OFFSET_W		1
#define FINGER_EV_V1_OFFSET_P		2
#define FINGER_EV_V1_OFFSET_X		3
#define FINGER_EV_V1_OFFSET_Y		5
#define FINGER_EV_V1_SIZE		7

/* The definition of a report packet */
#define TOUCH_PK_OFFSET_REPORT_ID	0
#define TOUCH_PK_OFFSET_EVENT		1
#define TOUCH_PK_OFFSET_SCAN_TIME	51
#define TOUCH_PK_OFFSET_FNGR_NUM	53

#define TOUCH_PK_V1_OFFSET_REPORT_ID	0
#define TOUCH_PK_V1_OFFSET_EVENT	1
#define TOUCH_PK_V1_OFFSET_SCAN_TIME	71
#define TOUCH_PK_V1_OFFSET_FNGR_NUM	73

/* The definition of the controller parameters */
#define CTL_PARAM_OFFSET_FW_ID		0
#define CTL_PARAM_OFFSET_PLAT_ID	2
#define CTL_PARAM_OFFSET_XMLS_ID1	4
#define CTL_PARAM_OFFSET_XMLS_ID2	6
#define CTL_PARAM_OFFSET_PHY_CH_X	8
#define CTL_PARAM_OFFSET_PHY_CH_Y	10
#define CTL_PARAM_OFFSET_PHY_X0		12
#define CTL_PARAM_OFFSET_PHY_X1		14
#define CTL_PARAM_OFFSET_PHY_Y0		16
#define CTL_PARAM_OFFSET_PHY_Y1		18
#define CTL_PARAM_OFFSET_PHY_W		22
#define CTL_PARAM_OFFSET_PHY_H		24
#define CTL_PARAM_OFFSET_FACTOR		32

/* Communication commands */
#define PACKET_SIZE			56
#define VND_REQ_READ			0x06
#define VND_READ_DATA			0x07
#define VND_REQ_WRITE			0x08

#define VND_CMD_START			0x00
#define VND_CMD_STOP			0x01
#define VND_CMD_RESET			0x09

#define VND_CMD_ERASE			0x1A

#define VND_GET_CHECKSUM		0x66

#define VND_SET_DATA			0x83
#define VND_SET_COMMAND_DATA		0x84
#define VND_SET_CHECKSUM_CALC		0x86
#define VND_SET_CHECKSUM_LENGTH		0x87

#define VND_CMD_SFLCK			0xFC
#define VND_CMD_SFUNL			0xFD

#define CMD_SFLCK_KEY			0xC39B
#define CMD_SFUNL_KEY			0x95DA

#define STRIDX_PLATFORM_ID		0x80
#define STRIDX_PARAMETERS		0x81

#define CMD_BUF_SIZE			8
#define PKT_BUF_SIZE			64

/* The definition of the command packet */
#define CMD_REPORT_ID_OFFSET		0x0
#define CMD_TYPE_OFFSET			0x1
#define CMD_INDEX_OFFSET		0x2
#define CMD_KEY_OFFSET			0x3
#define CMD_LENGTH_OFFSET		0x4
#define CMD_DATA_OFFSET			0x8

/* The definition of firmware chunk tags */
#define FOURCC_ID_RIFF			0x46464952
#define FOURCC_ID_WHIF			0x46494857
#define FOURCC_ID_FRMT			0x544D5246
#define FOURCC_ID_FRWR			0x52575246
#define FOURCC_ID_CNFG			0x47464E43

#define CHUNK_ID_FRMT			FOURCC_ID_FRMT
#define CHUNK_ID_FRWR			FOURCC_ID_FRWR
#define CHUNK_ID_CNFG			FOURCC_ID_CNFG

#define FW_FOURCC1_OFFSET		0
#define FW_SIZE_OFFSET			4
#define FW_FOURCC2_OFFSET		8
#define FW_PAYLOAD_OFFSET		40

#define FW_CHUNK_ID_OFFSET		0
#define FW_CHUNK_SIZE_OFFSET		4
#define FW_CHUNK_TGT_START_OFFSET	8
#define FW_CHUNK_PAYLOAD_LEN_OFFSET	12
#define FW_CHUNK_SRC_START_OFFSET	16
#define FW_CHUNK_VERSION_OFFSET		20
#define FW_CHUNK_ATTR_OFFSET		24
#define FW_CHUNK_PAYLOAD_OFFSET		32

/* Controller requires minimum 300us between commands */
#define WDT_COMMAND_DELAY_MS		2
#define WDT_FLASH_WRITE_DELAY_MS	4

struct wdt87xx_sys_param {
	u16	fw_id;
	u16	plat_id;
	u16	xmls_id1;
	u16	xmls_id2;
	u16	phy_ch_x;
	u16	phy_ch_y;
	u16	phy_w;
	u16	phy_h;
	u16	scaling_factor;
	u32	max_x;
	u32	max_y;
};

struct wdt87xx_data {
	struct i2c_client		*client;
	struct input_dev		*input;
	/* Mutex for fw update to prevent concurrent access */
	struct mutex			fw_mutex;
	struct wdt87xx_sys_param	param;
	u8				phys[32];
};

static int wdt87xx_i2c_xfer(struct i2c_client *client,
			    void *txdata, size_t txlen,
			    void *rxdata, size_t rxlen)
{
	struct i2c_msg msgs[] = {
		{
			.addr	= client->addr,
			.flags	= 0,
			.len	= txlen,
			.buf	= txdata,
		},
		{
			.addr	= client->addr,
			.flags	= I2C_M_RD,
			.len	= rxlen,
			.buf	= rxdata,
		},
	};
	int error;
	int ret;

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

	return 0;
}

static int wdt87xx_get_string(struct i2c_client *client, u8 str_idx,
			      u8 *buf, size_t len)
{
	u8 tx_buf[] = { 0x22, 0x00, 0x13, 0x0E, str_idx, 0x23, 0x00 };
	u8 rx_buf[PKT_WRITE_SIZE];
	size_t rx_len = len + 2;
	int error;

	if (rx_len > sizeof(rx_buf))
		return -EINVAL;

	error = wdt87xx_i2c_xfer(client, tx_buf, sizeof(tx_buf),
				 rx_buf, rx_len);
	if (error) {
		dev_err(&client->dev, "get string failed: %d\n", error);
		return error;
	}

	if (rx_buf[1] != 0x03) {
		dev_err(&client->dev, "unexpected response to get string: %d\n",
			rx_buf[1]);
		return -EINVAL;
	}

	rx_len = min_t(size_t, len, rx_buf[0]);
	memcpy(buf, &rx_buf[2], rx_len);

	mdelay(WDT_COMMAND_DELAY_MS);

	return 0;
}

static int wdt87xx_get_feature(struct i2c_client *client,
			       u8 *buf, size_t buf_size)
{
	u8 tx_buf[8];
	u8 rx_buf[PKT_WRITE_SIZE];
	size_t tx_len = 0;
	size_t rx_len = buf_size + 2;
	int error;

	if (rx_len > sizeof(rx_buf))
		return -EINVAL;

	/* Get feature command packet */
	tx_buf[tx_len++] = 0x22;
	tx_buf[tx_len++] = 0x00;
	if (buf[CMD_REPORT_ID_OFFSET] > 0xF) {
		tx_buf[tx_len++] = 0x30;
		tx_buf[tx_len++] = 0x02;
		tx_buf[tx_len++] = buf[CMD_REPORT_ID_OFFSET];
	} else {
		tx_buf[tx_len++] = 0x30 | buf[CMD_REPORT_ID_OFFSET];
		tx_buf[tx_len++] = 0x02;
	}
	tx_buf[tx_len++] = 0x23;
	tx_buf[tx_len++] = 0x00;

	error = wdt87xx_i2c_xfer(client, tx_buf, tx_len, rx_buf, rx_len);
	if (error) {
		dev_err(&client->dev, "get feature failed: %d\n", error);
		return error;
	}

	rx_len = min_t(size_t, buf_size, get_unaligned_le16(rx_buf));
	memcpy(buf, &rx_buf[2], rx_len);

	mdelay(WDT_COMMAND_DELAY_MS);

	return 0;
}

static int wdt87xx_set_feature(struct i2c_client *client,
			       const u8 *buf, size_t buf_size)
{
	u8 tx_buf[PKT_WRITE_SIZE];
	int tx_len = 0;
	int error;

	/* Set feature command packet */
	tx_buf[tx_len++] = 0x22;
	tx_buf[tx_len++] = 0x00;
	if (buf[CMD_REPORT_ID_OFFSET] > 0xF) {
		tx_buf[tx_len++] = 0x30;
		tx_buf[tx_len++] = 0x03;
		tx_buf[tx_len++] = buf[CMD_REPORT_ID_OFFSET];
	} else {
		tx_buf[tx_len++] = 0x30 | buf[CMD_REPORT_ID_OFFSET];
		tx_buf[tx_len++] = 0x03;
	}
	tx_buf[tx_len++] = 0x23;
	tx_buf[tx_len++] = 0x00;
	tx_buf[tx_len++] = (buf_size & 0xFF);
	tx_buf[tx_len++] = ((buf_size & 0xFF00) >> 8);

	if (tx_len + buf_size > sizeof(tx_buf))
		return -EINVAL;

	memcpy(&tx_buf[tx_len], buf, buf_size);
	tx_len += buf_size;

	error = i2c_master_send(client, tx_buf, tx_len);
	if (error < 0) {
		dev_err(&client->dev, "set feature failed: %d\n", error);
		return error;
	}

	mdelay(WDT_COMMAND_DELAY_MS);

	return 0;
}

static int wdt87xx_send_command(struct i2c_client *client, int cmd, int value)
{
	u8 cmd_buf[CMD_BUF_SIZE];

	/* Set the command packet */
	cmd_buf[CMD_REPORT_ID_OFFSET] = VND_REQ_WRITE;
	cmd_buf[CMD_TYPE_OFFSET] = VND_SET_COMMAND_DATA;
	put_unaligned_le16((u16)cmd, &cmd_buf[CMD_INDEX_OFFSET]);

	switch (cmd) {
	case VND_CMD_START:
	case VND_CMD_STOP:
	case VND_CMD_RESET:
		/* Mode selector */
		put_unaligned_le32((value & 0xFF), &cmd_buf[CMD_LENGTH_OFFSET]);
		break;

	case VND_CMD_SFLCK:
		put_unaligned_le16(CMD_SFLCK_KEY, &cmd_buf[CMD_KEY_OFFSET]);
		break;

	case VND_CMD_SFUNL:
		put_unaligned_le16(CMD_SFUNL_KEY, &cmd_buf[CMD_KEY_OFFSET]);
		break;

	case VND_CMD_ERASE:
	case VND_SET_CHECKSUM_CALC:
	case VND_SET_CHECKSUM_LENGTH:
		put_unaligned_le32(value, &cmd_buf[CMD_KEY_OFFSET]);
		break;

	default:
		cmd_buf[CMD_REPORT_ID_OFFSET] = 0;
		dev_err(&client->dev, "Invalid command: %d\n", cmd);
		return -EINVAL;
	}

	return wdt87xx_set_feature(client, cmd_buf, sizeof(cmd_buf));
}

static int wdt87xx_sw_reset(struct i2c_client *client)
{
	int error;

	dev_dbg(&client->dev, "resetting device now\n");

	error = wdt87xx_send_command(client, VND_CMD_RESET, 0);
	if (error) {
		dev_err(&client->dev, "reset failed\n");
		return error;
	}

	/* Wait the device to be ready */
	msleep(200);

	return 0;
}

static const void *wdt87xx_get_fw_chunk(const struct firmware *fw, u32 id)
{
	size_t pos = FW_PAYLOAD_OFFSET;
	u32 chunk_id, chunk_size;

	while (pos < fw->size) {
		chunk_id = get_unaligned_le32(fw->data +
					      pos + FW_CHUNK_ID_OFFSET);
		if (chunk_id == id)
			return fw->data + pos;

		chunk_size = get_unaligned_le32(fw->data +
						pos + FW_CHUNK_SIZE_OFFSET);
		pos += chunk_size + 2 * sizeof(u32); /* chunk ID + size */
	}

	return NULL;
}

static int wdt87xx_get_sysparam(struct i2c_client *client,
				struct wdt87xx_sys_param *param)
{
	u8 buf[PKT_READ_SIZE];
	int error;

	error = wdt87xx_get_string(client, STRIDX_PARAMETERS, buf, 34);
	if (error) {
		dev_err(&client->dev, "failed to get parameters\n");
		return error;
	}

	param->xmls_id1 = get_unaligned_le16(buf + CTL_PARAM_OFFSET_XMLS_ID1);
	param->xmls_id2 = get_unaligned_le16(buf + CTL_PARAM_OFFSET_XMLS_ID2);
	param->phy_ch_x = get_unaligned_le16(buf + CTL_PARAM_OFFSET_PHY_CH_X);
	param->phy_ch_y = get_unaligned_le16(buf + CTL_PARAM_OFFSET_PHY_CH_Y);
	param->phy_w = get_unaligned_le16(buf + CTL_PARAM_OFFSET_PHY_W) / 10;
	param->phy_h = get_unaligned_le16(buf + CTL_PARAM_OFFSET_PHY_H) / 10;

	/* Get the scaling factor of pixel to logical coordinate */
	param->scaling_factor =
			get_unaligned_le16(buf + CTL_PARAM_OFFSET_FACTOR);

	param->max_x = MAX_UNIT_AXIS;
	param->max_y = DIV_ROUND_CLOSEST(MAX_UNIT_AXIS * param->phy_h,
					 param->phy_w);

	error = wdt87xx_get_string(client, STRIDX_PLATFORM_ID, buf, 8);
	if (error) {
		dev_err(&client->dev, "failed to get platform id\n");
		return error;
	}

	param->plat_id = buf[1];

	buf[0] = 0xf2;
	error = wdt87xx_get_feature(client, buf, 16);
	if (error) {
		dev_err(&client->dev, "failed to get firmware id\n");
		return error;
	}

	if (buf[0] != 0xf2) {
		dev_err(&client->dev, "wrong id of fw response: 0x%x\n",
			buf[0]);
		return -EINVAL;
	}

	param->fw_id = get_unaligned_le16(&buf[1]);

	dev_info(&client->dev,
		 "fw_id: 0x%x, plat_id: 0x%x, xml_id1: %04x, xml_id2: %04x\n",
		 param->fw_id, param->plat_id,
		 param->xmls_id1, param->xmls_id2);

	return 0;
}

static int wdt87xx_validate_firmware(struct wdt87xx_data *wdt,
				     const struct firmware *fw)
{
	const void *fw_chunk;
	u32 data1, data2;
	u32 size;
	u8 fw_chip_id;
	u8 chip_id;

	data1 = get_unaligned_le32(fw->data + FW_FOURCC1_OFFSET);
	data2 = get_unaligned_le32(fw->data + FW_FOURCC2_OFFSET);
	if (data1 != FOURCC_ID_RIFF || data2 != FOURCC_ID_WHIF) {
		dev_err(&wdt->client->dev, "check fw tag failed\n");
		return -EINVAL;
	}

	size = get_unaligned_le32(fw->data + FW_SIZE_OFFSET);
	if (size != fw->size) {
		dev_err(&wdt->client->dev,
			"fw size mismatch: expected %d, actual %zu\n",
			size, fw->size);
		return -EINVAL;
	}

	/*
	 * Get the chip_id from the firmware. Make sure that it is the
	 * right controller to do the firmware and config update.
	 */
	fw_chunk = wdt87xx_get_fw_chunk(fw, CHUNK_ID_FRWR);
	if (!fw_chunk) {
		dev_err(&wdt->client->dev,
			"unable to locate firmware chunk\n");
		return -EINVAL;
	}

	fw_chip_id = (get_unaligned_le32(fw_chunk +
					 FW_CHUNK_VERSION_OFFSET) >> 12) & 0xF;
	chip_id = (wdt->param.fw_id >> 12) & 0xF;

	if (fw_chip_id != chip_id) {
		dev_err(&wdt->client->dev,
			"fw version mismatch: fw %d vs. chip %d\n",
			fw_chip_id, chip_id);
		return -ENODEV;
	}

	return 0;
}

static int wdt87xx_validate_fw_chunk(const void *data, int id)
{
	if (id == CHUNK_ID_FRWR) {
		u32 fw_id;

		fw_id = get_unaligned_le32(data + FW_CHUNK_PAYLOAD_OFFSET);
		if (fw_id != WDT_FIRMWARE_ID)
			return -EINVAL;
	}

	return 0;
}

static int wdt87xx_write_data(struct i2c_client *client, const char *data,
			      u32 address, int length)
{
	u16 packet_size;
	int count = 0;
	int error;
	u8 pkt_buf[PKT_BUF_SIZE];

	/* Address and length should be 4 bytes aligned */
	if ((address & 0x3) != 0 || (length & 0x3) != 0) {
		dev_err(&client->dev,
			"addr & len must be 4 bytes aligned %x, %x\n",
			address, length);
		return -EINVAL;
	}

	while (length) {
		packet_size = min(length, PACKET_SIZE);

		pkt_buf[CMD_REPORT_ID_OFFSET] = VND_REQ_WRITE;
		pkt_buf[CMD_TYPE_OFFSET] = VND_SET_DATA;
		put_unaligned_le16(packet_size, &pkt_buf[CMD_INDEX_OFFSET]);
		put_unaligned_le32(address, &pkt_buf[CMD_LENGTH_OFFSET]);
		memcpy(&pkt_buf[CMD_DATA_OFFSET], data, packet_size);

		error = wdt87xx_set_feature(client, pkt_buf, sizeof(pkt_buf));
		if (error)
			return error;

		length -= packet_size;
		data += packet_size;
		address += packet_size;

		/* Wait for the controller to finish the write */
		mdelay(WDT_FLASH_WRITE_DELAY_MS);

		if ((++count % 32) == 0) {
			/* Delay for fw to clear watch dog */
			msleep(20);
		}
	}

	return 0;
}

static u16 misr(u16 cur_value, u8 new_value)
{
	u32 a, b;
	u32 bit0;
	u32 y;

	a = cur_value;
	b = new_value;
	bit0 = a ^ (b & 1);
	bit0 ^= a >> 1;
	bit0 ^= a >> 2;
	bit0 ^= a >> 4;
	bit0 ^= a >> 5;
	bit0 ^= a >> 7;
	bit0 ^= a >> 11;
	bit0 ^= a >> 15;
	y = (a << 1) ^ b;
	y = (y & ~1) | (bit0 & 1);

	return (u16)y;
}

static u16 wdt87xx_calculate_checksum(const u8 *data, size_t length)
{
	u16 checksum = 0;
	size_t i;

	for (i = 0; i < length; i++)
		checksum = misr(checksum, data[i]);

	return checksum;
}

static int wdt87xx_get_checksum(struct i2c_client *client, u16 *checksum,
				u32 address, int length)
{
	int error;
	int time_delay;
	u8 pkt_buf[PKT_BUF_SIZE];
	u8 cmd_buf[CMD_BUF_SIZE];

	error = wdt87xx_send_command(client, VND_SET_CHECKSUM_LENGTH, length);
	if (error) {
		dev_err(&client->dev, "failed to set checksum length\n");
		return error;
	}

	error = wdt87xx_send_command(client, VND_SET_CHECKSUM_CALC, address);
	if (error) {
		dev_err(&client->dev, "failed to set checksum address\n");
		return error;
	}

	/* Wait the operation to complete */
	time_delay = DIV_ROUND_UP(length, 1024);
	msleep(time_delay * 30);

	memset(cmd_buf, 0, sizeof(cmd_buf));
	cmd_buf[CMD_REPORT_ID_OFFSET] = VND_REQ_READ;
	cmd_buf[CMD_TYPE_OFFSET] = VND_GET_CHECKSUM;
	error = wdt87xx_set_feature(client, cmd_buf, sizeof(cmd_buf));
	if (error) {
		dev_err(&client->dev, "failed to request checksum\n");
		return error;
	}

	memset(pkt_buf, 0, sizeof(pkt_buf));
	pkt_buf[CMD_REPORT_ID_OFFSET] = VND_READ_DATA;
	error = wdt87xx_get_feature(client, pkt_buf, sizeof(pkt_buf));
	if (error) {
		dev_err(&client->dev, "failed to read checksum\n");
		return error;
	}

	*checksum = get_unaligned_le16(&pkt_buf[CMD_DATA_OFFSET]);
	return 0;
}

static int wdt87xx_write_firmware(struct i2c_client *client, const void *chunk)
{
	u32 start_addr = get_unaligned_le32(chunk + FW_CHUNK_TGT_START_OFFSET);
	u32 size = get_unaligned_le32(chunk + FW_CHUNK_PAYLOAD_LEN_OFFSET);
	const void *data = chunk + FW_CHUNK_PAYLOAD_OFFSET;
	int error;
	int err1;
	int page_size;
	int retry = 0;
	u16 device_checksum, firmware_checksum;

	dev_dbg(&client->dev, "start 4k page program\n");

	error = wdt87xx_send_command(client, VND_CMD_STOP, MODE_STOP);
	if (error) {
		dev_err(&client->dev, "stop report mode failed\n");
		return error;
	}

	error = wdt87xx_send_command(client, VND_CMD_SFUNL, 0);
	if (error) {
		dev_err(&client->dev, "unlock failed\n");
		goto out_enable_reporting;
	}

	mdelay(10);

	while (size) {
		dev_dbg(&client->dev, "%s: %x, %x\n", __func__,
			start_addr, size);

		page_size = min_t(u32, size, PG_SIZE);
		size -= page_size;

		for (retry = 0; retry < MAX_RETRIES; retry++) {
			error = wdt87xx_send_command(client, VND_CMD_ERASE,
						     start_addr);
			if (error) {
				dev_err(&client->dev,
					"erase failed at %#08x\n", start_addr);
				break;
			}

			msleep(50);

			error = wdt87xx_write_data(client, data, start_addr,
						   page_size);
			if (error) {
				dev_err(&client->dev,
					"write failed at %#08x (%d bytes)\n",
					start_addr, page_size);
				break;
			}

			error = wdt87xx_get_checksum(client, &device_checksum,
						     start_addr, page_size);
			if (error) {
				dev_err(&client->dev,
					"failed to retrieve checksum for %#08x (len: %d)\n",
					start_addr, page_size);
				break;
			}

			firmware_checksum =
				wdt87xx_calculate_checksum(data, page_size);

			if (device_checksum == firmware_checksum)
				break;

			dev_err(&client->dev,
				"checksum fail: %d vs %d, retry %d\n",
				device_checksum, firmware_checksum, retry);
		}

		if (retry == MAX_RETRIES) {
			dev_err(&client->dev, "page write failed\n");
			error = -EIO;
			goto out_lock_device;
		}

		start_addr = start_addr + page_size;
		data = data + page_size;
	}

out_lock_device:
	err1 = wdt87xx_send_command(client, VND_CMD_SFLCK, 0);
	if (err1)
		dev_err(&client->dev, "lock failed\n");

	mdelay(10);

out_enable_reporting:
	err1 = wdt87xx_send_command(client, VND_CMD_START, 0);
	if (err1)
		dev_err(&client->dev, "start to report failed\n");

	return error ? error : err1;
}

static int wdt87xx_load_chunk(struct i2c_client *client,
			      const struct firmware *fw, u32 ck_id)
{
	const void *chunk;
	int error;

	chunk = wdt87xx_get_fw_chunk(fw, ck_id);
	if (!chunk) {
		dev_err(&client->dev, "unable to locate chunk (type %d)\n",
			ck_id);
		return -EINVAL;
	}

	error = wdt87xx_validate_fw_chunk(chunk, ck_id);
	if (error) {
		dev_err(&client->dev, "invalid chunk (type %d): %d\n",
			ck_id, error);
		return error;
	}

	error = wdt87xx_write_firmware(client, chunk);
	if (error) {
		dev_err(&client->dev,
			"failed to write fw chunk (type %d): %d\n",
			ck_id, error);
		return error;
	}

	return 0;
}

static int wdt87xx_do_update_firmware(struct i2c_client *client,
				      const struct firmware *fw,
				      unsigned int chunk_id)
{
	struct wdt87xx_data *wdt = i2c_get_clientdata(client);
	int error;

	error = wdt87xx_validate_firmware(wdt, fw);
	if (error)
		return error;

	error = mutex_lock_interruptible(&wdt->fw_mutex);
	if (error)
		return error;

	disable_irq(client->irq);

	error = wdt87xx_load_chunk(client, fw, chunk_id);
	if (error) {
		dev_err(&client->dev,
			"firmware load failed (type: %d): %d\n",
			chunk_id, error);
		goto out;
	}

	error = wdt87xx_sw_reset(client);
	if (error) {
		dev_err(&client->dev, "soft reset failed: %d\n", error);
		goto out;
	}

	/* Refresh the parameters */
	error = wdt87xx_get_sysparam(client, &wdt->param);
	if (error)
		dev_err(&client->dev,
			"failed to refresh system paramaters: %d\n", error);
out:
	enable_irq(client->irq);
	mutex_unlock(&wdt->fw_mutex);

	return error ? error : 0;
}

static int wdt87xx_update_firmware(struct device *dev,
				   const char *fw_name, unsigned int chunk_id)
{
	struct i2c_client *client = to_i2c_client(dev);
	const struct firmware *fw;
	int error;

	error = request_firmware(&fw, fw_name, dev);
	if (error) {
		dev_err(&client->dev, "unable to retrieve firmware %s: %d\n",
			fw_name, error);
		return error;
	}

	error = wdt87xx_do_update_firmware(client, fw, chunk_id);

	release_firmware(fw);

	return error ? error : 0;
}

static ssize_t config_csum_show(struct device *dev,
				struct device_attribute *attr, char *buf)
{
	struct i2c_client *client = to_i2c_client(dev);
	struct wdt87xx_data *wdt = i2c_get_clientdata(client);
	u32 cfg_csum;

	cfg_csum = wdt->param.xmls_id1;
	cfg_csum = (cfg_csum << 16) | wdt->param.xmls_id2;

	return scnprintf(buf, PAGE_SIZE, "%x\n", cfg_csum);
}

static ssize_t fw_version_show(struct device *dev,
			       struct device_attribute *attr, char *buf)
{
	struct i2c_client *client = to_i2c_client(dev);
	struct wdt87xx_data *wdt = i2c_get_clientdata(client);

	return scnprintf(buf, PAGE_SIZE, "%x\n", wdt->param.fw_id);
}

static ssize_t plat_id_show(struct device *dev,
			    struct device_attribute *attr, char *buf)
{
	struct i2c_client *client = to_i2c_client(dev);
	struct wdt87xx_data *wdt = i2c_get_clientdata(client);

	return scnprintf(buf, PAGE_SIZE, "%x\n", wdt->param.plat_id);
}

static ssize_t update_config_store(struct device *dev,
				   struct device_attribute *attr,
				   const char *buf, size_t count)
{
	int error;

	error = wdt87xx_update_firmware(dev, WDT87XX_CFG_NAME, CHUNK_ID_CNFG);

	return error ? error : count;
}

static ssize_t update_fw_store(struct device *dev,
			       struct device_attribute *attr,
			       const char *buf, size_t count)
{
	int error;

	error = wdt87xx_update_firmware(dev, WDT87XX_FW_NAME, CHUNK_ID_FRWR);

	return error ? error : count;
}

static DEVICE_ATTR_RO(config_csum);
static DEVICE_ATTR_RO(fw_version);
static DEVICE_ATTR_RO(plat_id);
static DEVICE_ATTR_WO(update_config);
static DEVICE_ATTR_WO(update_fw);

static struct attribute *wdt87xx_attrs[] = {
	&dev_attr_config_csum.attr,
	&dev_attr_fw_version.attr,
	&dev_attr_plat_id.attr,
	&dev_attr_update_config.attr,
	&dev_attr_update_fw.attr,
	NULL
};

static const struct attribute_group wdt87xx_attr_group = {
	.attrs = wdt87xx_attrs,
};

static void wdt87xx_report_contact(struct input_dev *input,
				   struct wdt87xx_sys_param *param,
				   u8 *buf)
{
	int finger_id;
	u32 x, y, w;
	u8 p;

	finger_id = (buf[FINGER_EV_V1_OFFSET_ID] >> 3) - 1;
	if (finger_id < 0)
		return;

	/* Check if this is an active contact */
	if (!(buf[FINGER_EV_V1_OFFSET_ID] & 0x1))
		return;

	w = buf[FINGER_EV_V1_OFFSET_W];
	w *= param->scaling_factor;

	p = buf[FINGER_EV_V1_OFFSET_P];

	x = get_unaligned_le16(buf + FINGER_EV_V1_OFFSET_X);

	y = get_unaligned_le16(buf + FINGER_EV_V1_OFFSET_Y);
	y = DIV_ROUND_CLOSEST(y * param->phy_h, param->phy_w);

	/* Refuse incorrect coordinates */
	if (x > param->max_x || y > param->max_y)
		return;

	dev_dbg(input->dev.parent, "tip on (%d), x(%d), y(%d)\n",
		finger_id, x, y);

	input_mt_slot(input, finger_id);
	input_mt_report_slot_state(input, MT_TOOL_FINGER, 1);
	input_report_abs(input, ABS_MT_TOUCH_MAJOR, w);
	input_report_abs(input, ABS_MT_PRESSURE, p);
	input_report_abs(input, ABS_MT_POSITION_X, x);
	input_report_abs(input, ABS_MT_POSITION_Y, y);
}

static irqreturn_t wdt87xx_ts_interrupt(int irq, void *dev_id)
{
	struct wdt87xx_data *wdt = dev_id;
	struct i2c_client *client = wdt->client;
	int i, fingers;
	int error;
	u8 raw_buf[WDT_V1_RAW_BUF_COUNT] = {0};

	error = i2c_master_recv(client, raw_buf, WDT_V1_RAW_BUF_COUNT);
	if (error < 0) {
		dev_err(&client->dev, "read v1 raw data failed: %d\n", error);
		goto irq_exit;
	}

	fingers = raw_buf[TOUCH_PK_V1_OFFSET_FNGR_NUM];
	if (!fingers)
		goto irq_exit;

	for (i = 0; i < WDT_MAX_FINGER; i++)
		wdt87xx_report_contact(wdt->input,
				       &wdt->param,
				       &raw_buf[TOUCH_PK_V1_OFFSET_EVENT +
						i * FINGER_EV_V1_SIZE]);

	input_mt_sync_frame(wdt->input);
	input_sync(wdt->input);

irq_exit:
	return IRQ_HANDLED;
}

static int wdt87xx_ts_create_input_device(struct wdt87xx_data *wdt)
{
	struct device *dev = &wdt->client->dev;
	struct input_dev *input;
	unsigned int res = DIV_ROUND_CLOSEST(MAX_UNIT_AXIS, wdt->param.phy_w);
	int error;

	input = devm_input_allocate_device(dev);
	if (!input) {
		dev_err(dev, "failed to allocate input device\n");
		return -ENOMEM;
	}
	wdt->input = input;

	input->name = "WDT87xx Touchscreen";
	input->id.bustype = BUS_I2C;
	input->phys = wdt->phys;

	input_set_abs_params(input, ABS_MT_POSITION_X, 0,
			     wdt->param.max_x, 0, 0);
	input_set_abs_params(input, ABS_MT_POSITION_Y, 0,
			     wdt->param.max_y, 0, 0);
	input_abs_set_res(input, ABS_MT_POSITION_X, res);
	input_abs_set_res(input, ABS_MT_POSITION_Y, res);

	input_set_abs_params(input, ABS_MT_TOUCH_MAJOR,
			     0, wdt->param.max_x, 0, 0);
	input_set_abs_params(input, ABS_MT_PRESSURE, 0, 0xFF, 0, 0);

	input_mt_init_slots(input, WDT_MAX_FINGER,
			    INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED);

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

	return 0;
}

static int wdt87xx_ts_probe(struct i2c_client *client,
			    const struct i2c_device_id *id)
{
	struct wdt87xx_data *wdt;
	int error;

	dev_dbg(&client->dev, "adapter=%d, client irq: %d\n",
		client->adapter->nr, client->irq);

	/* Check if the I2C function is ok in this adaptor */
	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
		return -ENXIO;

	wdt = devm_kzalloc(&client->dev, sizeof(*wdt), GFP_KERNEL);
	if (!wdt)
		return -ENOMEM;

	wdt->client = client;
	mutex_init(&wdt->fw_mutex);
	i2c_set_clientdata(client, wdt);

	snprintf(wdt->phys, sizeof(wdt->phys), "i2c-%u-%04x/input0",
		 client->adapter->nr, client->addr);

	error = wdt87xx_get_sysparam(client, &wdt->param);
	if (error)
		return error;

	error = wdt87xx_ts_create_input_device(wdt);
	if (error)
		return error;

	error = devm_request_threaded_irq(&client->dev, client->irq,
					  NULL, wdt87xx_ts_interrupt,
					  IRQF_ONESHOT,
					  client->name, wdt);
	if (error) {
		dev_err(&client->dev, "request irq failed: %d\n", error);
		return error;
	}

	error = sysfs_create_group(&client->dev.kobj, &wdt87xx_attr_group);
	if (error) {
		dev_err(&client->dev, "create sysfs failed: %d\n", error);
		return error;
	}

	return 0;
}

static int wdt87xx_ts_remove(struct i2c_client *client)
{
	sysfs_remove_group(&client->dev.kobj, &wdt87xx_attr_group);

	return 0;
}

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

	disable_irq(client->irq);

	error = wdt87xx_send_command(client, VND_CMD_STOP, MODE_IDLE);
	if (error) {
		enable_irq(client->irq);
		dev_err(&client->dev,
			"failed to stop device when suspending: %d\n",
			error);
		return error;
	}

	return 0;
}

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

	/*
	 * The chip may have been reset while system is resuming,
	 * give it some time to settle.
	 */
	mdelay(100);

	error = wdt87xx_send_command(client, VND_CMD_START, 0);
	if (error)
		dev_err(&client->dev,
			"failed to start device when resuming: %d\n",
			error);

	enable_irq(client->irq);

	return 0;
}

static SIMPLE_DEV_PM_OPS(wdt87xx_pm_ops, wdt87xx_suspend, wdt87xx_resume);

static const struct i2c_device_id wdt87xx_dev_id[] = {
	{ WDT87XX_NAME, 0 },
	{ }
};
MODULE_DEVICE_TABLE(i2c, wdt87xx_dev_id);

static const struct acpi_device_id wdt87xx_acpi_id[] = {
	{ "WDHT0001", 0 },
	{ }
};
MODULE_DEVICE_TABLE(acpi, wdt87xx_acpi_id);

static struct i2c_driver wdt87xx_driver = {
	.probe		= wdt87xx_ts_probe,
	.remove		= wdt87xx_ts_remove,
	.id_table	= wdt87xx_dev_id,
	.driver	= {
		.name	= WDT87XX_NAME,
		.pm     = &wdt87xx_pm_ops,
		.acpi_match_table = ACPI_PTR(wdt87xx_acpi_id),
	},
};
module_i2c_driver(wdt87xx_driver);

MODULE_AUTHOR("HN Chen <hn.chen@weidahitech.com>");
MODULE_DESCRIPTION("WeidaHiTech WDT87XX Touchscreen driver");
MODULE_VERSION(WDT87XX_DRV_VER);
MODULE_LICENSE("GPL");
