// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (C) 2021
 * Author(s): Giulio Benetti <giulio.benetti@benettiengineering.com>
 */

#include <linux/delay.h>
#include <linux/gpio/consumer.h>
#include <linux/i2c.h>
#include <linux/interrupt.h>
#include <linux/input.h>
#include <linux/input/mt.h>
#include <linux/input/touchscreen.h>
#include <linux/irq.h>
#include <linux/regulator/consumer.h>
#include <linux/regmap.h>

#include <asm/unaligned.h>

#define HY46XX_CHKSUM_CODE		0x1
#define HY46XX_FINGER_NUM		0x2
#define HY46XX_CHKSUM_LEN		0x7
#define HY46XX_THRESHOLD		0x80
#define HY46XX_GLOVE_EN			0x84
#define HY46XX_REPORT_SPEED		0x88
#define HY46XX_PWR_NOISE_EN		0x89
#define HY46XX_FILTER_DATA		0x8A
#define HY46XX_GAIN			0x92
#define HY46XX_EDGE_OFFSET		0x93
#define HY46XX_RX_NR_USED		0x94
#define HY46XX_TX_NR_USED		0x95
#define HY46XX_PWR_MODE			0xA5
#define HY46XX_FW_VERSION		0xA6
#define HY46XX_LIB_VERSION		0xA7
#define HY46XX_TP_INFO			0xA8
#define HY46XX_TP_CHIP_ID		0xA9
#define HY46XX_BOOT_VER			0xB0

#define HY46XX_TPLEN			0x6
#define HY46XX_REPORT_PKT_LEN		0x44

#define HY46XX_MAX_SUPPORTED_POINTS	11

#define TOUCH_EVENT_DOWN		0x00
#define TOUCH_EVENT_UP			0x01
#define TOUCH_EVENT_CONTACT		0x02
#define TOUCH_EVENT_RESERVED		0x03

struct hycon_hy46xx_data {
	struct i2c_client *client;
	struct input_dev *input;
	struct touchscreen_properties prop;
	struct regulator *vcc;

	struct gpio_desc *reset_gpio;

	struct mutex mutex;
	struct regmap *regmap;

	int threshold;
	bool glove_enable;
	int report_speed;
	bool noise_filter_enable;
	int filter_data;
	int gain;
	int edge_offset;
	int rx_number_used;
	int tx_number_used;
	int power_mode;
	int fw_version;
	int lib_version;
	int tp_information;
	int tp_chip_id;
	int bootloader_version;
};

static const struct regmap_config hycon_hy46xx_i2c_regmap_config = {
	.reg_bits = 8,
	.val_bits = 8,
};

static bool hycon_hy46xx_check_checksum(struct hycon_hy46xx_data *tsdata, u8 *buf)
{
	u8 chksum = 0;
	int i;

	for (i = 2; i < buf[HY46XX_CHKSUM_LEN]; i++)
		chksum += buf[i];

	if (chksum == buf[HY46XX_CHKSUM_CODE])
		return true;

	dev_err_ratelimited(&tsdata->client->dev,
			    "checksum error: 0x%02x expected, got 0x%02x\n",
			    chksum, buf[HY46XX_CHKSUM_CODE]);

	return false;
}

static irqreturn_t hycon_hy46xx_isr(int irq, void *dev_id)
{
	struct hycon_hy46xx_data *tsdata = dev_id;
	struct device *dev = &tsdata->client->dev;
	u8 rdbuf[HY46XX_REPORT_PKT_LEN];
	int i, x, y, id;
	int error;

	memset(rdbuf, 0, sizeof(rdbuf));

	error = regmap_bulk_read(tsdata->regmap, 0, rdbuf, sizeof(rdbuf));
	if (error) {
		dev_err_ratelimited(dev, "Unable to fetch data, error: %d\n",
				    error);
		goto out;
	}

	if (!hycon_hy46xx_check_checksum(tsdata, rdbuf))
		goto out;

	for (i = 0; i < HY46XX_MAX_SUPPORTED_POINTS; i++) {
		u8 *buf = &rdbuf[3 + (HY46XX_TPLEN * i)];
		int type = buf[0] >> 6;

		if (type == TOUCH_EVENT_RESERVED)
			continue;

		x = get_unaligned_be16(buf) & 0x0fff;
		y = get_unaligned_be16(buf + 2) & 0x0fff;

		id = buf[2] >> 4;

		input_mt_slot(tsdata->input, id);
		if (input_mt_report_slot_state(tsdata->input, MT_TOOL_FINGER,
					       type != TOUCH_EVENT_UP))
			touchscreen_report_pos(tsdata->input, &tsdata->prop,
					       x, y, true);
	}

	input_mt_report_pointer_emulation(tsdata->input, false);
	input_sync(tsdata->input);

out:
	return IRQ_HANDLED;
}

