// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Streamzap Remote Control driver
 *
 * Copyright (c) 2005 Christoph Bartelmus <lirc@bartelmus.de>
 * Copyright (c) 2010 Jarod Wilson <jarod@wilsonet.com>
 *
 * This driver was based on the work of Greg Wickham and Adrian
 * Dewhurst. It was substantially rewritten to support correct signal
 * gaps and now maintains a delay buffer, which is used to present
 * consistent timing behaviour to user space applications. Without the
 * delay buffer an ugly hack would be required in lircd, which can
 * cause sluggish signal decoding in certain situations.
 *
 * Ported to in-kernel ir-core interface by Jarod Wilson
 *
 * This driver is based on the USB skeleton driver packaged with the
 * kernel; copyright (C) 2001-2003 Greg Kroah-Hartman (greg@kroah.com)
 */

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

#define DRIVER_VERSION	"1.61"
#define DRIVER_NAME	"streamzap"
#define DRIVER_DESC	"Streamzap Remote Control driver"

#define USB_STREAMZAP_VENDOR_ID		0x0e9c
#define USB_STREAMZAP_PRODUCT_ID	0x0000

/* table of devices that work with this driver */
static const struct usb_device_id streamzap_table[] = {
	/* Streamzap Remote Control */
	{ USB_DEVICE(USB_STREAMZAP_VENDOR_ID, USB_STREAMZAP_PRODUCT_ID) },
	/* Terminating entry */
	{ }
};

MODULE_DEVICE_TABLE(usb, streamzap_table);

#define SZ_PULSE_MASK 0xf0
#define SZ_SPACE_MASK 0x0f
#define SZ_TIMEOUT    0xff
#define SZ_RESOLUTION 256

/* number of samples buffered */
#define SZ_BUF_LEN 128

enum StreamzapDecoderState {
	PulseSpace,
	FullPulse,
	FullSpace,
	IgnorePulse
};

/* structure to hold our device specific stuff */
struct streamzap_ir {
	/* ir-core */
	struct rc_dev *rdev;

	/* core device info */
	struct device *dev;

	/* usb */
	struct usb_device	*usbdev;
	struct usb_interface	*interface;
	struct usb_endpoint_descriptor *endpoint;
	struct urb		*urb_in;

	/* buffer & dma */
	unsigned char		*buf_in;
	dma_addr_t		dma_in;
	unsigned int		buf_in_len;

	/* track what state we're in */
	enum StreamzapDecoderState decoder_state;
	/* tracks whether we are currently receiving some signal */
	bool			idle;
	/* sum of signal lengths received since signal start */
	unsigned long		sum;
	/* start time of signal; necessary for gap tracking */
	ktime_t			signal_last;
	ktime_t			signal_start;
	bool			timeout_enabled;

	char			name[128];
	char			phys[64];
};


/* local function prototypes */
static int streamzap_probe(struct usb_interface *interface,
			   const struct usb_device_id *id);
static void streamzap_disconnect(struct usb_interface *interface);
static void streamzap_callback(struct urb *urb);
static int streamzap_suspend(struct usb_interface *intf, pm_message_t message);
static int streamzap_resume(struct usb_interface *intf);

/* usb specific object needed to register this driver with the usb subsystem */
static struct usb_driver streamzap_driver = {
	.name =		DRIVER_NAME,
	.probe =	streamzap_probe,
	.disconnect =	streamzap_disconnect,
	.suspend =	streamzap_suspend,
	.resume =	streamzap_resume,
	.id_table =	streamzap_table,
};

static void sz_push(struct streamzap_ir *sz, struct ir_raw_event rawir)
{
	dev_dbg(sz->dev, "Storing %s with duration %u us\n",
		(rawir.pulse ? "pulse" : "space"), rawir.duration);
	ir_raw_event_store_with_filter(sz->rdev, &rawir);
}

