// SPDX-License-Identifier: GPL-2.0-or-later

/*
 * Infrared Toy and IR Droid RC core driver
 *
 * Copyright (C) 2020 Sean Young <sean@mess.org>

 * This driver is based on the lirc driver which can be found here:
 * https://sourceforge.net/p/lirc/git/ci/master/tree/plugins/irtoy.c
 * Copyright (C) 2011 Peter Kooiman <pkooiman@gmail.com>
 */

#include <asm/unaligned.h>
#include <linux/completion.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/usb.h>
#include <linux/slab.h>
#include <linux/usb/input.h>

#include <media/rc-core.h>

static const u8 COMMAND_VERSION[] = { 'v' };
// End transmit and repeat reset command so we exit sump mode
static const u8 COMMAND_RESET[] = { 0xff, 0xff, 0, 0, 0, 0, 0 };
static const u8 COMMAND_SMODE_ENTER[] = { 's' };
static const u8 COMMAND_SMODE_EXIT[] = { 0 };
static const u8 COMMAND_TXSTART[] = { 0x26, 0x24, 0x25, 0x03 };

#define REPLY_XMITCOUNT 't'
#define REPLY_XMITSUCCESS 'C'
#define REPLY_VERSION 'V'
#define REPLY_SAMPLEMODEPROTO 'S'

#define TIMEOUT 500

#define LEN_XMITRES 3
#define LEN_VERSION 4
#define LEN_SAMPLEMODEPROTO 3

#define MIN_FW_VERSION 20
#define UNIT_US 21
#define MAX_TIMEOUT_US (UNIT_US * U16_MAX)

#define MAX_PACKET 64

enum state {
	STATE_IRDATA,
	STATE_RESET,
	STATE_COMMAND,
	STATE_TX,
};

struct irtoy {
	struct device *dev;
	struct usb_device *usbdev;

	struct rc_dev *rc;
	struct urb *urb_in, *urb_out;

	u8 *in;
	u8 *out;
	struct completion command_done;

	bool pulse;
	enum state state;

	void *tx_buf;
	uint tx_len;

	uint emitted;
	uint hw_version;
	uint sw_version;
	uint proto_version;

	char phys[64];
};

static void irtoy_response(struct irtoy *irtoy, u32 len)
{
	switch (irtoy->state) {
	case STATE_COMMAND:
		if (len == LEN_VERSION && irtoy->in[0] == REPLY_VERSION) {
			uint version;

			irtoy->in[LEN_VERSION] = 0;

			if (kstrtouint(irtoy->in + 1, 10, &version)) {
				dev_err(irtoy->dev, "invalid version %*phN. Please make sure you are using firmware v20 or higher",
					LEN_VERSION, irtoy->in);
				break;
			}

			dev_dbg(irtoy->dev, "version %s\n", irtoy->in);

			irtoy->hw_version = version / 100;
			irtoy->sw_version = version % 100;

			irtoy->state = STATE_IRDATA;
			complete(&irtoy->command_done);
		} else if (len == LEN_SAMPLEMODEPROTO &&
			   irtoy->in[0] == REPLY_SAMPLEMODEPROTO) {
			uint version;

			irtoy->in[LEN_SAMPLEMODEPROTO] = 0;

			if (kstrtouint(irtoy->in + 1, 10, &version)) {
				dev_err(irtoy->dev, "invalid sample mode response %*phN",
					LEN_SAMPLEMODEPROTO, irtoy->in);
				return;
			}

			dev_dbg(irtoy->dev, "protocol %s\n", irtoy->in);

			irtoy->proto_version = version;

			irtoy->state = STATE_IRDATA;
			complete(&irtoy->command_done);
		} else {
			dev_err(irtoy->dev, "unexpected response to command: %*phN\n",
				len, irtoy->in);
		}
		break;
	case STATE_IRDATA: {
		struct ir_raw_event rawir = { .pulse = irtoy->pulse };
		__be16 *in = (__be16 *)irtoy->in;
		int i;

		for (i = 0; i < len / sizeof(__be16); i++) {
			u16 v = be16_to_cpu(in[i]);

			if (v == 0xffff) {
				rawir.pulse = false;
			} else {
				rawir.duration = v * UNIT_US;
				ir_raw_event_store_with_timeout(irtoy->rc,
								&rawir);
			}

			rawir.pulse = !rawir.pulse;
		}

		irtoy->pulse = rawir.pulse;

		ir_raw_event_handle(irtoy->rc);
		break;
	}
	case STATE_TX:
		if (irtoy->tx_len == 0) {
			if (len == LEN_XMITRES &&
			    irtoy->in[0] == REPLY_XMITCOUNT) {
				u16 emitted = get_unaligned_be16(irtoy->in + 1);

				dev_dbg(irtoy->dev, "emitted:%u\n", emitted);

				irtoy->emitted = emitted;
			} else if (len == 1 &&
				   irtoy->in[0] == REPLY_XMITSUCCESS) {
				irtoy->state = STATE_IRDATA;
				complete(&irtoy->command_done);
			}
		} else {
			// send next part of tx buffer
			uint space = irtoy->in[0];
			uint buf_len;
			int err;

			if (len != 1 || space > MAX_PACKET || space == 0) {
				dev_err(irtoy->dev, "packet length expected: %*phN\n",
					len, irtoy->in);
				irtoy->state = STATE_IRDATA;
				complete(&irtoy->command_done);
				break;
			}

			buf_len = min(space, irtoy->tx_len);

			dev_dbg(irtoy->dev, "remaining:%u sending:%u\n",
				irtoy->tx_len, buf_len);

			memcpy(irtoy->out, irtoy->tx_buf, buf_len);
			irtoy->urb_out->transfer_buffer_length = buf_len;
			err = usb_submit_urb(irtoy->urb_out, GFP_ATOMIC);
			if (err != 0) {
				dev_err(irtoy->dev, "fail to submit tx buf urb: %d\n",
					err);
				irtoy->state = STATE_IRDATA;
				complete(&irtoy->command_done);
				break;
			}

			irtoy->tx_buf += buf_len;
			irtoy->tx_len -= buf_len;
		}
		break;
	case STATE_RESET:
		dev_err(irtoy->dev, "unexpected response to reset: %*phN\n",
			len, irtoy->in);
	}
}