struct hycon_hy46xx_attribute {
	struct device_attribute dattr;
	size_t field_offset;
	u8 address;
	u8 limit_low;
	u8 limit_high;
};

#define HYCON_ATTR_U8(_field, _mode, _address, _limit_low, _limit_high)	\
	struct hycon_hy46xx_attribute hycon_hy46xx_attr_##_field = {		\
		.dattr = __ATTR(_field, _mode,				\
				hycon_hy46xx_setting_show,			\
				hycon_hy46xx_setting_store),			\
		.field_offset = offsetof(struct hycon_hy46xx_data, _field),	\
		.address = _address,					\
		.limit_low = _limit_low,				\
		.limit_high = _limit_high,				\
	}

#define HYCON_ATTR_BOOL(_field, _mode, _address)			\
	struct hycon_hy46xx_attribute hycon_hy46xx_attr_##_field = {		\
		.dattr = __ATTR(_field, _mode,				\
				hycon_hy46xx_setting_show,			\
				hycon_hy46xx_setting_store),			\
		.field_offset = offsetof(struct hycon_hy46xx_data, _field),	\
		.address = _address,					\
		.limit_low = false,					\
		.limit_high = true,					\
	}

static ssize_t hycon_hy46xx_setting_show(struct device *dev,
				   struct device_attribute *dattr, char *buf)
{
	struct i2c_client *client = to_i2c_client(dev);
	struct hycon_hy46xx_data *tsdata = i2c_get_clientdata(client);
	struct hycon_hy46xx_attribute *attr =
			container_of(dattr, struct hycon_hy46xx_attribute, dattr);
	u8 *field = (u8 *)tsdata + attr->field_offset;
	size_t count = 0;
	int error = 0;
	int val;

	mutex_lock(&tsdata->mutex);

	error = regmap_read(tsdata->regmap, attr->address, &val);
	if (error < 0) {
		dev_err(&tsdata->client->dev,
			"Failed to fetch attribute %s, error %d\n",
			dattr->attr.name, error);
		goto out;
	}

	if (val != *field) {
		dev_warn(&tsdata->client->dev,
			 "%s: read (%d) and stored value (%d) differ\n",
			 dattr->attr.name, val, *field);
		*field = val;
	}

	count = scnprintf(buf, PAGE_SIZE, "%d\n", val);

out:
	mutex_unlock(&tsdata->mutex);
	return error ?: count;
}

static ssize_t hycon_hy46xx_setting_store(struct device *dev,
					struct device_attribute *dattr,
					const char *buf, size_t count)
{
	struct i2c_client *client = to_i2c_client(dev);
	struct hycon_hy46xx_data *tsdata = i2c_get_clientdata(client);
	struct hycon_hy46xx_attribute *attr =
			container_of(dattr, struct hycon_hy46xx_attribute, dattr);
	u8 *field = (u8 *)tsdata + attr->field_offset;
	unsigned int val;
	int error;

	mutex_lock(&tsdata->mutex);

	error = kstrtouint(buf, 0, &val);
	if (error)
		goto out;

	if (val < attr->limit_low || val > attr->limit_high) {
		error = -ERANGE;
		goto out;
	}

	error = regmap_write(tsdata->regmap, attr->address, val);
	if (error < 0) {
		dev_err(&tsdata->client->dev,
			"Failed to update attribute %s, error: %d\n",
			dattr->attr.name, error);
		goto out;
	}
	*field = val;

out:
	mutex_unlock(&tsdata->mutex);
	return error ?: count;
}

