// SPDX-License-Identifier: GPL-2.0-or-later
/*
 *  Copyright (c) 2001 Vojtech Pavlik
 *
 *  Based on the work of:
 *	Toby Deshane
 */

/*
 * InterAct digital gamepad/joystick driver for Linux
 */

/*
 */

#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/delay.h>
#include <linux/gameport.h>
#include <linux/input.h>
#include <linux/jiffies.h>

#define DRIVER_DESC	"InterAct digital joystick driver"

MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");

#define INTERACT_MAX_START	600	/* 400 us */
#define INTERACT_MAX_STROBE	60	/* 40 us */
#define INTERACT_MAX_LENGTH	32	/* 32 bits */

#define INTERACT_TYPE_HHFX	0	/* HammerHead/FX */
#define INTERACT_TYPE_PP8D	1	/* ProPad 8 */

struct interact {
	struct gameport *gameport;
	struct input_dev *dev;
	int bads;
	int reads;
	unsigned char type;
	unsigned char length;
	char phys[32];
};

static short interact_abs_hhfx[] =
	{ ABS_RX, ABS_RY, ABS_X, ABS_Y, ABS_HAT0X, ABS_HAT0Y, -1 };
static short interact_abs_pp8d[] =
	{ ABS_X, ABS_Y, -1 };

static short interact_btn_hhfx[] =
	{ BTN_TR, BTN_X, BTN_Y, BTN_Z, BTN_A, BTN_B, BTN_C, BTN_TL, BTN_TL2, BTN_TR2, BTN_MODE, BTN_SELECT, -1 };
static short interact_btn_pp8d[] =
	{ BTN_C, BTN_TL, BTN_TR, BTN_A, BTN_B, BTN_Y, BTN_Z, BTN_X, -1 };

struct interact_type {
	int id;
	short *abs;
	short *btn;
	char *name;
	unsigned char length;
	unsigned char b8;
};

static struct interact_type interact_type[] = {
	{ 0x6202, interact_abs_hhfx, interact_btn_hhfx, "InterAct HammerHead/FX",    32, 4 },
	{ 0x53f8, interact_abs_pp8d, interact_btn_pp8d, "InterAct ProPad 8 Digital", 16, 0 },
	{ 0 }};

/*
 * interact_read_packet() reads and InterAct joystick data.
 */

static int interact_read_packet(struct gameport *gameport, int length, u32 *data)
{
	unsigned long flags;
	unsigned char u, v;
	unsigned int t, s;
	int i;

	i = 0;
	data[0] = data[1] = data[2] = 0;
	t = gameport_time(gameport, INTERACT_MAX_START);
	s = gameport_time(gameport, INTERACT_MAX_STROBE);

	local_irq_save(flags);
	gameport_trigger(gameport);
	v = gameport_read(gameport);

	while (t > 0 && i < length) {
		t--;
		u = v; v = gameport_read(gameport);
		if (v & ~u & 0x40) {
			data[0] = (data[0] << 1) | ((v >> 4) & 1);
			data[1] = (data[1] << 1) | ((v >> 5) & 1);
			data[2] = (data[2] << 1) | ((v >> 7) & 1);
			i++;
			t = s;
		}
	}

	local_irq_restore(flags);

	return i;
}

/*
 * interact_poll() reads and analyzes InterAct joystick data.
 */

static void interact_poll(struct gameport *gameport)
{
	struct interact *interact = gameport_get_drvdata(gameport);
	struct input_dev *dev = interact->dev;
	u32 data[3];
	int i;

	interact->reads++;

	if (interact_read_packet(interact->gameport, interact->length, data) < interact->length) {
		interact->bads++;
	} else {

		for (i = 0; i < 3; i++)
			data[i] <<= INTERACT_MAX_LENGTH - interact->length;

		switch (interact->type) {

			case INTERACT_TYPE_HHFX:

				for (i = 0; i < 4; i++)
					input_report_abs(dev, interact_abs_hhfx[i], (data[i & 1] >> ((i >> 1) << 3)) & 0xff);

				for (i = 0; i < 2; i++)
					input_report_abs(dev, ABS_HAT0Y - i,
						((data[1] >> ((i << 1) + 17)) & 1)  - ((data[1] >> ((i << 1) + 16)) & 1));

				for (i = 0; i < 8; i++)
					input_report_key(dev, interact_btn_hhfx[i], (data[0] >> (i + 16)) & 1);

				for (i = 0; i < 4; i++)
					input_report_key(dev, interact_btn_hhfx[i + 8], (data[1] >> (i + 20)) & 1);

				break;

			case INTERACT_TYPE_PP8D:

				for (i = 0; i < 2; i++)
					input_report_abs(dev, interact_abs_pp8d[i],
						((data[0] >> ((i << 1) + 20)) & 1)  - ((data[0] >> ((i << 1) + 21)) & 1));

				for (i = 0; i < 8; i++)
					input_report_key(dev, interact_btn_pp8d[i], (data[1] >> (i + 16)) & 1);

				break;
		}
	}

	input_sync(dev);
}