static void irtoy_out_callback(struct urb *urb)
{
	struct irtoy *irtoy = urb->context;

	if (urb->status == 0) {
		if (irtoy->state == STATE_RESET)
			complete(&irtoy->command_done);
	} else {
		dev_warn(irtoy->dev, "out urb status: %d\n", urb->status);
	}
}

static void irtoy_in_callback(struct urb *urb)
{
	struct irtoy *irtoy = urb->context;
	int ret;

	if (urb->status == 0)
		irtoy_response(irtoy, urb->actual_length);
	else
		dev_dbg(irtoy->dev, "in urb status: %d\n", urb->status);

	ret = usb_submit_urb(urb, GFP_ATOMIC);
	if (ret && ret != -ENODEV)
		dev_warn(irtoy->dev, "failed to resubmit urb: %d\n", ret);
}

static int irtoy_command(struct irtoy *irtoy, const u8 *cmd, int cmd_len,
			 enum state state)
{
	int err;

	init_completion(&irtoy->command_done);

	irtoy->state = state;

	memcpy(irtoy->out, cmd, cmd_len);
	irtoy->urb_out->transfer_buffer_length = cmd_len;

	err = usb_submit_urb(irtoy->urb_out, GFP_KERNEL);
	if (err != 0)
		return err;

	if (!wait_for_completion_timeout(&irtoy->command_done,
					 msecs_to_jiffies(TIMEOUT))) {
		usb_kill_urb(irtoy->urb_out);
		return -ETIMEDOUT;
	}

	return 0;
}

static int irtoy_setup(struct irtoy *irtoy)
{
	int err;

	err = irtoy_command(irtoy, COMMAND_RESET, sizeof(COMMAND_RESET),
			    STATE_RESET);
	if (err != 0) {
		dev_err(irtoy->dev, "could not write reset command: %d\n",
			err);
		return err;
	}

	usleep_range(50, 50);

	// get version
	err = irtoy_command(irtoy, COMMAND_VERSION, sizeof(COMMAND_VERSION),
			    STATE_COMMAND);
	if (err) {
		dev_err(irtoy->dev, "could not write version command: %d\n",
			err);
		return err;
	}

	// enter sample mode
	err = irtoy_command(irtoy, COMMAND_SMODE_ENTER,
			    sizeof(COMMAND_SMODE_ENTER), STATE_COMMAND);
	if (err)
		dev_err(irtoy->dev, "could not write sample command: %d\n",
			err);

	return err;
}