static HYCON_ATTR_U8(threshold, 0644, HY46XX_THRESHOLD, 0, 255);
static HYCON_ATTR_BOOL(glove_enable, 0644, HY46XX_GLOVE_EN);
static HYCON_ATTR_U8(report_speed, 0644, HY46XX_REPORT_SPEED, 0, 255);
static HYCON_ATTR_BOOL(noise_filter_enable, 0644, HY46XX_PWR_NOISE_EN);
static HYCON_ATTR_U8(filter_data, 0644, HY46XX_FILTER_DATA, 0, 5);
static HYCON_ATTR_U8(gain, 0644, HY46XX_GAIN, 0, 5);
static HYCON_ATTR_U8(edge_offset, 0644, HY46XX_EDGE_OFFSET, 0, 5);
static HYCON_ATTR_U8(fw_version, 0444, HY46XX_FW_VERSION, 0, 255);
static HYCON_ATTR_U8(lib_version, 0444, HY46XX_LIB_VERSION, 0, 255);
static HYCON_ATTR_U8(tp_information, 0444, HY46XX_TP_INFO, 0, 255);
static HYCON_ATTR_U8(tp_chip_id, 0444, HY46XX_TP_CHIP_ID, 0, 255);
static HYCON_ATTR_U8(bootloader_version, 0444, HY46XX_BOOT_VER, 0, 255);

static struct attribute *hycon_hy46xx_attrs[] = {
	&hycon_hy46xx_attr_threshold.dattr.attr,
	&hycon_hy46xx_attr_glove_enable.dattr.attr,
	&hycon_hy46xx_attr_report_speed.dattr.attr,
	&hycon_hy46xx_attr_noise_filter_enable.dattr.attr,
	&hycon_hy46xx_attr_filter_data.dattr.attr,
	&hycon_hy46xx_attr_gain.dattr.attr,
	&hycon_hy46xx_attr_edge_offset.dattr.attr,
	&hycon_hy46xx_attr_fw_version.dattr.attr,
	&hycon_hy46xx_attr_lib_version.dattr.attr,
	&hycon_hy46xx_attr_tp_information.dattr.attr,
	&hycon_hy46xx_attr_tp_chip_id.dattr.attr,
	&hycon_hy46xx_attr_bootloader_version.dattr.attr,
	NULL
};

static const struct attribute_group hycon_hy46xx_attr_group = {
	.attrs = hycon_hy46xx_attrs,
};

static void hycon_hy46xx_get_defaults(struct device *dev, struct hycon_hy46xx_data *tsdata)
{
	bool val_bool;
	int error;
	u32 val;

	error = device_property_read_u32(dev, "hycon,threshold", &val);
	if (!error) {
		error = regmap_write(tsdata->regmap, HY46XX_THRESHOLD, val);
		if (error < 0)
			goto out;

		tsdata->threshold = val;
	}

	val_bool = device_property_read_bool(dev, "hycon,glove-enable");
	error = regmap_write(tsdata->regmap, HY46XX_GLOVE_EN, val_bool);
	if (error < 0)
		goto out;
	tsdata->glove_enable = val_bool;

	error = device_property_read_u32(dev, "hycon,report-speed-hz", &val);
	if (!error) {
		error = regmap_write(tsdata->regmap, HY46XX_REPORT_SPEED, val);
		if (error < 0)
			goto out;

		tsdata->report_speed = val;
	}

	val_bool = device_property_read_bool(dev, "hycon,noise-filter-enable");
	error = regmap_write(tsdata->regmap, HY46XX_PWR_NOISE_EN, val_bool);
	if (error < 0)
		goto out;
	tsdata->noise_filter_enable = val_bool;

	error = device_property_read_u32(dev, "hycon,filter-data", &val);
	if (!error) {
		error = regmap_write(tsdata->regmap, HY46XX_FILTER_DATA, val);
		if (error < 0)
			goto out;

		tsdata->filter_data = val;
	}

	error = device_property_read_u32(dev, "hycon,gain", &val);
	if (!error) {
		error = regmap_write(tsdata->regmap, HY46XX_GAIN, val);
		if (error < 0)
			goto out;

		tsdata->gain = val;
	}

	error = device_property_read_u32(dev, "hycon,edge-offset", &val);
	if (!error) {
		error = regmap_write(tsdata->regmap, HY46XX_EDGE_OFFSET, val);
		if (error < 0)
			goto out;

		tsdata->edge_offset = val;
	}

	return;
out:
	dev_err(&tsdata->client->dev, "Failed to set default settings");
}

