// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (C) 2021 Oleh Kravchenko <oleg@kaa.org.ua>
 *
 * SparkFun Qwiic Joystick
 * Product page:https://www.sparkfun.com/products/15168
 * Firmware and hardware sources:https://github.com/sparkfun/Qwiic_Joystick
 */

#include <linux/bits.h>
#include <linux/i2c.h>
#include <linux/input.h>
#include <linux/kernel.h>
#include <linux/module.h>

#define DRV_NAME "qwiic-joystick"

#define QWIIC_JSK_REG_VERS	1
#define QWIIC_JSK_REG_DATA	3

#define QWIIC_JSK_MAX_AXIS	GENMASK(9, 0)
#define QWIIC_JSK_FUZZ		2
#define QWIIC_JSK_FLAT		2
#define QWIIC_JSK_POLL_INTERVAL	16
#define QWIIC_JSK_POLL_MIN	8
#define QWIIC_JSK_POLL_MAX	32

struct qwiic_jsk {
	char phys[32];
	struct input_dev *dev;
	struct i2c_client *client;
};

struct qwiic_ver {
	u8 major;
	u8 minor;
};

struct qwiic_data {
	__be16 x;
	__be16 y;
	u8 thumb;
};

static void qwiic_poll(struct input_dev *input)
{
	struct qwiic_jsk *priv = input_get_drvdata(input);
	struct qwiic_data data;
	int err;

	err = i2c_smbus_read_i2c_block_data(priv->client, QWIIC_JSK_REG_DATA,
					    sizeof(data), (u8 *)&data);
	if (err != sizeof(data))
		return;

	input_report_abs(input, ABS_X, be16_to_cpu(data.x) >> 6);
	input_report_abs(input, ABS_Y, be16_to_cpu(data.y) >> 6);
	input_report_key(input, BTN_THUMBL, !data.thumb);
	input_sync(input);
}

static int qwiic_probe(struct i2c_client *client)
{
	struct qwiic_jsk *priv;
	struct qwiic_ver vers;
	int err;

	err = i2c_smbus_read_i2c_block_data(client, QWIIC_JSK_REG_VERS,
					    sizeof(vers), (u8 *)&vers);
	if (err < 0)
		return err;
	if (err != sizeof(vers))
		return -EIO;

	dev_dbg(&client->dev, "SparkFun Qwiic Joystick, FW: %u.%u\n",
		vers.major, vers.minor);

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

	priv->client = client;
	snprintf(priv->phys, sizeof(priv->phys),
		 "i2c/%s", dev_name(&client->dev));
	i2c_set_clientdata(client, priv);

	priv->dev = devm_input_allocate_device(&client->dev);
	if (!priv->dev)
		return -ENOMEM;

	priv->dev->id.bustype = BUS_I2C;
	priv->dev->name = "SparkFun Qwiic Joystick";
	priv->dev->phys = priv->phys;
	input_set_drvdata(priv->dev, priv);

	input_set_abs_params(priv->dev, ABS_X, 0, QWIIC_JSK_MAX_AXIS,
			     QWIIC_JSK_FUZZ, QWIIC_JSK_FLAT);
	input_set_abs_params(priv->dev, ABS_Y, 0, QWIIC_JSK_MAX_AXIS,
			     QWIIC_JSK_FUZZ, QWIIC_JSK_FLAT);
	input_set_capability(priv->dev, EV_KEY, BTN_THUMBL);

	err = input_setup_polling(priv->dev, qwiic_poll);
	if (err) {
		dev_err(&client->dev, "failed to set up polling: %d\n", err);
		return err;
	}
	input_set_poll_interval(priv->dev, QWIIC_JSK_POLL_INTERVAL);
	input_set_min_poll_interval(priv->dev, QWIIC_JSK_POLL_MIN);
	input_set_max_poll_interval(priv->dev, QWIIC_JSK_POLL_MAX);

	err = input_register_device(priv->dev);
	if (err) {
		dev_err(&client->dev, "failed to register joystick: %d\n", err);
		return err;
	}

	return 0;
}

#ifdef CONFIG_OF
static const struct of_device_id of_qwiic_match[] = {
	{ .compatible = "sparkfun,qwiic-joystick", },
	{ },
};
MODULE_DEVICE_TABLE(of, of_qwiic_match);
#endif /* CONFIG_OF */

static const struct i2c_device_id qwiic_id_table[] = {
	{ .name = KBUILD_MODNAME },
	{ }
};
MODULE_DEVICE_TABLE(i2c, qwiic_id_table);

static struct i2c_driver qwiic_driver = {
	.driver = {
		.name		= DRV_NAME,
		.of_match_table	= of_match_ptr(of_qwiic_match),
	},
	.id_table	= qwiic_id_table,
	.probe		= qwiic_probe,
};
module_i2c_driver(qwiic_driver);

MODULE_AUTHOR("Oleh Kravchenko <oleg@kaa.org.ua>");
MODULE_DESCRIPTION("SparkFun Qwiic Joystick driver");
MODULE_LICENSE("GPL v2");