static void sz_push_full_pulse(struct streamzap_ir *sz,
			       unsigned char value)
{
	struct ir_raw_event rawir = {};

	if (sz->idle) {
		int delta;

		sz->signal_last = sz->signal_start;
		sz->signal_start = ktime_get_real();

		delta = ktime_us_delta(sz->signal_start, sz->signal_last);
		rawir.pulse = false;
		if (delta > (15 * USEC_PER_SEC)) {
			/* really long time */
			rawir.duration = IR_MAX_DURATION;
		} else {
			rawir.duration = delta;
			rawir.duration -= sz->sum;
			rawir.duration = (rawir.duration > IR_MAX_DURATION) ?
					 IR_MAX_DURATION : rawir.duration;
		}
		sz_push(sz, rawir);

		sz->idle = false;
		sz->sum = 0;
	}

	rawir.pulse = true;
	rawir.duration = ((int) value) * SZ_RESOLUTION;
	rawir.duration += SZ_RESOLUTION / 2;
	sz->sum += rawir.duration;
	rawir.duration = (rawir.duration > IR_MAX_DURATION) ?
			 IR_MAX_DURATION : rawir.duration;
	sz_push(sz, rawir);
}

static void sz_push_half_pulse(struct streamzap_ir *sz,
			       unsigned char value)
{
	sz_push_full_pulse(sz, (value & SZ_PULSE_MASK) >> 4);
}

static void sz_push_full_space(struct streamzap_ir *sz,
			       unsigned char value)
{
	struct ir_raw_event rawir = {};

	rawir.pulse = false;
	rawir.duration = ((int) value) * SZ_RESOLUTION;
	rawir.duration += SZ_RESOLUTION / 2;
	sz->sum += rawir.duration;
	sz_push(sz, rawir);
}

static void sz_push_half_space(struct streamzap_ir *sz,
			       unsigned long value)
{
	sz_push_full_space(sz, value & SZ_SPACE_MASK);
}

/*
 * streamzap_callback - usb IRQ handler callback
 *
 * This procedure is invoked on reception of data from
 * the usb remote.
 */
static void streamzap_callback(struct urb *urb)
{
	struct streamzap_ir *sz;
	unsigned int i;
	int len;

	if (!urb)
		return;

	sz = urb->context;
	len = urb->actual_length;

	switch (urb->status) {
	case -ECONNRESET:
	case -ENOENT:
	case -ESHUTDOWN:
		/*
		 * this urb is terminated, clean up.
		 * sz might already be invalid at this point
		 */
		dev_err(sz->dev, "urb terminated, status: %d\n", urb->status);
		return;
	default:
		break;
	}

	dev_dbg(sz->dev, "%s: received urb, len %d\n", __func__, len);
	for (i = 0; i < len; i++) {
		dev_dbg(sz->dev, "sz->buf_in[%d]: %x\n",
			i, (unsigned char)sz->buf_in[i]);
		switch (sz->decoder_state) {
		case PulseSpace:
			if ((sz->buf_in[i] & SZ_PULSE_MASK) ==
				SZ_PULSE_MASK) {
				sz->decoder_state = FullPulse;
				continue;
			} else if ((sz->buf_in[i] & SZ_SPACE_MASK)
					== SZ_SPACE_MASK) {
				sz_push_half_pulse(sz, sz->buf_in[i]);
				sz->decoder_state = FullSpace;
				continue;
			} else {
				sz_push_half_pulse(sz, sz->buf_in[i]);
				sz_push_half_space(sz, sz->buf_in[i]);
			}
			break;
		case FullPulse:
			sz_push_full_pulse(sz, sz->buf_in[i]);
			sz->decoder_state = IgnorePulse;
			break;
		case FullSpace:
			if (sz->buf_in[i] == SZ_TIMEOUT) {
				struct ir_raw_event rawir = {
					.pulse = false,
					.duration = sz->rdev->timeout
				};
				sz->idle = true;
				if (sz->timeout_enabled)
					sz_push(sz, rawir);
				ir_raw_event_handle(sz->rdev);
				ir_raw_event_reset(sz->rdev);
			} else {
				sz_push_full_space(sz, sz->buf_in[i]);
			}
			sz->decoder_state = PulseSpace;
			break;
		case IgnorePulse:
			if ((sz->buf_in[i] & SZ_SPACE_MASK) ==
				SZ_SPACE_MASK) {
				sz->decoder_state = FullSpace;
				continue;
			}
			sz_push_half_space(sz, sz->buf_in[i]);
			sz->decoder_state = PulseSpace;
			break;
		}
	}

	ir_raw_event_handle(sz->rdev);
	usb_submit_urb(urb, GFP_ATOMIC);

	return;
}