static void hycon_hy46xx_get_parameters(struct hycon_hy46xx_data *tsdata)
{
	int error;
	u32 val;

	error = regmap_read(tsdata->regmap, HY46XX_THRESHOLD, &val);
	if (error < 0)
		goto out;
	tsdata->threshold = val;

	error = regmap_read(tsdata->regmap, HY46XX_GLOVE_EN, &val);
	if (error < 0)
		goto out;
	tsdata->glove_enable = val;

	error = regmap_read(tsdata->regmap, HY46XX_REPORT_SPEED, &val);
	if (error < 0)
		goto out;
	tsdata->report_speed = val;

	error = regmap_read(tsdata->regmap, HY46XX_PWR_NOISE_EN, &val);
	if (error < 0)
		goto out;
	tsdata->noise_filter_enable = val;

	error = regmap_read(tsdata->regmap, HY46XX_FILTER_DATA, &val);
	if (error < 0)
		goto out;
	tsdata->filter_data = val;

	error = regmap_read(tsdata->regmap, HY46XX_GAIN, &val);
	if (error < 0)
		goto out;
	tsdata->gain = val;

	error = regmap_read(tsdata->regmap, HY46XX_EDGE_OFFSET, &val);
	if (error < 0)
		goto out;
	tsdata->edge_offset = val;

	error = regmap_read(tsdata->regmap, HY46XX_RX_NR_USED, &val);
	if (error < 0)
		goto out;
	tsdata->rx_number_used = val;

	error = regmap_read(tsdata->regmap, HY46XX_TX_NR_USED, &val);
	if (error < 0)
		goto out;
	tsdata->tx_number_used = val;

	error = regmap_read(tsdata->regmap, HY46XX_PWR_MODE, &val);
	if (error < 0)
		goto out;
	tsdata->power_mode = val;

	error = regmap_read(tsdata->regmap, HY46XX_FW_VERSION, &val);
	if (error < 0)
		goto out;
	tsdata->fw_version = val;

	error = regmap_read(tsdata->regmap, HY46XX_LIB_VERSION, &val);
	if (error < 0)
		goto out;
	tsdata->lib_version = val;

	error = regmap_read(tsdata->regmap, HY46XX_TP_INFO, &val);
	if (error < 0)
		goto out;
	tsdata->tp_information = val;

	error = regmap_read(tsdata->regmap, HY46XX_TP_CHIP_ID, &val);
	if (error < 0)
		goto out;
	tsdata->tp_chip_id = val;

	error = regmap_read(tsdata->regmap, HY46XX_BOOT_VER, &val);
	if (error < 0)
		goto out;
	tsdata->bootloader_version = val;

	return;
out:
	dev_err(&tsdata->client->dev, "Failed to read default settings");
}

static void hycon_hy46xx_disable_regulator(void *arg)
{
	struct hycon_hy46xx_data *data = arg;

	regulator_disable(data->vcc);
}