/*
 * When sending IR, it is imperative that we send the IR data as quickly
 * as possible to the device, so it does not run out of IR data and
 * introduce gaps. Allocate the buffer here, and then feed the data from
 * the urb callback handler.
 */
static int irtoy_tx(struct rc_dev *rc, uint *txbuf, uint count)
{
	struct irtoy *irtoy = rc->priv;
	unsigned int i, size;
	__be16 *buf;
	int err;

	size = sizeof(u16) * (count + 1);
	buf = kmalloc(size, GFP_KERNEL);
	if (!buf)
		return -ENOMEM;

	for (i = 0; i < count; i++) {
		u16 v = DIV_ROUND_CLOSEST(txbuf[i], UNIT_US);

		if (!v)
			v = 1;
		buf[i] = cpu_to_be16(v);
	}

	buf[count] = 0xffff;

	irtoy->tx_buf = buf;
	irtoy->tx_len = size;
	irtoy->emitted = 0;

	// There is an issue where if the unit is receiving IR while the
	// first TXSTART command is sent, the device might end up hanging
	// with its led on. It does not respond to any command when this
	// happens. To work around this, re-enter sample mode.
	err = irtoy_command(irtoy, COMMAND_SMODE_EXIT,
			    sizeof(COMMAND_SMODE_EXIT), STATE_RESET);
	if (err) {
		dev_err(irtoy->dev, "exit sample mode: %d\n", err);
		return err;
	}

	err = irtoy_command(irtoy, COMMAND_SMODE_ENTER,
			    sizeof(COMMAND_SMODE_ENTER), STATE_COMMAND);
	if (err) {
		dev_err(irtoy->dev, "enter sample mode: %d\n", err);
		return err;
	}

	err = irtoy_command(irtoy, COMMAND_TXSTART, sizeof(COMMAND_TXSTART),
			    STATE_TX);
	kfree(buf);

	if (err) {
		dev_err(irtoy->dev, "failed to send tx start command: %d\n",
			err);
		// not sure what state the device is in, reset it
		irtoy_setup(irtoy);
		return err;
	}

	if (size != irtoy->emitted) {
		dev_err(irtoy->dev, "expected %u emitted, got %u\n", size,
			irtoy->emitted);
		// not sure what state the device is in, reset it
		irtoy_setup(irtoy);
		return -EINVAL;
	}

	return count;
}

