// SPDX-License-Identifier: GPL-2.0+
/*
 * Driver for ChipOne icn8505 i2c touchscreen controller
 *
 * Copyright (c) 2015-2018 Red Hat Inc.
 *
 * Red Hat authors:
 * Hans de Goede <hdegoede@redhat.com>
 */

#include <linux/unaligned.h>
#include <linux/acpi.h>
#include <linux/crc32.h>
#include <linux/delay.h>
#include <linux/firmware.h>
#include <linux/interrupt.h>
#include <linux/i2c.h>
#include <linux/input.h>
#include <linux/input/mt.h>
#include <linux/input/touchscreen.h>
#include <linux/module.h>

/* Normal operation mode defines */
#define ICN8505_REG_ADDR_WIDTH		16

#define ICN8505_REG_POWER		0x0004
#define ICN8505_REG_TOUCHDATA		0x1000
#define ICN8505_REG_CONFIGDATA		0x8000

/* ICN8505_REG_POWER commands */
#define ICN8505_POWER_ACTIVE		0x00
#define ICN8505_POWER_MONITOR		0x01
#define ICN8505_POWER_HIBERNATE		0x02
/*
 * The Android driver uses these to turn on/off the charger filter, but the
 * filter is way too aggressive making e.g. onscreen keyboards unusable.
 */
#define ICN8505_POWER_ENA_CHARGER_MODE	0x55
#define ICN8505_POWER_DIS_CHARGER_MODE	0x66

#define ICN8505_MAX_TOUCHES		10

/* Programming mode defines */
#define ICN8505_PROG_I2C_ADDR		0x30
#define ICN8505_PROG_REG_ADDR_WIDTH	24

#define MAX_FW_UPLOAD_TRIES		3

struct icn8505_touch {
	u8 slot;
	u8 x[2];
	u8 y[2];
	u8 pressure;	/* Seems more like finger width then pressure really */
	u8 event;
/* The difference between 2 and 3 is unclear */
#define ICN8505_EVENT_NO_DATA	1 /* No finger seen yet since wakeup */
#define ICN8505_EVENT_UPDATE1	2 /* New or updated coordinates */
#define ICN8505_EVENT_UPDATE2	3 /* New or updated coordinates */
#define ICN8505_EVENT_END	4 /* Finger lifted */
} __packed;

struct icn8505_touch_data {
	u8 softbutton;
	u8 touch_count;
	struct icn8505_touch touches[ICN8505_MAX_TOUCHES];
} __packed;

struct icn8505_data {
	struct i2c_client *client;
	struct input_dev *input;
	struct touchscreen_properties prop;
	char firmware_name[32];
};

static int icn8505_read_xfer(struct i2c_client *client, u16 i2c_addr,
			     int reg_addr, int reg_addr_width,
			     void *data, int len, bool silent)
{
	u8 buf[3];
	int i, ret;
	struct i2c_msg msg[2] = {
		{
			.addr = i2c_addr,
			.buf = buf,
			.len = reg_addr_width / 8,
		},
		{
			.addr = i2c_addr,
			.flags = I2C_M_RD,
			.buf = data,
			.len = len,
		}
	};

	for (i = 0; i < (reg_addr_width / 8); i++)
		buf[i] = (reg_addr >> (reg_addr_width - (i + 1) * 8)) & 0xff;

	ret = i2c_transfer(client->adapter, msg, 2);
	if (ret != ARRAY_SIZE(msg)) {
		if (ret >= 0)
			ret = -EIO;
		if (!silent)
			dev_err(&client->dev,
				"Error reading addr %#x reg %#x: %d\n",
				i2c_addr, reg_addr, ret);
		return ret;
	}

	return 0;
}

