// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Raspberry Pi Sense HAT joystick driver
 * http://raspberrypi.org
 *
 * Copyright (C) 2015 Raspberry Pi
 * Copyright (C) 2021 Charles Mirabile, Mwesigwa Guma, Joel Savitz
 *
 * Original Author: Serge Schneider
 * Revised for upstream Linux by: Charles Mirabile, Mwesigwa Guma, Joel Savitz
 */

#include <linux/module.h>
#include <linux/input.h>
#include <linux/i2c.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/property.h>

#define JOYSTICK_SMB_REG 0xf2

struct sensehat_joystick {
	struct platform_device *pdev;
	struct input_dev *keys_dev;
	unsigned long prev_states;
	struct regmap *regmap;
};

static const unsigned int keymap[] = {
	BTN_DPAD_DOWN, BTN_DPAD_RIGHT, BTN_DPAD_UP, BTN_SELECT, BTN_DPAD_LEFT,
};

static irqreturn_t sensehat_joystick_report(int irq, void *cookie)
{
	struct sensehat_joystick *sensehat_joystick = cookie;
	unsigned long curr_states, changes;
	unsigned int keys;
	int error;
	int i;

	error = regmap_read(sensehat_joystick->regmap, JOYSTICK_SMB_REG, &keys);
	if (error < 0) {
		dev_err(&sensehat_joystick->pdev->dev,
			"Failed to read joystick state: %d", error);
		return IRQ_NONE;
	}
	curr_states = keys;
	bitmap_xor(&changes, &curr_states, &sensehat_joystick->prev_states,
		   ARRAY_SIZE(keymap));

	for_each_set_bit(i, &changes, ARRAY_SIZE(keymap))
		input_report_key(sensehat_joystick->keys_dev, keymap[i],
				 curr_states & BIT(i));

	input_sync(sensehat_joystick->keys_dev);
	sensehat_joystick->prev_states = keys;
	return IRQ_HANDLED;
}

static int sensehat_joystick_probe(struct platform_device *pdev)
{
	struct sensehat_joystick *sensehat_joystick;
	int error, i, irq;

	sensehat_joystick = devm_kzalloc(&pdev->dev, sizeof(*sensehat_joystick),
					 GFP_KERNEL);
	if (!sensehat_joystick)
		return -ENOMEM;

	sensehat_joystick->pdev = pdev;

	sensehat_joystick->regmap = dev_get_regmap(pdev->dev.parent, NULL);
	if (!sensehat_joystick->regmap) {
		dev_err(&pdev->dev, "unable to get sensehat regmap");
		return -ENODEV;
	}

	sensehat_joystick->keys_dev = devm_input_allocate_device(&pdev->dev);
	if (!sensehat_joystick->keys_dev) {
		dev_err(&pdev->dev, "Could not allocate input device");
		return -ENOMEM;
	}

	sensehat_joystick->keys_dev->name = "Raspberry Pi Sense HAT Joystick";
	sensehat_joystick->keys_dev->phys = "sensehat-joystick/input0";
	sensehat_joystick->keys_dev->id.bustype = BUS_I2C;

	__set_bit(EV_KEY, sensehat_joystick->keys_dev->evbit);
	__set_bit(EV_REP, sensehat_joystick->keys_dev->evbit);
	for (i = 0; i < ARRAY_SIZE(keymap); i++)
		__set_bit(keymap[i], sensehat_joystick->keys_dev->keybit);

	error = input_register_device(sensehat_joystick->keys_dev);
	if (error) {
		dev_err(&pdev->dev, "Could not register input device");
		return error;
	}

	irq = platform_get_irq(pdev, 0);
	if (irq < 0)
		return irq;

	error = devm_request_threaded_irq(&pdev->dev, irq,
					  NULL, sensehat_joystick_report,
					  IRQF_ONESHOT, "keys",
					  sensehat_joystick);
	if (error) {
		dev_err(&pdev->dev, "IRQ request failed");
		return error;
	}

	return 0;
}

static const struct of_device_id sensehat_joystick_device_id[] = {
	{ .compatible = "raspberrypi,sensehat-joystick" },
	{},
};
MODULE_DEVICE_TABLE(of, sensehat_joystick_device_id);

static struct platform_driver sensehat_joystick_driver = {
	.probe = sensehat_joystick_probe,
	.driver = {
		.name = "sensehat-joystick",
		.of_match_table = sensehat_joystick_device_id,
	},
};

module_platform_driver(sensehat_joystick_driver);

MODULE_DESCRIPTION("Raspberry Pi Sense HAT joystick driver");
MODULE_AUTHOR("Charles Mirabile <cmirabil@redhat.com>");
MODULE_AUTHOR("Serge Schneider <serge@raspberrypi.org>");
MODULE_LICENSE("GPL");
