// SPDX-License-Identifier: GPL-2.0+
// Driver for Xbox DVD Movie Playback Kit
// Copyright (c) 2018 by Benjamin Valentin <benpicco@googlemail.com>

/*
 *  Xbox DVD Movie Playback Kit USB IR dongle support
 *
 *  The driver was derived from the ati_remote driver 2.2.1
 *          and used information from lirc_xbox.c
 *
 *          Copyright (c) 2011, 2012 Anssi Hannula <anssi.hannula@iki.fi>
 *          Copyright (c) 2004 Torrey Hoffman <thoffman@arnor.net>
 *          Copyright (c) 2002 Vladimir Dergachev
 *          Copyright (c) 2003-2004 Paul Miller <pmiller9@users.sourceforge.net>
 */

#include <linux/slab.h>
#include <linux/module.h>
#include <linux/usb/input.h>
#include <media/rc-core.h>

/*
 * Module and Version Information
 */
#define DRIVER_VERSION	"1.0.0"
#define DRIVER_AUTHOR	"Benjamin Valentin <benpicco@googlemail.com>"
#define DRIVER_DESC		"Xbox DVD USB Remote Control"

#define NAME_BUFSIZE      80    /* size of product name, path buffers */
#define DATA_BUFSIZE      8     /* size of URB data buffers */

/*
 * USB vendor ids for XBOX DVD Dongles
 */
#define VENDOR_GAMESTER     0x040b
#define VENDOR_MICROSOFT    0x045e

static const struct usb_device_id xbox_remote_table[] = {
	/* Gamester Xbox DVD Movie Playback Kit IR */
	{
		USB_DEVICE(VENDOR_GAMESTER, 0x6521),
	},
	/* Microsoft Xbox DVD Movie Playback Kit IR */
	{
		USB_DEVICE(VENDOR_MICROSOFT, 0x0284),
	},
	{}	/* Terminating entry */
};

MODULE_DEVICE_TABLE(usb, xbox_remote_table);

struct xbox_remote {
	struct rc_dev *rdev;
	struct usb_device *udev;
	struct usb_interface *interface;

	struct urb *irq_urb;
	unsigned char inbuf[DATA_BUFSIZE] __aligned(sizeof(u16));

	char rc_name[NAME_BUFSIZE];
	char rc_phys[NAME_BUFSIZE];
};

static int xbox_remote_rc_open(struct rc_dev *rdev)
{
	struct xbox_remote *xbox_remote = rdev->priv;

	/* On first open, submit the read urb which was set up previously. */
	xbox_remote->irq_urb->dev = xbox_remote->udev;
	if (usb_submit_urb(xbox_remote->irq_urb, GFP_KERNEL)) {
		dev_err(&xbox_remote->interface->dev,
			"%s: usb_submit_urb failed!\n", __func__);
		return -EIO;
	}

	return 0;
}

static void xbox_remote_rc_close(struct rc_dev *rdev)
{
	struct xbox_remote *xbox_remote = rdev->priv;

	usb_kill_urb(xbox_remote->irq_urb);
}

/*
 * xbox_remote_report_input
 */
static void xbox_remote_input_report(struct urb *urb)
{
	struct xbox_remote *xbox_remote = urb->context;
	unsigned char *data = xbox_remote->inbuf;

	/*
	 * data[0] = 0x00
	 * data[1] = length - always 0x06
	 * data[2] = the key code
	 * data[3] = high part of key code
	 * data[4] = last_press_ms (low)
	 * data[5] = last_press_ms (high)
	 */

	/* Deal with strange looking inputs */
	if (urb->actual_length != 6 || urb->actual_length != data[1]) {
		dev_warn(&urb->dev->dev, "Weird data, len=%d: %*ph\n",
			 urb->actual_length, urb->actual_length, data);
		return;
	}

	rc_keydown(xbox_remote->rdev, RC_PROTO_XBOX_DVD,
		   le16_to_cpup((__le16 *)(data + 2)), 0);
}

/*
 * xbox_remote_irq_in
 */
static void xbox_remote_irq_in(struct urb *urb)
{
	struct xbox_remote *xbox_remote = urb->context;
	int retval;

	switch (urb->status) {
	case 0:			/* success */
		xbox_remote_input_report(urb);
		break;
	case -ECONNRESET:	/* unlink */
	case -ENOENT:
	case -ESHUTDOWN:
		dev_dbg(&xbox_remote->interface->dev,
			"%s: urb error status, unlink?\n",
			__func__);
		return;
	default:		/* error */
		dev_dbg(&xbox_remote->interface->dev,
			"%s: Nonzero urb status %d\n",
			__func__, urb->status);
	}

	retval = usb_submit_urb(urb, GFP_ATOMIC);
	if (retval)
		dev_err(&xbox_remote->interface->dev,
			"%s: usb_submit_urb()=%d\n",
			__func__, retval);
}

static void xbox_remote_rc_init(struct xbox_remote *xbox_remote)
{
	struct rc_dev *rdev = xbox_remote->rdev;

	rdev->priv = xbox_remote;
	rdev->allowed_protocols = RC_PROTO_BIT_XBOX_DVD;
	rdev->driver_name = "xbox_remote";

	rdev->open = xbox_remote_rc_open;
	rdev->close = xbox_remote_rc_close;

	rdev->device_name = xbox_remote->rc_name;
	rdev->input_phys = xbox_remote->rc_phys;

	rdev->timeout = MS_TO_US(10);

	usb_to_input_id(xbox_remote->udev, &rdev->input_id);
	rdev->dev.parent = &xbox_remote->interface->dev;
}