static int icn8505_write_xfer(struct i2c_client *client, u16 i2c_addr,
			      int reg_addr, int reg_addr_width,
			      const void *data, int len, bool silent)
{
	u8 buf[3 + 32]; /* 3 bytes for 24 bit reg-addr + 32 bytes max len */
	int i, ret;
	struct i2c_msg msg = {
		.addr = i2c_addr,
		.buf = buf,
		.len = reg_addr_width / 8 + len,
	};

	if (WARN_ON(len > 32))
		return -EINVAL;

	for (i = 0; i < (reg_addr_width / 8); i++)
		buf[i] = (reg_addr >> (reg_addr_width - (i + 1) * 8)) & 0xff;

	memcpy(buf + reg_addr_width / 8, data, len);

	ret = i2c_transfer(client->adapter, &msg, 1);
	if (ret != 1) {
		if (ret >= 0)
			ret = -EIO;
		if (!silent)
			dev_err(&client->dev,
				"Error writing addr %#x reg %#x: %d\n",
				i2c_addr, reg_addr, ret);
		return ret;
	}

	return 0;
}

static int icn8505_read_data(struct icn8505_data *icn8505, int reg,
			     void *buf, int len)
{
	return icn8505_read_xfer(icn8505->client, icn8505->client->addr, reg,
				 ICN8505_REG_ADDR_WIDTH, buf, len, false);
}

static int icn8505_read_reg_silent(struct icn8505_data *icn8505, int reg)
{
	u8 buf;
	int error;

	error = icn8505_read_xfer(icn8505->client, icn8505->client->addr, reg,
				  ICN8505_REG_ADDR_WIDTH, &buf, 1, true);
	if (error)
		return error;

	return buf;
}

static int icn8505_write_reg(struct icn8505_data *icn8505, int reg, u8 val)
{
	return icn8505_write_xfer(icn8505->client, icn8505->client->addr, reg,
				  ICN8505_REG_ADDR_WIDTH, &val, 1, false);
}

static int icn8505_read_prog_data(struct icn8505_data *icn8505, int reg,
				  void *buf, int len)
{
	return icn8505_read_xfer(icn8505->client, ICN8505_PROG_I2C_ADDR, reg,
				 ICN8505_PROG_REG_ADDR_WIDTH, buf, len, false);
}

static int icn8505_write_prog_data(struct icn8505_data *icn8505, int reg,
				   const void *buf, int len)
{
	return icn8505_write_xfer(icn8505->client, ICN8505_PROG_I2C_ADDR, reg,
				  ICN8505_PROG_REG_ADDR_WIDTH, buf, len, false);
}

static int icn8505_write_prog_reg(struct icn8505_data *icn8505, int reg, u8 val)
{
	return icn8505_write_xfer(icn8505->client, ICN8505_PROG_I2C_ADDR, reg,
				  ICN8505_PROG_REG_ADDR_WIDTH, &val, 1, false);
}

/*
 * Note this function uses a number of magic register addresses and values,
 * there are deliberately no defines for these because the algorithm is taken
 * from the icn85xx Android driver and I do not want to make up possibly wrong
 * names for the addresses and/or values.
 */
static int icn8505_try_fw_upload(struct icn8505_data *icn8505,
				 const struct firmware *fw)
{
	struct device *dev = &icn8505->client->dev;
	size_t offset, count;
	int error;
	u8 buf[4];
	u32 crc;

	/* Put the controller in programming mode */
	error = icn8505_write_prog_reg(icn8505, 0xcc3355, 0x5a);
	if (error)
		return error;

	usleep_range(2000, 5000);

	error = icn8505_write_prog_reg(icn8505, 0x040400, 0x01);
	if (error)
		return error;

	usleep_range(2000, 5000);

	error = icn8505_read_prog_data(icn8505, 0x040002, buf, 1);
	if (error)
		return error;

	if (buf[0] != 0x85) {
		dev_err(dev, "Failed to enter programming mode\n");
		return -ENODEV;
	}

	usleep_range(1000, 5000);

	/* Enable CRC mode */
	error = icn8505_write_prog_reg(icn8505, 0x40028, 1);
	if (error)
		return error;

	/* Send the firmware to SRAM */
	for (offset = 0; offset < fw->size; offset += count) {
		count = min_t(size_t, fw->size - offset, 32);
		error = icn8505_write_prog_data(icn8505, offset,
					      fw->data + offset, count);
		if (error)
			return error;
	}

	/* Disable CRC mode */
	error = icn8505_write_prog_reg(icn8505, 0x40028, 0);
	if (error)
		return error;

	/* Get and check length and CRC */
	error = icn8505_read_prog_data(icn8505, 0x40034, buf, 2);
	if (error)
		return error;

	if (get_unaligned_le16(buf) != fw->size) {
		dev_warn(dev, "Length mismatch after uploading fw\n");
		return -EIO;
	}

	error = icn8505_read_prog_data(icn8505, 0x4002c, buf, 4);
	if (error)
		return error;

	crc = crc32_be(0, fw->data, fw->size);
	if (get_unaligned_le32(buf) != crc) {
		dev_warn(dev, "CRC mismatch after uploading fw\n");
		return -EIO;
	}

	/* Boot controller from SRAM */
	error = icn8505_write_prog_reg(icn8505, 0x40400, 0x03);
	if (error)
		return error;

	usleep_range(2000, 5000);
	return 0;
}