static int irtoy_probe(struct usb_interface *intf,
		       const struct usb_device_id *id)
{
	struct usb_host_interface *idesc = intf->cur_altsetting;
	struct usb_device *usbdev = interface_to_usbdev(intf);
	struct usb_endpoint_descriptor *ep_in = NULL;
	struct usb_endpoint_descriptor *ep_out = NULL;
	struct usb_endpoint_descriptor *ep = NULL;
	struct irtoy *irtoy;
	struct rc_dev *rc;
	struct urb *urb;
	int i, pipe, err = -ENOMEM;

	for (i = 0; i < idesc->desc.bNumEndpoints; i++) {
		ep = &idesc->endpoint[i].desc;

		if (!ep_in && usb_endpoint_is_bulk_in(ep) &&
		    usb_endpoint_maxp(ep) == MAX_PACKET)
			ep_in = ep;

		if (!ep_out && usb_endpoint_is_bulk_out(ep) &&
		    usb_endpoint_maxp(ep) == MAX_PACKET)
			ep_out = ep;
	}

	if (!ep_in || !ep_out) {
		dev_err(&intf->dev, "required endpoints not found\n");
		return -ENODEV;
	}

	irtoy = kzalloc(sizeof(*irtoy), GFP_KERNEL);
	if (!irtoy)
		return -ENOMEM;

	irtoy->in = kmalloc(MAX_PACKET,  GFP_KERNEL);
	if (!irtoy->in)
		goto free_irtoy;

	irtoy->out = kmalloc(MAX_PACKET,  GFP_KERNEL);
	if (!irtoy->out)
		goto free_irtoy;

	rc = rc_allocate_device(RC_DRIVER_IR_RAW);
	if (!rc)
		goto free_irtoy;

	urb = usb_alloc_urb(0, GFP_KERNEL);
	if (!urb)
		goto free_rcdev;

	pipe = usb_rcvbulkpipe(usbdev, ep_in->bEndpointAddress);
	usb_fill_bulk_urb(urb, usbdev, pipe, irtoy->in, MAX_PACKET,
			  irtoy_in_callback, irtoy);
	irtoy->urb_in = urb;

	urb = usb_alloc_urb(0, GFP_KERNEL);
	if (!urb)
		goto free_rcdev;

	pipe = usb_sndbulkpipe(usbdev, ep_out->bEndpointAddress);
	usb_fill_bulk_urb(urb, usbdev, pipe, irtoy->out, MAX_PACKET,
			  irtoy_out_callback, irtoy);

	irtoy->dev = &intf->dev;
	irtoy->usbdev = usbdev;
	irtoy->rc = rc;
	irtoy->urb_out = urb;
	irtoy->pulse = true;

	err = usb_submit_urb(irtoy->urb_in, GFP_KERNEL);
	if (err != 0) {
		dev_err(irtoy->dev, "fail to submit in urb: %d\n", err);
		goto free_rcdev;
	}

	err = irtoy_setup(irtoy);
	if (err)
		goto free_rcdev;

	dev_info(irtoy->dev, "version: hardware %u, firmware %u, protocol %u",
		 irtoy->hw_version, irtoy->sw_version, irtoy->proto_version);

	if (irtoy->sw_version < MIN_FW_VERSION) {
		dev_err(irtoy->dev, "need firmware V%02u or higher",
			MIN_FW_VERSION);
		err = -ENODEV;
		goto free_rcdev;
	}

	usb_make_path(usbdev, irtoy->phys, sizeof(irtoy->phys));

	rc->device_name = "Infrared Toy";
	rc->driver_name = KBUILD_MODNAME;
	rc->input_phys = irtoy->phys;
	usb_to_input_id(usbdev, &rc->input_id);
	rc->dev.parent = &intf->dev;
	rc->priv = irtoy;
	rc->tx_ir = irtoy_tx;
	rc->allowed_protocols = RC_PROTO_BIT_ALL_IR_DECODER;
	rc->map_name = RC_MAP_RC6_MCE;
	rc->rx_resolution = UNIT_US;
	rc->timeout = IR_DEFAULT_TIMEOUT;

	/*
	 * end of transmission is detected by absence of a usb packet
	 * with more pulse/spaces. However, each usb packet sent can
	 * contain 32 pulse/spaces, which can be quite lengthy, so there
	 * can be a delay between usb packets. For example with nec there is a
	 * 17ms gap between packets.
	 *
	 * So, make timeout a largish minimum which works with most protocols.
	 */
	rc->min_timeout = MS_TO_US(40);
	rc->max_timeout = MAX_TIMEOUT_US;

	err = rc_register_device(rc);
	if (err)
		goto free_rcdev;

	usb_set_intfdata(intf, irtoy);

	return 0;

free_rcdev:
	usb_kill_urb(irtoy->urb_out);
	usb_free_urb(irtoy->urb_out);
	usb_kill_urb(irtoy->urb_in);
	usb_free_urb(irtoy->urb_in);
	rc_free_device(rc);
free_irtoy:
	kfree(irtoy->in);
	kfree(irtoy->out);
	kfree(irtoy);
	return err;
}

static void irtoy_disconnect(struct usb_interface *intf)
{
	struct irtoy *ir = usb_get_intfdata(intf);

	rc_unregister_device(ir->rc);
	usb_set_intfdata(intf, NULL);
	usb_kill_urb(ir->urb_out);
	usb_free_urb(ir->urb_out);
	usb_kill_urb(ir->urb_in);
	usb_free_urb(ir->urb_in);
	kfree(ir->in);
	kfree(ir->out);
	kfree(ir);
}

static const struct usb_device_id irtoy_table[] = {
	{ USB_DEVICE_INTERFACE_CLASS(0x04d8, 0xfd08, USB_CLASS_CDC_DATA) },
	{ USB_DEVICE_INTERFACE_CLASS(0x04d8, 0xf58b, USB_CLASS_CDC_DATA) },
	{ }
};

static struct usb_driver irtoy_driver = {
	.name = KBUILD_MODNAME,
	.probe = irtoy_probe,
	.disconnect = irtoy_disconnect,
	.id_table = irtoy_table,
};

module_usb_driver(irtoy_driver);

MODULE_AUTHOR("Sean Young <sean@mess.org>");
MODULE_DESCRIPTION("Infrared Toy and IR Droid driver");
MODULE_LICENSE("GPL");
MODULE_DEVICE_TABLE(usb, irtoy_table);