static int hycon_hy46xx_probe(struct i2c_client *client,
					 const struct i2c_device_id *id)
{
	struct hycon_hy46xx_data *tsdata;
	struct input_dev *input;
	int error;

	dev_dbg(&client->dev, "probing for HYCON HY46XX I2C\n");

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

	tsdata->vcc = devm_regulator_get(&client->dev, "vcc");
	if (IS_ERR(tsdata->vcc)) {
		error = PTR_ERR(tsdata->vcc);
		if (error != -EPROBE_DEFER)
			dev_err(&client->dev,
				"failed to request regulator: %d\n", error);
		return error;
	}

	error = regulator_enable(tsdata->vcc);
	if (error < 0) {
		dev_err(&client->dev, "failed to enable vcc: %d\n", error);
		return error;
	}

	error = devm_add_action_or_reset(&client->dev,
					 hycon_hy46xx_disable_regulator,
					 tsdata);
	if (error)
		return error;

	tsdata->reset_gpio = devm_gpiod_get_optional(&client->dev,
						     "reset", GPIOD_OUT_LOW);
	if (IS_ERR(tsdata->reset_gpio)) {
		error = PTR_ERR(tsdata->reset_gpio);
		dev_err(&client->dev,
			"Failed to request GPIO reset pin, error %d\n", error);
		return error;
	}

	if (tsdata->reset_gpio) {
		usleep_range(5000, 6000);
		gpiod_set_value_cansleep(tsdata->reset_gpio, 1);
		usleep_range(5000, 6000);
		gpiod_set_value_cansleep(tsdata->reset_gpio, 0);
		msleep(1000);
	}

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

	mutex_init(&tsdata->mutex);
	tsdata->client = client;
	tsdata->input = input;

	tsdata->regmap = devm_regmap_init_i2c(client,
					      &hycon_hy46xx_i2c_regmap_config);
	if (IS_ERR(tsdata->regmap)) {
		dev_err(&client->dev, "regmap allocation failed\n");
		return PTR_ERR(tsdata->regmap);
	}

	hycon_hy46xx_get_defaults(&client->dev, tsdata);
	hycon_hy46xx_get_parameters(tsdata);

	input->name = "Hycon Capacitive Touch";
	input->id.bustype = BUS_I2C;
	input->dev.parent = &client->dev;

	input_set_abs_params(input, ABS_MT_POSITION_X, 0, -1, 0, 0);
	input_set_abs_params(input, ABS_MT_POSITION_Y, 0, -1, 0, 0);

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

	error = input_mt_init_slots(input, HY46XX_MAX_SUPPORTED_POINTS,
				    INPUT_MT_DIRECT);
	if (error) {
		dev_err(&client->dev, "Unable to init MT slots.\n");
		return error;
	}

	i2c_set_clientdata(client, tsdata);

	error = devm_request_threaded_irq(&client->dev, client->irq,
					  NULL, hycon_hy46xx_isr, IRQF_ONESHOT,
					  client->name, tsdata);
	if (error) {
		dev_err(&client->dev, "Unable to request touchscreen IRQ.\n");
		return error;
	}

	error = devm_device_add_group(&client->dev, &hycon_hy46xx_attr_group);
	if (error)
		return error;

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

	dev_dbg(&client->dev,
		"HYCON HY46XX initialized: IRQ %d, Reset pin %d.\n",
		client->irq,
		tsdata->reset_gpio ? desc_to_gpio(tsdata->reset_gpio) : -1);

	return 0;
}

static const struct i2c_device_id hycon_hy46xx_id[] = {
	{ .name = "hy4613" },
	{ .name = "hy4614" },
	{ .name = "hy4621" },
	{ .name = "hy4623" },
	{ .name = "hy4633" },
	{ .name = "hy4635" },
	{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(i2c, hycon_hy46xx_id);

static const struct of_device_id hycon_hy46xx_of_match[] = {
	{ .compatible = "hycon,hy4613" },
	{ .compatible = "hycon,hy4614" },
	{ .compatible = "hycon,hy4621" },
	{ .compatible = "hycon,hy4623" },
	{ .compatible = "hycon,hy4633" },
	{ .compatible = "hycon,hy4635" },
	{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, hycon_hy46xx_of_match);

static struct i2c_driver hycon_hy46xx_driver = {
	.driver = {
		.name = "hycon_hy46xx",
		.of_match_table = hycon_hy46xx_of_match,
		.probe_type = PROBE_PREFER_ASYNCHRONOUS,
	},
	.id_table = hycon_hy46xx_id,
	.probe    = hycon_hy46xx_probe,
};

module_i2c_driver(hycon_hy46xx_driver);

MODULE_AUTHOR("Giulio Benetti <giulio.benetti@benettiengineering.com>");
MODULE_DESCRIPTION("HYCON HY46XX I2C Touchscreen Driver");
MODULE_LICENSE("GPL v2");