static int icn8505_upload_fw(struct icn8505_data *icn8505)
{
	struct device *dev = &icn8505->client->dev;
	const struct firmware *fw;
	int i, error;

	/*
	 * Always load the firmware, even if we don't need it at boot, we
	 * we may need it at resume. Having loaded it once will make the
	 * firmware class code cache it at suspend/resume.
	 */
	error = firmware_request_platform(&fw, icn8505->firmware_name, dev);
	if (error) {
		dev_err(dev, "Firmware request error %d\n", error);
		return error;
	}

	/* Check if the controller is not already up and running */
	if (icn8505_read_reg_silent(icn8505, 0x000a) == 0x85)
		goto success;

	for (i = 1; i <= MAX_FW_UPLOAD_TRIES; i++) {
		error = icn8505_try_fw_upload(icn8505, fw);
		if (!error)
			goto success;

		dev_err(dev, "Failed to upload firmware: %d (attempt %d/%d)\n",
			error, i, MAX_FW_UPLOAD_TRIES);
		usleep_range(2000, 5000);
	}

success:
	release_firmware(fw);
	return error;
}

static bool icn8505_touch_active(u8 event)
{
	return event == ICN8505_EVENT_UPDATE1 ||
	       event == ICN8505_EVENT_UPDATE2;
}

static irqreturn_t icn8505_irq(int irq, void *dev_id)
{
	struct icn8505_data *icn8505 = dev_id;
	struct device *dev = &icn8505->client->dev;
	struct icn8505_touch_data touch_data;
	int i, error;

	error = icn8505_read_data(icn8505, ICN8505_REG_TOUCHDATA,
				  &touch_data, sizeof(touch_data));
	if (error) {
		dev_err(dev, "Error reading touch data: %d\n", error);
		return IRQ_HANDLED;
	}

	if (touch_data.touch_count > ICN8505_MAX_TOUCHES) {
		dev_warn(dev, "Too many touches %d > %d\n",
			 touch_data.touch_count, ICN8505_MAX_TOUCHES);
		touch_data.touch_count = ICN8505_MAX_TOUCHES;
	}

	for (i = 0; i < touch_data.touch_count; i++) {
		struct icn8505_touch *touch = &touch_data.touches[i];
		bool act = icn8505_touch_active(touch->event);

		input_mt_slot(icn8505->input, touch->slot);
		input_mt_report_slot_state(icn8505->input, MT_TOOL_FINGER, act);
		if (!act)
			continue;

		touchscreen_report_pos(icn8505->input, &icn8505->prop,
				       get_unaligned_le16(touch->x),
				       get_unaligned_le16(touch->y),
				       true);
	}

	input_mt_sync_frame(icn8505->input);
	input_report_key(icn8505->input, KEY_LEFTMETA,
			 touch_data.softbutton == 1);
	input_sync(icn8505->input);

	return IRQ_HANDLED;
}