static struct rc_dev *streamzap_init_rc_dev(struct streamzap_ir *sz)
{
	struct rc_dev *rdev;
	struct device *dev = sz->dev;
	int ret;

	rdev = rc_allocate_device(RC_DRIVER_IR_RAW);
	if (!rdev) {
		dev_err(dev, "remote dev allocation failed\n");
		goto out;
	}

	snprintf(sz->name, sizeof(sz->name), "Streamzap PC Remote Infrared Receiver (%04x:%04x)",
		 le16_to_cpu(sz->usbdev->descriptor.idVendor),
		 le16_to_cpu(sz->usbdev->descriptor.idProduct));
	usb_make_path(sz->usbdev, sz->phys, sizeof(sz->phys));
	strlcat(sz->phys, "/input0", sizeof(sz->phys));

	rdev->device_name = sz->name;
	rdev->input_phys = sz->phys;
	usb_to_input_id(sz->usbdev, &rdev->input_id);
	rdev->dev.parent = dev;
	rdev->priv = sz;
	rdev->allowed_protocols = RC_PROTO_BIT_ALL_IR_DECODER;
	rdev->driver_name = DRIVER_NAME;
	rdev->map_name = RC_MAP_STREAMZAP;

	ret = rc_register_device(rdev);
	if (ret < 0) {
		dev_err(dev, "remote input device register failed\n");
		goto out;
	}

	return rdev;

out:
	rc_free_device(rdev);
	return NULL;
}

/*
 *	streamzap_probe
 *
 *	Called by usb-core to associated with a candidate device
 *	On any failure the return value is the ERROR
 *	On success return 0
 */
