// SPDX-License-Identifier: GPL-2.0
/*
 * Support for the four N64 controllers.
 *
 * Copyright (c) 2021 Lauri Kasanen
 */

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include <linux/errno.h>
#include <linux/init.h>
#include <linux/input.h>
#include <linux/limits.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/timer.h>

MODULE_AUTHOR("Lauri Kasanen <cand@gmx.com>");
MODULE_DESCRIPTION("Driver for N64 controllers");
MODULE_LICENSE("GPL");

#define PIF_RAM 0x1fc007c0

#define SI_DRAM_REG 0
#define SI_READ_REG 1
#define SI_WRITE_REG 4
#define SI_STATUS_REG 6

#define SI_STATUS_DMA_BUSY  BIT(0)
#define SI_STATUS_IO_BUSY   BIT(1)

#define N64_CONTROLLER_ID 0x0500

#define MAX_CONTROLLERS 4

static const char *n64joy_phys[MAX_CONTROLLERS] = {
	"n64joy/port0",
	"n64joy/port1",
	"n64joy/port2",
	"n64joy/port3",
};

struct n64joy_priv {
	u64 si_buf[8] ____cacheline_aligned;
	struct timer_list timer;
	struct mutex n64joy_mutex;
	struct input_dev *n64joy_dev[MAX_CONTROLLERS];
	u32 __iomem *reg_base;
	u8 n64joy_opened;
};

struct joydata {
	unsigned int: 16; /* unused */
	unsigned int err: 2;
	unsigned int: 14; /* unused */

	union {
		u32 data;

		struct {
			unsigned int a: 1;
			unsigned int b: 1;
			unsigned int z: 1;
			unsigned int start: 1;
			unsigned int up: 1;
			unsigned int down: 1;
			unsigned int left: 1;
			unsigned int right: 1;
			unsigned int: 2; /* unused */
			unsigned int l: 1;
			unsigned int r: 1;
			unsigned int c_up: 1;
			unsigned int c_down: 1;
			unsigned int c_left: 1;
			unsigned int c_right: 1;
			signed int x: 8;
			signed int y: 8;
		};
	};
};

static void n64joy_write_reg(u32 __iomem *reg_base, const u8 reg, const u32 value)
{
	writel(value, reg_base + reg);
}

static u32 n64joy_read_reg(u32 __iomem *reg_base, const u8 reg)
{
	return readl(reg_base + reg);
}

static void n64joy_wait_si_dma(u32 __iomem *reg_base)
{
	while (n64joy_read_reg(reg_base, SI_STATUS_REG) &
	       (SI_STATUS_DMA_BUSY | SI_STATUS_IO_BUSY))
		cpu_relax();
}

static void n64joy_exec_pif(struct n64joy_priv *priv, const u64 in[8])
{
	unsigned long flags;

	dma_cache_wback_inv((unsigned long) in, 8 * 8);
	dma_cache_inv((unsigned long) priv->si_buf, 8 * 8);

	local_irq_save(flags);

	n64joy_wait_si_dma(priv->reg_base);

	barrier();
	n64joy_write_reg(priv->reg_base, SI_DRAM_REG, virt_to_phys(in));
	barrier();
	n64joy_write_reg(priv->reg_base, SI_WRITE_REG, PIF_RAM);
	barrier();

	n64joy_wait_si_dma(priv->reg_base);

	barrier();
	n64joy_write_reg(priv->reg_base, SI_DRAM_REG, virt_to_phys(priv->si_buf));
	barrier();
	n64joy_write_reg(priv->reg_base, SI_READ_REG, PIF_RAM);
	barrier();

	n64joy_wait_si_dma(priv->reg_base);

	local_irq_restore(flags);
}

static const u64 polldata[] ____cacheline_aligned = {
	0xff010401ffffffff,
	0xff010401ffffffff,
	0xff010401ffffffff,
	0xff010401ffffffff,
	0xfe00000000000000,
	0,
	0,
	1
};

static void n64joy_poll(struct timer_list *t)
{
	const struct joydata *data;
	struct n64joy_priv *priv = container_of(t, struct n64joy_priv, timer);
	struct input_dev *dev;
	u32 i;

	n64joy_exec_pif(priv, polldata);

	data = (struct joydata *) priv->si_buf;

	for (i = 0; i < MAX_CONTROLLERS; i++) {
		if (!priv->n64joy_dev[i])
			continue;

		dev = priv->n64joy_dev[i];

		/* d-pad */
		input_report_key(dev, BTN_DPAD_UP, data[i].up);
		input_report_key(dev, BTN_DPAD_DOWN, data[i].down);
		input_report_key(dev, BTN_DPAD_LEFT, data[i].left);
		input_report_key(dev, BTN_DPAD_RIGHT, data[i].right);

		/* c buttons */
		input_report_key(dev, BTN_FORWARD, data[i].c_up);
		input_report_key(dev, BTN_BACK, data[i].c_down);
		input_report_key(dev, BTN_LEFT, data[i].c_left);
		input_report_key(dev, BTN_RIGHT, data[i].c_right);

		/* matching buttons */
		input_report_key(dev, BTN_START, data[i].start);
		input_report_key(dev, BTN_Z, data[i].z);

		/* remaining ones: a, b, l, r */
		input_report_key(dev, BTN_0, data[i].a);
		input_report_key(dev, BTN_1, data[i].b);
		input_report_key(dev, BTN_2, data[i].l);
		input_report_key(dev, BTN_3, data[i].r);

		input_report_abs(dev, ABS_X, data[i].x);
		input_report_abs(dev, ABS_Y, data[i].y);

		input_sync(dev);
	}

	mod_timer(&priv->timer, jiffies + msecs_to_jiffies(16));
}

