// SPDX-License-Identifier: GPL-2.0-or-later
/*
 *  Copyright (c) 1998-2001 Vojtech Pavlik
 */

/*
 * FP-Gaming Assassin 3D joystick driver for Linux
 */

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

#define DRIVER_DESC	"FP-Gaming Assassin 3D joystick driver"

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

#define A3D_MAX_START		600	/* 600 us */
#define A3D_MAX_STROBE		80	/* 80 us */
#define A3D_MAX_LENGTH		40	/* 40*3 bits */

#define A3D_MODE_A3D		1	/* Assassin 3D */
#define A3D_MODE_PAN		2	/* Panther */
#define A3D_MODE_OEM		3	/* Panther OEM version */
#define A3D_MODE_PXL		4	/* Panther XL */

static char *a3d_names[] = { NULL, "FP-Gaming Assassin 3D", "MadCatz Panther", "OEM Panther",
			"MadCatz Panther XL", "MadCatz Panther XL w/ rudder" };

struct a3d {
	struct gameport *gameport;
	struct gameport *adc;
	struct input_dev *dev;
	int axes[4];
	int buttons;
	int mode;
	int length;
	int reads;
	int bads;
	char phys[32];
};

/*
 * a3d_read_packet() reads an Assassin 3D packet.
 */

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

	i = 0;
	t = gameport_time(gameport, A3D_MAX_START);
	s = gameport_time(gameport, A3D_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 & 0x10) {
			data[i++] = v >> 5;
			t = s;
		}
	}

	local_irq_restore(flags);

	return i;
}

/*
 * a3d_csum() computes checksum of triplet packet
 */

static int a3d_csum(char *data, int count)
{
	int i, csum = 0;

	for (i = 0; i < count - 2; i++)
		csum += data[i];
	return (csum & 0x3f) != ((data[count - 2] << 3) | data[count - 1]);
}

static void a3d_read(struct a3d *a3d, unsigned char *data)
{
	struct input_dev *dev = a3d->dev;

	switch (a3d->mode) {

		case A3D_MODE_A3D:
		case A3D_MODE_OEM:
		case A3D_MODE_PAN:

			input_report_rel(dev, REL_X, ((data[5] << 6) | (data[6] << 3) | data[ 7]) - ((data[5] & 4) << 7));
			input_report_rel(dev, REL_Y, ((data[8] << 6) | (data[9] << 3) | data[10]) - ((data[8] & 4) << 7));

			input_report_key(dev, BTN_RIGHT,  data[2] & 1);
			input_report_key(dev, BTN_LEFT,   data[3] & 2);
			input_report_key(dev, BTN_MIDDLE, data[3] & 4);

			input_sync(dev);

			a3d->axes[0] = ((signed char)((data[11] << 6) | (data[12] << 3) | (data[13]))) + 128;
			a3d->axes[1] = ((signed char)((data[14] << 6) | (data[15] << 3) | (data[16]))) + 128;
			a3d->axes[2] = ((signed char)((data[17] << 6) | (data[18] << 3) | (data[19]))) + 128;
			a3d->axes[3] = ((signed char)((data[20] << 6) | (data[21] << 3) | (data[22]))) + 128;

			a3d->buttons = ((data[3] << 3) | data[4]) & 0xf;

			break;

		case A3D_MODE_PXL:

			input_report_rel(dev, REL_X, ((data[ 9] << 6) | (data[10] << 3) | data[11]) - ((data[ 9] & 4) << 7));
			input_report_rel(dev, REL_Y, ((data[12] << 6) | (data[13] << 3) | data[14]) - ((data[12] & 4) << 7));

			input_report_key(dev, BTN_RIGHT,  data[2] & 1);
			input_report_key(dev, BTN_LEFT,   data[3] & 2);
			input_report_key(dev, BTN_MIDDLE, data[3] & 4);
			input_report_key(dev, BTN_SIDE,   data[7] & 2);
			input_report_key(dev, BTN_EXTRA,  data[7] & 4);

			input_report_abs(dev, ABS_X,        ((signed char)((data[15] << 6) | (data[16] << 3) | (data[17]))) + 128);
			input_report_abs(dev, ABS_Y,        ((signed char)((data[18] << 6) | (data[19] << 3) | (data[20]))) + 128);
			input_report_abs(dev, ABS_RUDDER,   ((signed char)((data[21] << 6) | (data[22] << 3) | (data[23]))) + 128);
			input_report_abs(dev, ABS_THROTTLE, ((signed char)((data[24] << 6) | (data[25] << 3) | (data[26]))) + 128);

			input_report_abs(dev, ABS_HAT0X, ( data[5]       & 1) - ((data[5] >> 2) & 1));
			input_report_abs(dev, ABS_HAT0Y, ((data[5] >> 1) & 1) - ((data[6] >> 2) & 1));
			input_report_abs(dev, ABS_HAT1X, ((data[4] >> 1) & 1) - ( data[3]       & 1));
			input_report_abs(dev, ABS_HAT1Y, ((data[4] >> 2) & 1) - ( data[4]       & 1));

			input_report_key(dev, BTN_TRIGGER, data[8] & 1);
			input_report_key(dev, BTN_THUMB,   data[8] & 2);
			input_report_key(dev, BTN_TOP,     data[8] & 4);
			input_report_key(dev, BTN_PINKIE,  data[7] & 1);

			input_sync(dev);

			break;
	}
}