/*
 * interact_open() is a callback from the input open routine.
 */

static int interact_open(struct input_dev *dev)
{
	struct interact *interact = input_get_drvdata(dev);

	gameport_start_polling(interact->gameport);
	return 0;
}

/*
 * interact_close() is a callback from the input close routine.
 */

static void interact_close(struct input_dev *dev)
{
	struct interact *interact = input_get_drvdata(dev);

	gameport_stop_polling(interact->gameport);
}

/*
 * interact_connect() probes for InterAct joysticks.
 */

static int interact_connect(struct gameport *gameport, struct gameport_driver *drv)
{
	struct interact *interact;
	struct input_dev *input_dev;
	__u32 data[3];
	int i, t;
	int err;

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

	interact->gameport = gameport;
	interact->dev = input_dev;

	gameport_set_drvdata(gameport, interact);

	err = gameport_open(gameport, drv, GAMEPORT_MODE_RAW);
	if (err)
		goto fail1;

	i = interact_read_packet(gameport, INTERACT_MAX_LENGTH * 2, data);

	if (i != 32 || (data[0] >> 24) != 0x0c || (data[1] >> 24) != 0x02) {
		err = -ENODEV;
		goto fail2;
	}

	for (i = 0; interact_type[i].length; i++)
		if (interact_type[i].id == (data[2] >> 16))
			break;

	if (!interact_type[i].length) {
		printk(KERN_WARNING "interact.c: Unknown joystick on %s. [len %d d0 %08x d1 %08x i2 %08x]\n",
			gameport->phys, i, data[0], data[1], data[2]);
		err = -ENODEV;
		goto fail2;
	}

	gameport_set_poll_handler(gameport, interact_poll);
	gameport_set_poll_interval(gameport, 20);

	snprintf(interact->phys, sizeof(interact->phys), "%s/input0", gameport->phys);

	interact->type = i;
	interact->length = interact_type[i].length;

	input_dev->name = interact_type[i].name;
	input_dev->phys = interact->phys;
	input_dev->id.bustype = BUS_GAMEPORT;
	input_dev->id.vendor = GAMEPORT_ID_VENDOR_INTERACT;
	input_dev->id.product = interact_type[i].id;
	input_dev->id.version = 0x0100;
	input_dev->dev.parent = &gameport->dev;

	input_set_drvdata(input_dev, interact);

	input_dev->open = interact_open;
	input_dev->close = interact_close;

	input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);

	for (i = 0; (t = interact_type[interact->type].abs[i]) >= 0; i++) {
		if (i < interact_type[interact->type].b8)
			input_set_abs_params(input_dev, t, 0, 255, 0, 0);
		else
			input_set_abs_params(input_dev, t, -1, 1, 0, 0);
	}

	for (i = 0; (t = interact_type[interact->type].btn[i]) >= 0; i++)
		__set_bit(t, input_dev->keybit);

	err = input_register_device(interact->dev);
	if (err)
		goto fail2;

	return 0;

fail2:	gameport_close(gameport);
fail1:  gameport_set_drvdata(gameport, NULL);
	input_free_device(input_dev);
	kfree(interact);
	return err;
}

static void interact_disconnect(struct gameport *gameport)
{
	struct interact *interact = gameport_get_drvdata(gameport);

	input_unregister_device(interact->dev);
	gameport_close(gameport);
	gameport_set_drvdata(gameport, NULL);
	kfree(interact);
}

static struct gameport_driver interact_drv = {
	.driver		= {
		.name	= "interact",
	},
	.description	= DRIVER_DESC,
	.connect	= interact_connect,
	.disconnect	= interact_disconnect,
};

module_gameport_driver(interact_drv);
