// SPDX-License-Identifier: GPL-2.0
// Melfas MMS114/MMS152 touchscreen device driver
//
// Copyright (c) 2012 Samsung Electronics Co., Ltd.
// Author: Joonyoung Shim <jy0922.shim@samsung.com>

#include <linux/module.h>
#include <linux/delay.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/i2c.h>
#include <linux/input/mt.h>
#include <linux/input/touchscreen.h>
#include <linux/interrupt.h>
#include <linux/regulator/consumer.h>
#include <linux/slab.h>

/* Write only registers */
#define MMS114_MODE_CONTROL		0x01
#define MMS114_OPERATION_MODE_MASK	0xE
#define MMS114_ACTIVE			BIT(1)

#define MMS114_XY_RESOLUTION_H		0x02
#define MMS114_X_RESOLUTION		0x03
#define MMS114_Y_RESOLUTION		0x04
#define MMS114_CONTACT_THRESHOLD	0x05
#define MMS114_MOVING_THRESHOLD		0x06

/* Read only registers */
#define MMS114_PACKET_SIZE		0x0F
#define MMS114_INFORMATION		0x10
#define MMS114_TSP_REV			0xF0

#define MMS152_FW_REV			0xE1
#define MMS152_COMPAT_GROUP		0xF2

/* Minimum delay time is 50us between stop and start signal of i2c */
#define MMS114_I2C_DELAY		50

/* 200ms needs after power on */
#define MMS114_POWERON_DELAY		200

/* Touchscreen absolute values */
#define MMS114_MAX_AREA			0xff

#define MMS114_MAX_TOUCH		10
#define MMS114_PACKET_NUM		8

/* Touch type */
#define MMS114_TYPE_NONE		0
#define MMS114_TYPE_TOUCHSCREEN		1
#define MMS114_TYPE_TOUCHKEY		2

enum mms_type {
	TYPE_MMS114	= 114,
	TYPE_MMS152	= 152,
	TYPE_MMS345L	= 345,
};

struct mms114_data {
	struct i2c_client	*client;
	struct input_dev	*input_dev;
	struct regulator	*core_reg;
	struct regulator	*io_reg;
	struct touchscreen_properties props;
	enum mms_type		type;
	unsigned int		contact_threshold;
	unsigned int		moving_threshold;

	/* Use cache data for mode control register(write only) */
	u8			cache_mode_control;
};

struct mms114_touch {
	u8 id:4, reserved_bit4:1, type:2, pressed:1;
	u8 x_hi:4, y_hi:4;
	u8 x_lo;
	u8 y_lo;
	u8 width;
	u8 strength;
	u8 reserved[2];
} __packed;

static int __mms114_read_reg(struct mms114_data *data, unsigned int reg,
			     unsigned int len, u8 *val)
{
	struct i2c_client *client = data->client;
	struct i2c_msg xfer[2];
	u8 buf = reg & 0xff;
	int error;

	if (reg <= MMS114_MODE_CONTROL && reg + len > MMS114_MODE_CONTROL)
		BUG();

	/* Write register */
	xfer[0].addr = client->addr;
	xfer[0].flags = client->flags & I2C_M_TEN;
	xfer[0].len = 1;
	xfer[0].buf = &buf;

	/* Read data */
	xfer[1].addr = client->addr;
	xfer[1].flags = (client->flags & I2C_M_TEN) | I2C_M_RD;
	xfer[1].len = len;
	xfer[1].buf = val;

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

	return 0;
}

static int mms114_read_reg(struct mms114_data *data, unsigned int reg)
{
	u8 val;
	int error;

	if (reg == MMS114_MODE_CONTROL)
		return data->cache_mode_control;

	error = __mms114_read_reg(data, reg, 1, &val);
	return error < 0 ? error : val;
}

static int mms114_write_reg(struct mms114_data *data, unsigned int reg,
			    unsigned int val)
{
	struct i2c_client *client = data->client;
	u8 buf[2];
	int error;

	buf[0] = reg & 0xff;
	buf[1] = val & 0xff;

	error = i2c_master_send(client, buf, 2);
	if (error != 2) {
		dev_err(&client->dev,
			"%s: i2c send failed (%d)\n", __func__, error);
		return error < 0 ? error : -EIO;
	}
	udelay(MMS114_I2C_DELAY);

	if (reg == MMS114_MODE_CONTROL)
		data->cache_mode_control = val;

	return 0;
}

