// SPDX-License-Identifier: GPL-2.0-only
/*
 * Dynapro serial touchscreen driver
 *
 * Copyright (c) 2009 Tias Guns
 * Based on the inexio driver (c) Vojtech Pavlik and Dan Streetman and
 * Richard Lemon
 */


/*
 * 2009/09/19 Tias Guns <tias@ulyssis.org>
 *   Copied inexio.c and edited for Dynapro protocol (from retired Xorg module)
 */

#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	"Dynapro serial touchscreen driver"

MODULE_AUTHOR("Tias Guns <tias@ulyssis.org>");
MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");

/*
 * Definitions & global arrays.
 */

#define DYNAPRO_FORMAT_TOUCH_BIT 0x40
#define DYNAPRO_FORMAT_LENGTH 3
#define DYNAPRO_RESPONSE_BEGIN_BYTE 0x80

#define DYNAPRO_MIN_XC 0
#define DYNAPRO_MAX_XC 0x3ff
#define DYNAPRO_MIN_YC 0
#define DYNAPRO_MAX_YC 0x3ff

#define DYNAPRO_GET_XC(data) (data[1] | ((data[0] & 0x38) << 4))
#define DYNAPRO_GET_YC(data) (data[2] | ((data[0] & 0x07) << 7))
#define DYNAPRO_GET_TOUCHED(data) (DYNAPRO_FORMAT_TOUCH_BIT & data[0])

/*
 * Per-touchscreen data.
 */

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

static void dynapro_process_data(struct dynapro *pdynapro)
{
	struct input_dev *dev = pdynapro->dev;

	if (DYNAPRO_FORMAT_LENGTH == ++pdynapro->idx) {
		input_report_abs(dev, ABS_X, DYNAPRO_GET_XC(pdynapro->data));
		input_report_abs(dev, ABS_Y, DYNAPRO_GET_YC(pdynapro->data));
		input_report_key(dev, BTN_TOUCH,
				 DYNAPRO_GET_TOUCHED(pdynapro->data));
		input_sync(dev);

		pdynapro->idx = 0;
	}
}

static irqreturn_t dynapro_interrupt(struct serio *serio,
		unsigned char data, unsigned int flags)
{
	struct dynapro *pdynapro = serio_get_drvdata(serio);

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

	if (DYNAPRO_RESPONSE_BEGIN_BYTE & pdynapro->data[0])
		dynapro_process_data(pdynapro);
	else
		dev_dbg(&serio->dev, "unknown/unsynchronized data: %x\n",
			pdynapro->data[0]);

	return IRQ_HANDLED;
}

static void dynapro_disconnect(struct serio *serio)
{
	struct dynapro *pdynapro = serio_get_drvdata(serio);

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

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

static int dynapro_connect(struct serio *serio, struct serio_driver *drv)
{
	struct dynapro *pdynapro;
	struct input_dev *input_dev;
	int err;

	pdynapro = kzalloc_obj(*pdynapro);
	input_dev = input_allocate_device();
	if (!pdynapro || !input_dev) {
		err = -ENOMEM;
		goto fail1;
	}

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

	input_dev->name = "Dynapro Serial TouchScreen";
	input_dev->phys = pdynapro->phys;
	input_dev->id.bustype = BUS_RS232;
	input_dev->id.vendor = SERIO_DYNAPRO;
	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(pdynapro->dev, ABS_X,
			     DYNAPRO_MIN_XC, DYNAPRO_MAX_XC, 0, 0);
	input_set_abs_params(pdynapro->dev, ABS_Y,
			     DYNAPRO_MIN_YC, DYNAPRO_MAX_YC, 0, 0);

	serio_set_drvdata(serio, pdynapro);

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

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

	return 0;

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

/*
 * The serio driver structure.
 */

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

MODULE_DEVICE_TABLE(serio, dynapro_serio_ids);

static struct serio_driver dynapro_drv = {
	.driver		= {
		.name	= "dynapro",
	},
	.description	= DRIVER_DESC,
	.id_table	= dynapro_serio_ids,
	.interrupt	= dynapro_interrupt,
	.connect	= dynapro_connect,
	.disconnect	= dynapro_disconnect,
};

module_serio_driver(dynapro_drv);
