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

/*
 * Infrared Toy and IR Droid RC core driver
 *
 * Copyright (C) 2020 Sean Young <sean@mess.org>
 *
 * http://dangerousprototypes.com/docs/USB_IR_Toy:_Sampling_mode
 *
 * 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_COMMAND_NO_RESP,
	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_COMMAND_NO_RESP:
	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_dbg(irtoy->dev, "packet length expected: %*phN\n",
					len, irtoy->in);
				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;
	}
}

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

	if (urb->status == 0) {
		if (irtoy->state == STATE_COMMAND_NO_RESP)
			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;

	switch (urb->status) {
	case 0:
		irtoy_response(irtoy, urb->actual_length);
		break;
	case -ECONNRESET:
	case -ENOENT:
	case -ESHUTDOWN:
	case -EPROTO:
	case -EPIPE:
		usb_unlink_urb(urb);
		return;
	default:
		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_COMMAND_NO_RESP);
	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] = cpu_to_be16(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_COMMAND_NO_RESP);
	if (err) {
		dev_err(irtoy->dev, "exit sample mode: %d\n", err);
		kfree(buf);
		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);
		kfree(buf);
		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_tx_carrier(struct rc_dev *rc, uint32_t carrier)
{
	struct irtoy *irtoy = rc->priv;
	u8 buf[3];
	int err;

	if (carrier < 11800)
		return -EINVAL;

	buf[0] = 0x06;
	buf[1] = DIV_ROUND_CLOSEST(48000000, 16 * carrier) - 1;
	buf[2] = 0;

	err = irtoy_command(irtoy, buf, sizeof(buf), STATE_COMMAND_NO_RESP);
	if (err)
		dev_err(irtoy->dev, "could not write carrier command: %d\n",
			err);

	return err;
}

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.%u, protocol %u",
		 irtoy->hw_version, irtoy->sw_version / 10,
		 irtoy->sw_version % 10, 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->s_tx_carrier = irtoy_tx_carrier;
	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);