static int icn8505_probe_acpi(struct icn8505_data *icn8505, struct device *dev)
{
	const char *subsys;
	int error;

	subsys = acpi_get_subsystem_id(ACPI_HANDLE(dev));
	error = PTR_ERR_OR_ZERO(subsys);
	if (error == -ENODATA)
		subsys = "unknown";
	else if (error)
		return error;

	snprintf(icn8505->firmware_name, sizeof(icn8505->firmware_name),
		 "chipone/icn8505-%s.fw", subsys);

	kfree_const(subsys);
	return 0;
}

static int icn8505_probe(struct i2c_client *client)
{
	struct device *dev = &client->dev;
	struct icn8505_data *icn8505;
	struct input_dev *input;
	__le16 resolution[2];
	int error;

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

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

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

	input->name = client->name;
	input->id.bustype = BUS_I2C;

	input_set_capability(input, EV_ABS, ABS_MT_POSITION_X);
	input_set_capability(input, EV_ABS, ABS_MT_POSITION_Y);
	input_set_capability(input, EV_KEY, KEY_LEFTMETA);

	icn8505->client = client;
	icn8505->input = input;
	input_set_drvdata(input, icn8505);

	error = icn8505_probe_acpi(icn8505, dev);
	if (error)
		return error;

	error = icn8505_upload_fw(icn8505);
	if (error)
		return error;

	error = icn8505_read_data(icn8505, ICN8505_REG_CONFIGDATA,
				resolution, sizeof(resolution));
	if (error) {
		dev_err(dev, "Error reading resolution: %d\n", error);
		return error;
	}

	input_set_abs_params(input, ABS_MT_POSITION_X, 0,
			     le16_to_cpu(resolution[0]) - 1, 0, 0);
	input_set_abs_params(input, ABS_MT_POSITION_Y, 0,
			     le16_to_cpu(resolution[1]) - 1, 0, 0);

	touchscreen_parse_properties(input, true, &icn8505->prop);
	if (!input_abs_get_max(input, ABS_MT_POSITION_X) ||
	    !input_abs_get_max(input, ABS_MT_POSITION_Y)) {
		dev_err(dev, "Error touchscreen-size-x and/or -y missing\n");
		return -EINVAL;
	}

	error = input_mt_init_slots(input, ICN8505_MAX_TOUCHES,
				  INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED);
	if (error)
		return error;

	error = devm_request_threaded_irq(dev, client->irq, NULL, icn8505_irq,
					IRQF_ONESHOT, client->name, icn8505);
	if (error) {
		dev_err(dev, "Error requesting irq: %d\n", error);
		return error;
	}

	error = input_register_device(input);
	if (error)
		return error;

	i2c_set_clientdata(client, icn8505);
	return 0;
}

static int icn8505_suspend(struct device *dev)
{
	struct icn8505_data *icn8505 = i2c_get_clientdata(to_i2c_client(dev));

	disable_irq(icn8505->client->irq);

	icn8505_write_reg(icn8505, ICN8505_REG_POWER, ICN8505_POWER_HIBERNATE);

	return 0;
}

static int icn8505_resume(struct device *dev)
{
	struct icn8505_data *icn8505 = i2c_get_clientdata(to_i2c_client(dev));
	int error;

	error = icn8505_upload_fw(icn8505);
	if (error)
		return error;

	enable_irq(icn8505->client->irq);
	return 0;
}

static DEFINE_SIMPLE_DEV_PM_OPS(icn8505_pm_ops, icn8505_suspend, icn8505_resume);

static const struct acpi_device_id icn8505_acpi_match[] = {
	{ "CHPN0001" },
	{ }
};
MODULE_DEVICE_TABLE(acpi, icn8505_acpi_match);

static struct i2c_driver icn8505_driver = {
	.driver = {
		.name	= "chipone_icn8505",
		.pm	= pm_sleep_ptr(&icn8505_pm_ops),
		.acpi_match_table = icn8505_acpi_match,
	},
	.probe = icn8505_probe,
};

module_i2c_driver(icn8505_driver);

MODULE_DESCRIPTION("ChipOne icn8505 I2C Touchscreen Driver");
MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
MODULE_LICENSE("GPL");