static int n64joy_open(struct input_dev *dev)
{
	struct n64joy_priv *priv = input_get_drvdata(dev);
	int err;

	err = mutex_lock_interruptible(&priv->n64joy_mutex);
	if (err)
		return err;

	if (!priv->n64joy_opened) {
		/*
		 * We could use the vblank irq, but it's not important if
		 * the poll point slightly changes.
		 */
		timer_setup(&priv->timer, n64joy_poll, 0);
		mod_timer(&priv->timer, jiffies + msecs_to_jiffies(16));
	}

	priv->n64joy_opened++;

	mutex_unlock(&priv->n64joy_mutex);
	return err;
}

static void n64joy_close(struct input_dev *dev)
{
	struct n64joy_priv *priv = input_get_drvdata(dev);

	mutex_lock(&priv->n64joy_mutex);
	if (!--priv->n64joy_opened)
		del_timer_sync(&priv->timer);
	mutex_unlock(&priv->n64joy_mutex);
}

static const u64 __initconst scandata[] ____cacheline_aligned = {
	0xff010300ffffffff,
	0xff010300ffffffff,
	0xff010300ffffffff,
	0xff010300ffffffff,
	0xfe00000000000000,
	0,
	0,
	1
};

/*
 * The target device is embedded and RAM-constrained. We save RAM
 * by initializing in __init code that gets dropped late in boot.
 * For the same reason there is no module or unloading support.
 */
static int __init n64joy_probe(struct platform_device *pdev)
{
	const struct joydata *data;
	struct n64joy_priv *priv;
	struct input_dev *dev;
	int err = 0;
	u32 i, j, found = 0;

	priv = kzalloc(sizeof(struct n64joy_priv), GFP_KERNEL);
	if (!priv)
		return -ENOMEM;
	mutex_init(&priv->n64joy_mutex);

	priv->reg_base = devm_platform_ioremap_resource(pdev, 0);
	if (!priv->reg_base) {
		err = -EINVAL;
		goto fail;
	}

	/* The controllers are not hotpluggable, so we can scan in init */
	n64joy_exec_pif(priv, scandata);

	data = (struct joydata *) priv->si_buf;

	for (i = 0; i < MAX_CONTROLLERS; i++) {
		if (!data[i].err && data[i].data >> 16 == N64_CONTROLLER_ID) {
			found++;

			dev = priv->n64joy_dev[i] = input_allocate_device();
			if (!priv->n64joy_dev[i]) {
				err = -ENOMEM;
				goto fail;
			}

			input_set_drvdata(dev, priv);

			dev->name = "N64 controller";
			dev->phys = n64joy_phys[i];
			dev->id.bustype = BUS_HOST;
			dev->id.vendor = 0;
			dev->id.product = data[i].data >> 16;
			dev->id.version = 0;
			dev->dev.parent = &pdev->dev;

			dev->open = n64joy_open;
			dev->close = n64joy_close;

			/* d-pad */
			input_set_capability(dev, EV_KEY, BTN_DPAD_UP);
			input_set_capability(dev, EV_KEY, BTN_DPAD_DOWN);
			input_set_capability(dev, EV_KEY, BTN_DPAD_LEFT);
			input_set_capability(dev, EV_KEY, BTN_DPAD_RIGHT);
			/* c buttons */
			input_set_capability(dev, EV_KEY, BTN_LEFT);
			input_set_capability(dev, EV_KEY, BTN_RIGHT);
			input_set_capability(dev, EV_KEY, BTN_FORWARD);
			input_set_capability(dev, EV_KEY, BTN_BACK);
			/* matching buttons */
			input_set_capability(dev, EV_KEY, BTN_START);
			input_set_capability(dev, EV_KEY, BTN_Z);
			/* remaining ones: a, b, l, r */
			input_set_capability(dev, EV_KEY, BTN_0);
			input_set_capability(dev, EV_KEY, BTN_1);
			input_set_capability(dev, EV_KEY, BTN_2);
			input_set_capability(dev, EV_KEY, BTN_3);

			for (j = 0; j < 2; j++)
				input_set_abs_params(dev, ABS_X + j,
						     S8_MIN, S8_MAX, 0, 0);

			err = input_register_device(dev);
			if (err) {
				input_free_device(dev);
				goto fail;
			}
		}
	}

	pr_info("%u controller(s) connected\n", found);

	if (!found)
		return -ENODEV;

	return 0;
fail:
	for (i = 0; i < MAX_CONTROLLERS; i++) {
		if (!priv->n64joy_dev[i])
			continue;
		input_unregister_device(priv->n64joy_dev[i]);
	}
	return err;
}

static struct platform_driver n64joy_driver = {
	.driver = {
		.name = "n64joy",
	},
};

static int __init n64joy_init(void)
{
	return platform_driver_probe(&n64joy_driver, n64joy_probe);
}

module_init(n64joy_init);