static void mms114_process_mt(struct mms114_data *data, struct mms114_touch *touch)
{
	struct i2c_client *client = data->client;
	struct input_dev *input_dev = data->input_dev;
	unsigned int id;
	unsigned int x;
	unsigned int y;

	if (touch->id > MMS114_MAX_TOUCH) {
		dev_err(&client->dev, "Wrong touch id (%d)\n", touch->id);
		return;
	}

	if (touch->type != MMS114_TYPE_TOUCHSCREEN) {
		dev_err(&client->dev, "Wrong touch type (%d)\n", touch->type);
		return;
	}

	id = touch->id - 1;
	x = touch->x_lo | touch->x_hi << 8;
	y = touch->y_lo | touch->y_hi << 8;

	dev_dbg(&client->dev,
		"id: %d, type: %d, pressed: %d, x: %d, y: %d, width: %d, strength: %d\n",
		id, touch->type, touch->pressed,
		x, y, touch->width, touch->strength);

	input_mt_slot(input_dev, id);
	input_mt_report_slot_state(input_dev, MT_TOOL_FINGER, touch->pressed);

	if (touch->pressed) {
		touchscreen_report_pos(input_dev, &data->props, x, y, true);
		input_report_abs(input_dev, ABS_MT_TOUCH_MAJOR, touch->width);
		input_report_abs(input_dev, ABS_MT_PRESSURE, touch->strength);
	}
}

static irqreturn_t mms114_interrupt(int irq, void *dev_id)
{
	struct mms114_data *data = dev_id;
	struct input_dev *input_dev = data->input_dev;
	struct mms114_touch touch[MMS114_MAX_TOUCH];
	int packet_size;
	int touch_size;
	int index;
	int error;

	mutex_lock(&input_dev->mutex);
	if (!input_dev->users) {
		mutex_unlock(&input_dev->mutex);
		goto out;
	}
	mutex_unlock(&input_dev->mutex);

	packet_size = mms114_read_reg(data, MMS114_PACKET_SIZE);
	if (packet_size <= 0)
		goto out;

	touch_size = packet_size / MMS114_PACKET_NUM;

	error = __mms114_read_reg(data, MMS114_INFORMATION, packet_size,
			(u8 *)touch);
	if (error < 0)
		goto out;

	for (index = 0; index < touch_size; index++)
		mms114_process_mt(data, touch + index);

	input_mt_report_pointer_emulation(data->input_dev, true);
	input_sync(data->input_dev);

out:
	return IRQ_HANDLED;
}

static int mms114_set_active(struct mms114_data *data, bool active)
{
	int val;

	val = mms114_read_reg(data, MMS114_MODE_CONTROL);
	if (val < 0)
		return val;

	val &= ~MMS114_OPERATION_MODE_MASK;

	/* If active is false, sleep mode */
	if (active)
		val |= MMS114_ACTIVE;

	return mms114_write_reg(data, MMS114_MODE_CONTROL, val);
}

static int mms114_get_version(struct mms114_data *data)
{
	struct device *dev = &data->client->dev;
	u8 buf[6];
	int group;
	int error;

	switch (data->type) {
	case TYPE_MMS345L:
		error = __mms114_read_reg(data, MMS152_FW_REV, 3, buf);
		if (error)
			return error;

		dev_info(dev, "TSP FW Rev: bootloader 0x%x / core 0x%x / config 0x%x\n",
			 buf[0], buf[1], buf[2]);
		break;

	case TYPE_MMS152:
		error = __mms114_read_reg(data, MMS152_FW_REV, 3, buf);
		if (error)
			return error;

		group = i2c_smbus_read_byte_data(data->client,
						  MMS152_COMPAT_GROUP);
		if (group < 0)
			return group;

		dev_info(dev, "TSP FW Rev: bootloader 0x%x / core 0x%x / config 0x%x, Compat group: %c\n",
			 buf[0], buf[1], buf[2], group);
		break;

	case TYPE_MMS114:
		error = __mms114_read_reg(data, MMS114_TSP_REV, 6, buf);
		if (error)
			return error;

		dev_info(dev, "TSP Rev: 0x%x, HW Rev: 0x%x, Firmware Ver: 0x%x\n",
			 buf[0], buf[1], buf[3]);
		break;
	}

	return 0;
}

static int mms114_setup_regs(struct mms114_data *data)
{
	const struct touchscreen_properties *props = &data->props;
	int val;
	int error;

	error = mms114_get_version(data);
	if (error < 0)
		return error;

	/* Only MMS114 has configuration and power on registers */
	if (data->type != TYPE_MMS114)
		return 0;

	error = mms114_set_active(data, true);
	if (error < 0)
		return error;

	val = (props->max_x >> 8) & 0xf;
	val |= ((props->max_y >> 8) & 0xf) << 4;
	error = mms114_write_reg(data, MMS114_XY_RESOLUTION_H, val);
	if (error < 0)
		return error;

	val = props->max_x & 0xff;
	error = mms114_write_reg(data, MMS114_X_RESOLUTION, val);
	if (error < 0)
		return error;

	val = props->max_x & 0xff;
	error = mms114_write_reg(data, MMS114_Y_RESOLUTION, val);
	if (error < 0)
		return error;

	if (data->contact_threshold) {
		error = mms114_write_reg(data, MMS114_CONTACT_THRESHOLD,
				data->contact_threshold);
		if (error < 0)
			return error;
	}

	if (data->moving_threshold) {
		error = mms114_write_reg(data, MMS114_MOVING_THRESHOLD,
				data->moving_threshold);
		if (error < 0)
			return error;
	}

	return 0;
}

