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

/*
 * Guillemot Digital Interface Protocol 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	"Guillemot Digital joystick driver"

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

#define GUILLEMOT_MAX_START	600	/* 600 us */
#define GUILLEMOT_MAX_STROBE	60	/* 60 us */
#define GUILLEMOT_MAX_LENGTH	17	/* 17 bytes */

static short guillemot_abs_pad[] =
	{ ABS_X, ABS_Y, ABS_THROTTLE, ABS_RUDDER, -1 };

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

static struct {
        int x;
        int y;
} guillemot_hat_to_axis[16] = {{ 0,-1}, { 1,-1}, { 1, 0}, { 1, 1}, { 0, 1}, {-1, 1}, {-1, 0}, {-1,-1}};

struct guillemot_type {
	unsigned char id;
	short *abs;
	short *btn;
	int hat;
	char *name;
};

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

static struct guillemot_type guillemot_type[] = {
	{ 0x00, guillemot_abs_pad, guillemot_btn_pad, 1, "Guillemot Pad" },
	{ 0 }};

/*
 * guillemot_read_packet() reads Guillemot joystick data.
 */

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

	for (i = 0; i < GUILLEMOT_MAX_LENGTH; i++)
		data[i] = 0;

	i = 0;
	t = gameport_time(gameport, GUILLEMOT_MAX_START);
	s = gameport_time(gameport, GUILLEMOT_MAX_STROBE);

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

	while (t > 0 && i < GUILLEMOT_MAX_LENGTH * 8) {
		t--;
		u = v; v = gameport_read(gameport);
		if (v & ~u & 0x10) {
			data[i >> 3] |= ((v >> 5) & 1) << (i & 7);
			i++;
			t = s;
		}
	}

	local_irq_restore(flags);

	return i;
}

/*
 * guillemot_poll() reads and analyzes Guillemot joystick data.
 */

static void guillemot_poll(struct gameport *gameport)
{
	struct guillemot *guillemot = gameport_get_drvdata(gameport);
	struct input_dev *dev = guillemot->dev;
	u8 data[GUILLEMOT_MAX_LENGTH];
	int i;

	guillemot->reads++;

	if (guillemot_read_packet(guillemot->gameport, data) != GUILLEMOT_MAX_LENGTH * 8 ||
		data[0] != 0x55 || data[16] != 0xaa) {
		guillemot->bads++;
	} else {

		for (i = 0; i < 6 && guillemot->type->abs[i] >= 0; i++)
			input_report_abs(dev, guillemot->type->abs[i], data[i + 5]);

		if (guillemot->type->hat) {
			input_report_abs(dev, ABS_HAT0X, guillemot_hat_to_axis[data[4] >> 4].x);
			input_report_abs(dev, ABS_HAT0Y, guillemot_hat_to_axis[data[4] >> 4].y);
		}

		for (i = 0; i < 16 && guillemot->type->btn[i] >= 0; i++)
			input_report_key(dev, guillemot->type->btn[i], (data[2 + (i >> 3)] >> (i & 7)) & 1);
	}

	input_sync(dev);
}

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

static int guillemot_open(struct input_dev *dev)
{
	struct guillemot *guillemot = input_get_drvdata(dev);

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

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

static void guillemot_close(struct input_dev *dev)
{
	struct guillemot *guillemot = input_get_drvdata(dev);

	gameport_stop_polling(guillemot->gameport);
}

/*
 * guillemot_connect() probes for Guillemot joysticks.
 */

static int guillemot_connect(struct gameport *gameport, struct gameport_driver *drv)
{
	struct guillemot *guillemot;
	struct input_dev *input_dev;
	u8 data[GUILLEMOT_MAX_LENGTH];
	int i, t;
	int err;

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

	guillemot->gameport = gameport;
	guillemot->dev = input_dev;

	gameport_set_drvdata(gameport, guillemot);

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

	i = guillemot_read_packet(gameport, data);

	if (i != GUILLEMOT_MAX_LENGTH * 8 || data[0] != 0x55 || data[16] != 0xaa) {
		err = -ENODEV;
		goto fail2;
	}

	for (i = 0; guillemot_type[i].name; i++)
		if (guillemot_type[i].id == data[11])
			break;

	if (!guillemot_type[i].name) {
		printk(KERN_WARNING "guillemot.c: Unknown joystick on %s. [ %02x%02x:%04x, ver %d.%02d ]\n",
			gameport->phys, data[12], data[13], data[11], data[14], data[15]);
		err = -ENODEV;
		goto fail2;
	}

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

	snprintf(guillemot->phys, sizeof(guillemot->phys), "%s/input0", gameport->phys);
	guillemot->type = guillemot_type + i;

	input_dev->name = guillemot_type[i].name;
	input_dev->phys = guillemot->phys;
	input_dev->id.bustype = BUS_GAMEPORT;
	input_dev->id.vendor = GAMEPORT_ID_VENDOR_GUILLEMOT;
	input_dev->id.product = guillemot_type[i].id;
	input_dev->id.version = (int)data[14] << 8 | data[15];
	input_dev->dev.parent = &gameport->dev;

	input_set_drvdata(input_dev, guillemot);

	input_dev->open = guillemot_open;
	input_dev->close = guillemot_close;

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

	for (i = 0; (t = guillemot->type->abs[i]) >= 0; i++)
		input_set_abs_params(input_dev, t, 0, 255, 0, 0);

	if (guillemot->type->hat) {
		input_set_abs_params(input_dev, ABS_HAT0X, -1, 1, 0, 0);
		input_set_abs_params(input_dev, ABS_HAT0Y, -1, 1, 0, 0);
	}

	for (i = 0; (t = guillemot->type->btn[i]) >= 0; i++)
		set_bit(t, input_dev->keybit);

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

	return 0;

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

static void guillemot_disconnect(struct gameport *gameport)
{
	struct guillemot *guillemot = gameport_get_drvdata(gameport);

	printk(KERN_INFO "guillemot.c: Failed %d reads out of %d on %s\n", guillemot->reads, guillemot->bads, guillemot->phys);
	input_unregister_device(guillemot->dev);
	gameport_close(gameport);
	kfree(guillemot);
}

static struct gameport_driver guillemot_drv = {
	.driver		= {
		.name	= "guillemot",
	},
	.description	= DRIVER_DESC,
	.connect	= guillemot_connect,
	.disconnect	= guillemot_disconnect,
};

module_gameport_driver(guillemot_drv);
