// SPDX-License-Identifier: GPL-2.0-only
/*
 * TSC-40 serial touchscreen driver. It should be compatible with
 * TSC-10 and 25.
 *
 * Author: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
 */

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/input.h>
#include <linux/serio.h>

#define PACKET_LENGTH  5
struct tsc_ser {
	struct input_dev *dev;
	struct serio *serio;
	u32 idx;
	unsigned char data[PACKET_LENGTH];
	char phys[32];
};

static void tsc_process_data(struct tsc_ser *ptsc)
{
	struct input_dev *dev = ptsc->dev;
	u8 *data = ptsc->data;
	u32 x;
	u32 y;

	x = ((data[1] & 0x03) << 8) | data[2];
	y = ((data[3] & 0x03) << 8) | data[4];

	input_report_abs(dev, ABS_X, x);
	input_report_abs(dev, ABS_Y, y);
	input_report_key(dev, BTN_TOUCH, 1);

	input_sync(dev);
}

static irqreturn_t tsc_interrupt(struct serio *serio,
		unsigned char data, unsigned int flags)
{
	struct tsc_ser *ptsc = serio_get_drvdata(serio);
	struct input_dev *dev = ptsc->dev;

	ptsc->data[ptsc->idx] = data;
	switch (ptsc->idx++) {
	case 0:
		if (unlikely((data & 0x3e) != 0x10)) {
			dev_dbg(&serio->dev,
				"unsynchronized packet start (0x%02x)\n", data);
			ptsc->idx = 0;
		} else if (!(data & 0x01)) {
			input_report_key(dev, BTN_TOUCH, 0);
			input_sync(dev);
			ptsc->idx = 0;
		}
		break;

	case 1:
	case 3:
		if (unlikely(data & 0xfc)) {
			dev_dbg(&serio->dev,
				"unsynchronized data 0x%02x at offset %d\n",
				data, ptsc->idx - 1);
			ptsc->idx = 0;
		}
		break;

	case 4:
		tsc_process_data(ptsc);
		ptsc->idx = 0;
		break;
	}

	return IRQ_HANDLED;
}

static int tsc_connect(struct serio *serio, struct serio_driver *drv)
{
	struct tsc_ser *ptsc;
	struct input_dev *input_dev;
	int error;

	ptsc = kzalloc(sizeof(struct tsc_ser), GFP_KERNEL);
	input_dev = input_allocate_device();
	if (!ptsc || !input_dev) {
		error = -ENOMEM;
		goto fail1;
	}

	ptsc->serio = serio;
	ptsc->dev = input_dev;
	snprintf(ptsc->phys, sizeof(ptsc->phys), "%s/input0", serio->phys);

	input_dev->name = "TSC-10/25/40 Serial TouchScreen";
	input_dev->phys = ptsc->phys;
	input_dev->id.bustype = BUS_RS232;
	input_dev->id.vendor = SERIO_TSC40;
	input_dev->id.product = 40;
	input_dev->id.version = 0x0001;
	input_dev->dev.parent = &serio->dev;

	input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
	__set_bit(BTN_TOUCH, input_dev->keybit);
	input_set_abs_params(ptsc->dev, ABS_X, 0, 0x3ff, 0, 0);
	input_set_abs_params(ptsc->dev, ABS_Y, 0, 0x3ff, 0, 0);

	serio_set_drvdata(serio, ptsc);

	error = serio_open(serio, drv);
	if (error)
		goto fail2;

	error = input_register_device(ptsc->dev);
	if (error)
		goto fail3;

	return 0;

fail3:
	serio_close(serio);
fail2:
	serio_set_drvdata(serio, NULL);
fail1:
	input_free_device(input_dev);
	kfree(ptsc);
	return error;
}

static void tsc_disconnect(struct serio *serio)
{
	struct tsc_ser *ptsc = serio_get_drvdata(serio);

	serio_close(serio);

	input_unregister_device(ptsc->dev);
	kfree(ptsc);

	serio_set_drvdata(serio, NULL);
}

static const struct serio_device_id tsc_serio_ids[] = {
	{
		.type   = SERIO_RS232,
		.proto  = SERIO_TSC40,
		.id     = SERIO_ANY,
		.extra  = SERIO_ANY,
	},
	{ 0 }
};
MODULE_DEVICE_TABLE(serio, tsc_serio_ids);

#define DRIVER_DESC    "TSC-10/25/40 serial touchscreen driver"

static struct serio_driver tsc_drv = {
	.driver	= {
		.name   = "tsc40",
	},
	.description    = DRIVER_DESC,
	.id_table	= tsc_serio_ids,
	.interrupt      = tsc_interrupt,
	.connect	= tsc_connect,
	.disconnect     = tsc_disconnect,
};

module_serio_driver(tsc_drv);

MODULE_AUTHOR("Sebastian Andrzej Siewior <bigeasy@linutronix.de>");
MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL v2");
