// SPDX-License-Identifier: GPL-2.0-only
/*
 *	SEGA Dreamcast controller driver
 *	Based on drivers/usb/iforce.c
 *
 *	Copyright Yaegashi Takeshi, 2001
 *	Adrian McMenamin, 2008 - 2009
 */

#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/input.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/timer.h>
#include <linux/maple.h>

MODULE_AUTHOR("Adrian McMenamin <adrian@mcmen.demon.co.uk>");
MODULE_DESCRIPTION("SEGA Dreamcast controller driver");
MODULE_LICENSE("GPL");

struct dc_pad {
	struct input_dev *dev;
	struct maple_device *mdev;
};

static void dc_pad_callback(struct mapleq *mq)
{
	unsigned short buttons;
	struct maple_device *mapledev = mq->dev;
	struct dc_pad *pad = maple_get_drvdata(mapledev);
	struct input_dev *dev = pad->dev;
	unsigned char *res = mq->recvbuf->buf;

	buttons = ~le16_to_cpup((__le16 *)(res + 8));

	input_report_abs(dev, ABS_HAT0Y,
		(buttons & 0x0010 ? -1 : 0) + (buttons & 0x0020 ? 1 : 0));
	input_report_abs(dev, ABS_HAT0X,
		(buttons & 0x0040 ? -1 : 0) + (buttons & 0x0080 ? 1 : 0));
	input_report_abs(dev, ABS_HAT1Y,
		(buttons & 0x1000 ? -1 : 0) + (buttons & 0x2000 ? 1 : 0));
	input_report_abs(dev, ABS_HAT1X,
		(buttons & 0x4000 ? -1 : 0) + (buttons & 0x8000 ? 1 : 0));

	input_report_key(dev, BTN_C,      buttons & 0x0001);
	input_report_key(dev, BTN_B,      buttons & 0x0002);
	input_report_key(dev, BTN_A,      buttons & 0x0004);
	input_report_key(dev, BTN_START,  buttons & 0x0008);
	input_report_key(dev, BTN_Z,      buttons & 0x0100);
	input_report_key(dev, BTN_Y,      buttons & 0x0200);
	input_report_key(dev, BTN_X,      buttons & 0x0400);
	input_report_key(dev, BTN_SELECT, buttons & 0x0800);

	input_report_abs(dev, ABS_GAS,    res[10]);
	input_report_abs(dev, ABS_BRAKE,  res[11]);
	input_report_abs(dev, ABS_X,      res[12]);
	input_report_abs(dev, ABS_Y,      res[13]);
	input_report_abs(dev, ABS_RX,     res[14]);
	input_report_abs(dev, ABS_RY,     res[15]);
}

static int dc_pad_open(struct input_dev *dev)
{
	struct dc_pad *pad = dev_get_platdata(&dev->dev);

	maple_getcond_callback(pad->mdev, dc_pad_callback, HZ/20,
		MAPLE_FUNC_CONTROLLER);

	return 0;
}

static void dc_pad_close(struct input_dev *dev)
{
	struct dc_pad *pad = dev_get_platdata(&dev->dev);

	maple_getcond_callback(pad->mdev, dc_pad_callback, 0,
		MAPLE_FUNC_CONTROLLER);
}

/* allow the controller to be used */
static int probe_maple_controller(struct device *dev)
{
	static const short btn_bit[32] = {
		BTN_C, BTN_B, BTN_A, BTN_START, -1, -1, -1, -1,
		BTN_Z, BTN_Y, BTN_X, BTN_SELECT, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1,
	};

	static const short abs_bit[32] = {
		-1, -1, -1, -1, ABS_HAT0Y, ABS_HAT0Y, ABS_HAT0X, ABS_HAT0X,
		-1, -1, -1, -1, ABS_HAT1Y, ABS_HAT1Y, ABS_HAT1X, ABS_HAT1X,
		ABS_GAS, ABS_BRAKE, ABS_X, ABS_Y, ABS_RX, ABS_RY, -1, -1,
		-1, -1, -1, -1, -1, -1, -1, -1,
	};

	struct maple_device *mdev = to_maple_dev(dev);
	struct maple_driver *mdrv = to_maple_driver(dev->driver);
	int i, error;
	struct dc_pad *pad;
	struct input_dev *idev;
	unsigned long data = be32_to_cpu(mdev->devinfo.function_data[0]);

	pad = kzalloc(sizeof(struct dc_pad), GFP_KERNEL);
	idev = input_allocate_device();
	if (!pad || !idev) {
		error = -ENOMEM;
		goto fail;
	}

	pad->dev = idev;
	pad->mdev = mdev;

	idev->open = dc_pad_open;
	idev->close = dc_pad_close;

	for (i = 0; i < 32; i++) {
		if (data & (1 << i)) {
			if (btn_bit[i] >= 0)
				__set_bit(btn_bit[i], idev->keybit);
			else if (abs_bit[i] >= 0)
				__set_bit(abs_bit[i], idev->absbit);
		}
	}

	if (idev->keybit[BIT_WORD(BTN_JOYSTICK)])
		idev->evbit[0] |= BIT_MASK(EV_KEY);

	if (idev->absbit[0])
		idev->evbit[0] |= BIT_MASK(EV_ABS);

	for (i = ABS_X; i <= ABS_BRAKE; i++)
		input_set_abs_params(idev, i, 0, 255, 0, 0);

	for (i = ABS_HAT0X; i <= ABS_HAT3Y; i++)
		input_set_abs_params(idev, i, 1, -1, 0, 0);

	idev->dev.platform_data = pad;
	idev->dev.parent = &mdev->dev;
	idev->name = mdev->product_name;
	idev->id.bustype = BUS_HOST;

	error = input_register_device(idev);
	if (error)
		goto fail;

	mdev->driver = mdrv;
	maple_set_drvdata(mdev, pad);

	return 0;

fail:
	input_free_device(idev);
	kfree(pad);
	maple_set_drvdata(mdev, NULL);
	return error;
}

static int remove_maple_controller(struct device *dev)
{
	struct maple_device *mdev = to_maple_dev(dev);
	struct dc_pad *pad = maple_get_drvdata(mdev);

	mdev->callback = NULL;
	input_unregister_device(pad->dev);
	maple_set_drvdata(mdev, NULL);
	kfree(pad);

	return 0;
}

static struct maple_driver dc_pad_driver = {
	.function =	MAPLE_FUNC_CONTROLLER,
	.drv = {
		.name	= "Dreamcast_controller",
		.probe	= probe_maple_controller,
		.remove	= remove_maple_controller,
	},
};

static int __init dc_pad_init(void)
{
	return maple_driver_register(&dc_pad_driver);
}

static void __exit dc_pad_exit(void)
{
	maple_driver_unregister(&dc_pad_driver);
}

module_init(dc_pad_init);
module_exit(dc_pad_exit);