static void xbox_remote_initialize(struct xbox_remote *xbox_remote,
				   struct usb_endpoint_descriptor *endpoint_in)
{
	struct usb_device *udev = xbox_remote->udev;
	int pipe, maxp;

	/* Set up irq_urb */
	pipe = usb_rcvintpipe(udev, endpoint_in->bEndpointAddress);
	maxp = usb_maxpacket(udev, pipe);
	maxp = (maxp > DATA_BUFSIZE) ? DATA_BUFSIZE : maxp;

	usb_fill_int_urb(xbox_remote->irq_urb, udev, pipe, xbox_remote->inbuf,
			 maxp, xbox_remote_irq_in, xbox_remote,
			 endpoint_in->bInterval);
}

/*
 * xbox_remote_probe
 */
static int xbox_remote_probe(struct usb_interface *interface,
			     const struct usb_device_id *id)
{
	struct usb_device *udev = interface_to_usbdev(interface);
	struct usb_host_interface *iface_host = interface->cur_altsetting;
	struct usb_endpoint_descriptor *endpoint_in;
	struct xbox_remote *xbox_remote;
	struct rc_dev *rc_dev;
	int err = -ENOMEM;

	// why is there also a device with no endpoints?
	if (iface_host->desc.bNumEndpoints == 0)
		return -ENODEV;

	if (iface_host->desc.bNumEndpoints != 1) {
		pr_err("%s: Unexpected desc.bNumEndpoints: %d\n",
		       __func__, iface_host->desc.bNumEndpoints);
		return -ENODEV;
	}

	endpoint_in = &iface_host->endpoint[0].desc;

	if (!usb_endpoint_is_int_in(endpoint_in)) {
		pr_err("%s: Unexpected endpoint_in\n", __func__);
		return -ENODEV;
	}
	if (le16_to_cpu(endpoint_in->wMaxPacketSize) == 0) {
		pr_err("%s: endpoint_in message size==0?\n", __func__);
		return -ENODEV;
	}

	xbox_remote = kzalloc(sizeof(*xbox_remote), GFP_KERNEL);
	rc_dev = rc_allocate_device(RC_DRIVER_SCANCODE);
	if (!xbox_remote || !rc_dev)
		goto exit_free_dev_rdev;

	/* Allocate URB buffer */
	xbox_remote->irq_urb = usb_alloc_urb(0, GFP_KERNEL);
	if (!xbox_remote->irq_urb)
		goto exit_free_buffers;

	xbox_remote->udev = udev;
	xbox_remote->rdev = rc_dev;
	xbox_remote->interface = interface;

	usb_make_path(udev, xbox_remote->rc_phys, sizeof(xbox_remote->rc_phys));

	strlcat(xbox_remote->rc_phys, "/input0", sizeof(xbox_remote->rc_phys));

	snprintf(xbox_remote->rc_name, sizeof(xbox_remote->rc_name), "%s%s%s",
		 udev->manufacturer ?: "",
		 udev->manufacturer && udev->product ? " " : "",
		 udev->product ?: "");

	if (!strlen(xbox_remote->rc_name))
		snprintf(xbox_remote->rc_name, sizeof(xbox_remote->rc_name),
			 DRIVER_DESC "(%04x,%04x)",
			 le16_to_cpu(xbox_remote->udev->descriptor.idVendor),
			 le16_to_cpu(xbox_remote->udev->descriptor.idProduct));

	rc_dev->map_name = RC_MAP_XBOX_DVD; /* default map */

	xbox_remote_rc_init(xbox_remote);

	/* Device Hardware Initialization */
	xbox_remote_initialize(xbox_remote, endpoint_in);

	/* Set up and register rc device */
	err = rc_register_device(xbox_remote->rdev);
	if (err)
		goto exit_kill_urbs;

	usb_set_intfdata(interface, xbox_remote);

	return 0;

exit_kill_urbs:
	usb_kill_urb(xbox_remote->irq_urb);
exit_free_buffers:
	usb_free_urb(xbox_remote->irq_urb);
exit_free_dev_rdev:
	rc_free_device(rc_dev);
	kfree(xbox_remote);

	return err;
}

/*
 * xbox_remote_disconnect
 */
static void xbox_remote_disconnect(struct usb_interface *interface)
{
	struct xbox_remote *xbox_remote;

	xbox_remote = usb_get_intfdata(interface);
	usb_set_intfdata(interface, NULL);
	if (!xbox_remote) {
		dev_warn(&interface->dev, "%s - null device?\n", __func__);
		return;
	}

	usb_kill_urb(xbox_remote->irq_urb);
	rc_unregister_device(xbox_remote->rdev);
	usb_free_urb(xbox_remote->irq_urb);
	kfree(xbox_remote);
}

/* usb specific object to register with the usb subsystem */
static struct usb_driver xbox_remote_driver = {
	.name         = "xbox_remote",
	.probe        = xbox_remote_probe,
	.disconnect   = xbox_remote_disconnect,
	.id_table     = xbox_remote_table,
};

module_usb_driver(xbox_remote_driver);

MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");