static int mms114_start(struct mms114_data *data)
{
	struct i2c_client *client = data->client;
	int error;

	error = regulator_enable(data->core_reg);
	if (error) {
		dev_err(&client->dev, "Failed to enable avdd: %d\n", error);
		return error;
	}

	error = regulator_enable(data->io_reg);
	if (error) {
		dev_err(&client->dev, "Failed to enable vdd: %d\n", error);
		regulator_disable(data->core_reg);
		return error;
	}

	msleep(MMS114_POWERON_DELAY);

	error = mms114_setup_regs(data);
	if (error < 0) {
		regulator_disable(data->io_reg);
		regulator_disable(data->core_reg);
		return error;
	}

	enable_irq(client->irq);

	return 0;
}

static void mms114_stop(struct mms114_data *data)
{
	struct i2c_client *client = data->client;
	int error;

	disable_irq(client->irq);

	error = regulator_disable(data->io_reg);
	if (error)
		dev_warn(&client->dev, "Failed to disable vdd: %d\n", error);

	error = regulator_disable(data->core_reg);
	if (error)
		dev_warn(&client->dev, "Failed to disable avdd: %d\n", error);
}

static int mms114_input_open(struct input_dev *dev)
{
	struct mms114_data *data = input_get_drvdata(dev);

	return mms114_start(data);
}

static void mms114_input_close(struct input_dev *dev)
{
	struct mms114_data *data = input_get_drvdata(dev);

	mms114_stop(data);
}

static int mms114_parse_legacy_bindings(struct mms114_data *data)
{
	struct device *dev = &data->client->dev;
	struct touchscreen_properties *props = &data->props;

	if (device_property_read_u32(dev, "x-size", &props->max_x)) {
		dev_dbg(dev, "failed to get legacy x-size property\n");
		return -EINVAL;
	}

	if (device_property_read_u32(dev, "y-size", &props->max_y)) {
		dev_dbg(dev, "failed to get legacy y-size property\n");
		return -EINVAL;
	}

	device_property_read_u32(dev, "contact-threshold",
				&data->contact_threshold);
	device_property_read_u32(dev, "moving-threshold",
				&data->moving_threshold);

	if (device_property_read_bool(dev, "x-invert"))
		props->invert_x = true;
	if (device_property_read_bool(dev, "y-invert"))
		props->invert_y = true;

	props->swap_x_y = false;

	return 0;
}

