// 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 (IS_ERR(priv->reg_base)) {
		err = PTR_ERR(priv->reg_base);
		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);