/*
 * a3d_poll() reads and analyzes A3D joystick data.
 */

static void a3d_poll(struct gameport *gameport)
{
	struct a3d *a3d = gameport_get_drvdata(gameport);
	unsigned char data[A3D_MAX_LENGTH];

	a3d->reads++;
	if (a3d_read_packet(a3d->gameport, a3d->length, data) != a3d->length ||
	    data[0] != a3d->mode || a3d_csum(data, a3d->length))
		a3d->bads++;
	else
		a3d_read(a3d, data);
}

/*
 * a3d_adc_cooked_read() copies the acis and button data to the
 * callers arrays. It could do the read itself, but the caller could
 * call this more than 50 times a second, which would use too much CPU.
 */

static int a3d_adc_cooked_read(struct gameport *gameport, int *axes, int *buttons)
{
	struct a3d *a3d = gameport->port_data;
	int i;

	for (i = 0; i < 4; i++)
		axes[i] = (a3d->axes[i] < 254) ? a3d->axes[i] : -1;
	*buttons = a3d->buttons;
	return 0;
}

/*
 * a3d_adc_open() is the gameport open routine. It refuses to serve
 * any but cooked data.
 */

static int a3d_adc_open(struct gameport *gameport, int mode)
{
	struct a3d *a3d = gameport->port_data;

	if (mode != GAMEPORT_MODE_COOKED)
		return -1;

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

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

static void a3d_adc_close(struct gameport *gameport)
{
	struct a3d *a3d = gameport->port_data;

	gameport_stop_polling(a3d->gameport);
}

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

static int a3d_open(struct input_dev *dev)
{
	struct a3d *a3d = input_get_drvdata(dev);

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

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

static void a3d_close(struct input_dev *dev)
{
	struct a3d *a3d = input_get_drvdata(dev);

	gameport_stop_polling(a3d->gameport);
}

/*
 * a3d_connect() probes for A3D joysticks.
 */

static int a3d_connect(struct gameport *gameport, struct gameport_driver *drv)
{
	struct a3d *a3d;
	struct input_dev *input_dev;
	struct gameport *adc;
	unsigned char data[A3D_MAX_LENGTH];
	int i;
	int err;

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

	a3d->dev = input_dev;
	a3d->gameport = gameport;

	gameport_set_drvdata(gameport, a3d);

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

	i = a3d_read_packet(gameport, A3D_MAX_LENGTH, data);

	if (!i || a3d_csum(data, i)) {
		err = -ENODEV;
		goto fail2;
	}

	a3d->mode = data[0];

	if (!a3d->mode || a3d->mode > 5) {
		printk(KERN_WARNING "a3d.c: Unknown A3D device detected "
			"(%s, id=%d), contact <vojtech@ucw.cz>\n", gameport->phys, a3d->mode);
		err = -ENODEV;
		goto fail2;
	}

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

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

	input_dev->name = a3d_names[a3d->mode];
	input_dev->phys = a3d->phys;
	input_dev->id.bustype = BUS_GAMEPORT;
	input_dev->id.vendor = GAMEPORT_ID_VENDOR_MADCATZ;
	input_dev->id.product = a3d->mode;
	input_dev->id.version = 0x0100;
	input_dev->dev.parent = &gameport->dev;
	input_dev->open = a3d_open;
	input_dev->close = a3d_close;

	input_set_drvdata(input_dev, a3d);

	if (a3d->mode == A3D_MODE_PXL) {

		int axes[] = { ABS_X, ABS_Y, ABS_THROTTLE, ABS_RUDDER };

		a3d->length = 33;

		input_dev->evbit[0] |= BIT_MASK(EV_ABS) | BIT_MASK(EV_KEY) |
			BIT_MASK(EV_REL);
		input_dev->relbit[0] |= BIT_MASK(REL_X) | BIT_MASK(REL_Y);
		input_dev->absbit[0] |= BIT_MASK(ABS_X) | BIT_MASK(ABS_Y) |
			BIT_MASK(ABS_THROTTLE) | BIT_MASK(ABS_RUDDER) |
			BIT_MASK(ABS_HAT0X) | BIT_MASK(ABS_HAT0Y) |
			BIT_MASK(ABS_HAT1X) | BIT_MASK(ABS_HAT1Y);
		input_dev->keybit[BIT_WORD(BTN_MOUSE)] |= BIT_MASK(BTN_RIGHT) |
			BIT_MASK(BTN_LEFT) | BIT_MASK(BTN_MIDDLE) |
			BIT_MASK(BTN_SIDE) | BIT_MASK(BTN_EXTRA);
		input_dev->keybit[BIT_WORD(BTN_JOYSTICK)] |=
			BIT_MASK(BTN_TRIGGER) | BIT_MASK(BTN_THUMB) |
			BIT_MASK(BTN_TOP) | BIT_MASK(BTN_PINKIE);

		a3d_read(a3d, data);

		for (i = 0; i < 4; i++) {
			if (i < 2)
				input_set_abs_params(input_dev, axes[i],
					48, input_abs_get_val(input_dev, axes[i]) * 2 - 48, 0, 8);
			else
				input_set_abs_params(input_dev, axes[i], 2, 253, 0, 0);
			input_set_abs_params(input_dev, ABS_HAT0X + i, -1, 1, 0, 0);
		}

	} else {
		a3d->length = 29;

		input_dev->evbit[0] |= BIT_MASK(EV_KEY) | BIT_MASK(EV_REL);
		input_dev->relbit[0] |= BIT_MASK(REL_X) | BIT_MASK(REL_Y);
		input_dev->keybit[BIT_WORD(BTN_MOUSE)] |= BIT_MASK(BTN_RIGHT) |
			BIT_MASK(BTN_LEFT) | BIT_MASK(BTN_MIDDLE);

		a3d_read(a3d, data);

		if (!(a3d->adc = adc = gameport_allocate_port()))
			printk(KERN_ERR "a3d: Not enough memory for ADC port\n");
		else {
			adc->port_data = a3d;
			adc->open = a3d_adc_open;
			adc->close = a3d_adc_close;
			adc->cooked_read = a3d_adc_cooked_read;
			adc->fuzz = 1;

			gameport_set_name(adc, a3d_names[a3d->mode]);
			gameport_set_phys(adc, "%s/gameport0", gameport->phys);
			adc->dev.parent = &gameport->dev;

			gameport_register_port(adc);
		}
	}

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

	return 0;

 fail3:	if (a3d->adc)
		gameport_unregister_port(a3d->adc);
 fail2:	gameport_close(gameport);
 fail1:	gameport_set_drvdata(gameport, NULL);
	input_free_device(input_dev);
	kfree(a3d);
	return err;
}

static void a3d_disconnect(struct gameport *gameport)
{
	struct a3d *a3d = gameport_get_drvdata(gameport);

	input_unregister_device(a3d->dev);
	if (a3d->adc)
		gameport_unregister_port(a3d->adc);
	gameport_close(gameport);
	gameport_set_drvdata(gameport, NULL);
	kfree(a3d);
}

static struct gameport_driver a3d_drv = {
	.driver		= {
		.name	= "adc",
		.owner	= THIS_MODULE,
	},
	.description	= DRIVER_DESC,
	.connect	= a3d_connect,
	.disconnect	= a3d_disconnect,
};

module_gameport_driver(a3d_drv);