static int mms114_probe(struct i2c_client *client,
				  const struct i2c_device_id *id)
{
	struct mms114_data *data;
	struct input_dev *input_dev;
	const void *match_data;
	int error;

	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
		dev_err(&client->dev, "Not supported I2C adapter\n");
		return -ENODEV;
	}

	data = devm_kzalloc(&client->dev, sizeof(struct mms114_data),
			    GFP_KERNEL);
	input_dev = devm_input_allocate_device(&client->dev);
	if (!data || !input_dev) {
		dev_err(&client->dev, "Failed to allocate memory\n");
		return -ENOMEM;
	}

	data->client = client;
	data->input_dev = input_dev;

	/* FIXME: switch to device_get_match_data() when available */
	match_data = of_device_get_match_data(&client->dev);
	if (!match_data)
		return -EINVAL;

	data->type = (enum mms_type)match_data;

	input_set_capability(input_dev, EV_ABS, ABS_MT_POSITION_X);
	input_set_capability(input_dev, EV_ABS, ABS_MT_POSITION_Y);
	input_set_abs_params(input_dev, ABS_MT_PRESSURE, 0, 255, 0, 0);
	input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR,
			     0, MMS114_MAX_AREA, 0, 0);

	touchscreen_parse_properties(input_dev, true, &data->props);
	if (!data->props.max_x || !data->props.max_y) {
		dev_dbg(&client->dev,
			"missing X/Y size properties, trying legacy bindings\n");
		error = mms114_parse_legacy_bindings(data);
		if (error)
			return error;

		input_set_abs_params(input_dev, ABS_MT_POSITION_X,
				     0, data->props.max_x, 0, 0);
		input_set_abs_params(input_dev, ABS_MT_POSITION_Y,
				     0, data->props.max_y, 0, 0);
	}

	if (data->type == TYPE_MMS114) {
		/*
		 * The firmware handles movement and pressure fuzz, so
		 * don't duplicate that in software.
		 */
		data->moving_threshold = input_abs_get_fuzz(input_dev,
							    ABS_MT_POSITION_X);
		data->contact_threshold = input_abs_get_fuzz(input_dev,
							     ABS_MT_PRESSURE);
		input_abs_set_fuzz(input_dev, ABS_MT_POSITION_X, 0);
		input_abs_set_fuzz(input_dev, ABS_MT_POSITION_Y, 0);
		input_abs_set_fuzz(input_dev, ABS_MT_PRESSURE, 0);
	}

	input_dev->name = devm_kasprintf(&client->dev, GFP_KERNEL,
					 "MELFAS MMS%d Touchscreen",
					 data->type);
	if (!input_dev->name)
		return -ENOMEM;

	input_dev->id.bustype = BUS_I2C;
	input_dev->dev.parent = &client->dev;
	input_dev->open = mms114_input_open;
	input_dev->close = mms114_input_close;

	error = input_mt_init_slots(input_dev, MMS114_MAX_TOUCH,
				    INPUT_MT_DIRECT);
	if (error)
		return error;

	input_set_drvdata(input_dev, data);
	i2c_set_clientdata(client, data);

	data->core_reg = devm_regulator_get(&client->dev, "avdd");
	if (IS_ERR(data->core_reg)) {
		error = PTR_ERR(data->core_reg);
		dev_err(&client->dev,
			"Unable to get the Core regulator (%d)\n", error);
		return error;
	}

	data->io_reg = devm_regulator_get(&client->dev, "vdd");
	if (IS_ERR(data->io_reg)) {
		error = PTR_ERR(data->io_reg);
		dev_err(&client->dev,
			"Unable to get the IO regulator (%d)\n", error);
		return error;
	}

	error = devm_request_threaded_irq(&client->dev, client->irq,
					  NULL, mms114_interrupt, IRQF_ONESHOT,
					  dev_name(&client->dev), data);
	if (error) {
		dev_err(&client->dev, "Failed to register interrupt\n");
		return error;
	}
	disable_irq(client->irq);

	error = input_register_device(data->input_dev);
	if (error) {
		dev_err(&client->dev, "Failed to register input device\n");
		return error;
	}

	return 0;
}

static int __maybe_unused mms114_suspend(struct device *dev)
{
	struct i2c_client *client = to_i2c_client(dev);
	struct mms114_data *data = i2c_get_clientdata(client);
	struct input_dev *input_dev = data->input_dev;
	int id;

	/* Release all touch */
	for (id = 0; id < MMS114_MAX_TOUCH; id++) {
		input_mt_slot(input_dev, id);
		input_mt_report_slot_state(input_dev, MT_TOOL_FINGER, false);
	}

	input_mt_report_pointer_emulation(input_dev, true);
	input_sync(input_dev);

	mutex_lock(&input_dev->mutex);
	if (input_dev->users)
		mms114_stop(data);
	mutex_unlock(&input_dev->mutex);

	return 0;
}

static int __maybe_unused mms114_resume(struct device *dev)
{
	struct i2c_client *client = to_i2c_client(dev);
	struct mms114_data *data = i2c_get_clientdata(client);
	struct input_dev *input_dev = data->input_dev;
	int error;

	mutex_lock(&input_dev->mutex);
	if (input_dev->users) {
		error = mms114_start(data);
		if (error < 0) {
			mutex_unlock(&input_dev->mutex);
			return error;
		}
	}
	mutex_unlock(&input_dev->mutex);

	return 0;
}

static SIMPLE_DEV_PM_OPS(mms114_pm_ops, mms114_suspend, mms114_resume);

static const struct i2c_device_id mms114_id[] = {
	{ "mms114", 0 },
	{ }
};
MODULE_DEVICE_TABLE(i2c, mms114_id);

#ifdef CONFIG_OF
static const struct of_device_id mms114_dt_match[] = {
	{
		.compatible = "melfas,mms114",
		.data = (void *)TYPE_MMS114,
	}, {
		.compatible = "melfas,mms152",
		.data = (void *)TYPE_MMS152,
	}, {
		.compatible = "melfas,mms345l",
		.data = (void *)TYPE_MMS345L,
	},
	{ }
};
MODULE_DEVICE_TABLE(of, mms114_dt_match);
#endif

static struct i2c_driver mms114_driver = {
	.driver = {
		.name	= "mms114",
		.pm	= &mms114_pm_ops,
		.of_match_table = of_match_ptr(mms114_dt_match),
	},
	.probe		= mms114_probe,
	.id_table	= mms114_id,
};

module_i2c_driver(mms114_driver);

/* Module information */
MODULE_AUTHOR("Joonyoung Shim <jy0922.shim@samsung.com>");
MODULE_DESCRIPTION("MELFAS mms114 Touchscreen driver");
MODULE_LICENSE("GPL v2");
