// SPDX-License-Identifier: GPL-2.0-only
/*
 * iNexio serial touchscreen driver
 *
 * Copyright (c) 2008 Richard Lemon
 * Based on the mtouch driver (c) Vojtech Pavlik and Dan Streetman
 */


/*
 * 2008/06/19 Richard Lemon <richard@codelemon.com>
 *   Copied mtouch.c and edited for iNexio protocol
 */

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

#define DRIVER_DESC	"iNexio serial touchscreen driver"

MODULE_AUTHOR("Richard Lemon <richard@codelemon.com>");
MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");

/*
 * Definitions & global arrays.
 */

#define INEXIO_FORMAT_TOUCH_BIT 0x01
#define INEXIO_FORMAT_LENGTH 5
#define INEXIO_RESPONSE_BEGIN_BYTE 0x80

/* todo: check specs for max length of all responses */
#define INEXIO_MAX_LENGTH 16

#define INEXIO_MIN_XC 0
#define INEXIO_MAX_XC 0x3fff
#define INEXIO_MIN_YC 0
#define INEXIO_MAX_YC 0x3fff

#define INEXIO_GET_XC(data) (((data[1])<<7) | data[2])
#define INEXIO_GET_YC(data) (((data[3])<<7) | data[4])
#define INEXIO_GET_TOUCHED(data) (INEXIO_FORMAT_TOUCH_BIT & data[0])

/*
 * Per-touchscreen data.
 */

struct inexio {
	struct input_dev *dev;
	struct serio *serio;
	int idx;
	unsigned char data[INEXIO_MAX_LENGTH];
	char phys[32];
};

static void inexio_process_data(struct inexio *pinexio)
{
	struct input_dev *dev = pinexio->dev;

	if (INEXIO_FORMAT_LENGTH == ++pinexio->idx) {
		input_report_abs(dev, ABS_X, INEXIO_GET_XC(pinexio->data));
		input_report_abs(dev, ABS_Y, INEXIO_GET_YC(pinexio->data));
		input_report_key(dev, BTN_TOUCH, INEXIO_GET_TOUCHED(pinexio->data));
		input_sync(dev);

		pinexio->idx = 0;
	}
}

static irqreturn_t inexio_interrupt(struct serio *serio,
		unsigned char data, unsigned int flags)
{
	struct inexio *pinexio = serio_get_drvdata(serio);

	pinexio->data[pinexio->idx] = data;

	if (INEXIO_RESPONSE_BEGIN_BYTE&pinexio->data[0])
		inexio_process_data(pinexio);
	else
		printk(KERN_DEBUG "inexio.c: unknown/unsynchronized data from device, byte %x\n",pinexio->data[0]);

	return IRQ_HANDLED;
}

/*
 * inexio_disconnect() is the opposite of inexio_connect()
 */

static void inexio_disconnect(struct serio *serio)
{
	struct inexio *pinexio = serio_get_drvdata(serio);

	input_get_device(pinexio->dev);
	input_unregister_device(pinexio->dev);
	serio_close(serio);
	serio_set_drvdata(serio, NULL);
	input_put_device(pinexio->dev);
	kfree(pinexio);
}

/*
 * inexio_connect() is the routine that is called when someone adds a
 * new serio device that supports iNexio protocol and registers it as
 * an input device. This is usually accomplished using inputattach.
 */

static int inexio_connect(struct serio *serio, struct serio_driver *drv)
{
	struct inexio *pinexio;
	struct input_dev *input_dev;
	int err;

	pinexio = kzalloc(sizeof(*pinexio), GFP_KERNEL);
	input_dev = input_allocate_device();
	if (!pinexio || !input_dev) {
		err = -ENOMEM;
		goto fail1;
	}

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

	input_dev->name = "iNexio Serial TouchScreen";
	input_dev->phys = pinexio->phys;
	input_dev->id.bustype = BUS_RS232;
	input_dev->id.vendor = SERIO_INEXIO;
	input_dev->id.product = 0;
	input_dev->id.version = 0x0001;
	input_dev->dev.parent = &serio->dev;
	input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
	input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
	input_set_abs_params(pinexio->dev, ABS_X, INEXIO_MIN_XC, INEXIO_MAX_XC, 0, 0);
	input_set_abs_params(pinexio->dev, ABS_Y, INEXIO_MIN_YC, INEXIO_MAX_YC, 0, 0);

	serio_set_drvdata(serio, pinexio);

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

	err = input_register_device(pinexio->dev);
	if (err)
		goto fail3;

	return 0;

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

/*
 * The serio driver structure.
 */

static const struct serio_device_id inexio_serio_ids[] = {
	{
		.type	= SERIO_RS232,
		.proto	= SERIO_INEXIO,
		.id	= SERIO_ANY,
		.extra	= SERIO_ANY,
	},
	{ 0 }
};

MODULE_DEVICE_TABLE(serio, inexio_serio_ids);

static struct serio_driver inexio_drv = {
	.driver		= {
		.name	= "inexio",
	},
	.description	= DRIVER_DESC,
	.id_table	= inexio_serio_ids,
	.interrupt	= inexio_interrupt,
	.connect	= inexio_connect,
	.disconnect	= inexio_disconnect,
};

module_serio_driver(inexio_drv);