static int streamzap_probe(struct usb_interface *intf,
			   const struct usb_device_id *id)
{
	struct usb_device *usbdev = interface_to_usbdev(intf);
	struct usb_host_interface *iface_host;
	struct streamzap_ir *sz = NULL;
	char buf[63], name[128] = "";
	int retval = -ENOMEM;
	int pipe, maxp;

	/* Allocate space for device driver specific data */
	sz = kzalloc(sizeof(struct streamzap_ir), GFP_KERNEL);
	if (!sz)
		return -ENOMEM;

	sz->usbdev = usbdev;
	sz->interface = intf;

	/* Check to ensure endpoint information matches requirements */
	iface_host = intf->cur_altsetting;

	if (iface_host->desc.bNumEndpoints != 1) {
		dev_err(&intf->dev, "%s: Unexpected desc.bNumEndpoints (%d)\n",
			__func__, iface_host->desc.bNumEndpoints);
		retval = -ENODEV;
		goto free_sz;
	}

	sz->endpoint = &(iface_host->endpoint[0].desc);
	if (!usb_endpoint_dir_in(sz->endpoint)) {
		dev_err(&intf->dev, "%s: endpoint doesn't match input device 02%02x\n",
			__func__, sz->endpoint->bEndpointAddress);
		retval = -ENODEV;
		goto free_sz;
	}

	if (!usb_endpoint_xfer_int(sz->endpoint)) {
		dev_err(&intf->dev, "%s: endpoint attributes don't match xfer 02%02x\n",
			__func__, sz->endpoint->bmAttributes);
		retval = -ENODEV;
		goto free_sz;
	}

	pipe = usb_rcvintpipe(usbdev, sz->endpoint->bEndpointAddress);
	maxp = usb_maxpacket(usbdev, pipe, usb_pipeout(pipe));

	if (maxp == 0) {
		dev_err(&intf->dev, "%s: endpoint Max Packet Size is 0!?!\n",
			__func__);
		retval = -ENODEV;
		goto free_sz;
	}

	/* Allocate the USB buffer and IRQ URB */
	sz->buf_in = usb_alloc_coherent(usbdev, maxp, GFP_ATOMIC, &sz->dma_in);
	if (!sz->buf_in)
		goto free_sz;

	sz->urb_in = usb_alloc_urb(0, GFP_KERNEL);
	if (!sz->urb_in)
		goto free_buf_in;

	sz->dev = &intf->dev;
	sz->buf_in_len = maxp;

	if (usbdev->descriptor.iManufacturer
	    && usb_string(usbdev, usbdev->descriptor.iManufacturer,
			  buf, sizeof(buf)) > 0)
		strscpy(name, buf, sizeof(name));

	if (usbdev->descriptor.iProduct
	    && usb_string(usbdev, usbdev->descriptor.iProduct,
			  buf, sizeof(buf)) > 0)
		snprintf(name + strlen(name), sizeof(name) - strlen(name),
			 " %s", buf);

	sz->rdev = streamzap_init_rc_dev(sz);
	if (!sz->rdev)
		goto rc_dev_fail;

	sz->idle = true;
	sz->decoder_state = PulseSpace;
	/* FIXME: don't yet have a way to set this */
	sz->timeout_enabled = true;
	sz->rdev->timeout = SZ_TIMEOUT * SZ_RESOLUTION;
	#if 0
	/* not yet supported, depends on patches from maxim */
	/* see also: LIRC_GET_REC_RESOLUTION and LIRC_SET_REC_TIMEOUT */
	sz->min_timeout = SZ_TIMEOUT * SZ_RESOLUTION;
	sz->max_timeout = SZ_TIMEOUT * SZ_RESOLUTION;
	#endif

	sz->signal_start = ktime_get_real();

	/* Complete final initialisations */
	usb_fill_int_urb(sz->urb_in, usbdev, pipe, sz->buf_in,
			 maxp, (usb_complete_t)streamzap_callback,
			 sz, sz->endpoint->bInterval);
	sz->urb_in->transfer_dma = sz->dma_in;
	sz->urb_in->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;

	usb_set_intfdata(intf, sz);

	if (usb_submit_urb(sz->urb_in, GFP_ATOMIC))
		dev_err(sz->dev, "urb submit failed\n");

	dev_info(sz->dev, "Registered %s on usb%d:%d\n", name,
		 usbdev->bus->busnum, usbdev->devnum);

	return 0;

rc_dev_fail:
	usb_free_urb(sz->urb_in);
free_buf_in:
	usb_free_coherent(usbdev, maxp, sz->buf_in, sz->dma_in);
free_sz:
	kfree(sz);

	return retval;
}

/*
 * streamzap_disconnect
 *
 * Called by the usb core when the device is removed from the system.
 *
 * This routine guarantees that the driver will not submit any more urbs
 * by clearing dev->usbdev.  It is also supposed to terminate any currently
 * active urbs.  Unfortunately, usb_bulk_msg(), used in streamzap_read(),
 * does not provide any way to do this.
 */
static void streamzap_disconnect(struct usb_interface *interface)
{
	struct streamzap_ir *sz = usb_get_intfdata(interface);
	struct usb_device *usbdev = interface_to_usbdev(interface);

	usb_set_intfdata(interface, NULL);

	if (!sz)
		return;

	sz->usbdev = NULL;
	rc_unregister_device(sz->rdev);
	usb_kill_urb(sz->urb_in);
	usb_free_urb(sz->urb_in);
	usb_free_coherent(usbdev, sz->buf_in_len, sz->buf_in, sz->dma_in);

	kfree(sz);
}

static int streamzap_suspend(struct usb_interface *intf, pm_message_t message)
{
	struct streamzap_ir *sz = usb_get_intfdata(intf);

	usb_kill_urb(sz->urb_in);

	return 0;
}

static int streamzap_resume(struct usb_interface *intf)
{
	struct streamzap_ir *sz = usb_get_intfdata(intf);

	if (usb_submit_urb(sz->urb_in, GFP_ATOMIC)) {
		dev_err(sz->dev, "Error submitting urb\n");
		return -EIO;
	}

	return 0;
}

module_usb_driver(streamzap_driver);

MODULE_AUTHOR("Jarod Wilson <jarod@wilsonet.com>");
MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");
