/*
 *   imon.c:	input and display driver for SoundGraph iMON IR/VFD/LCD
 *
 *   Copyright(C) 2010  Jarod Wilson <jarod@wilsonet.com>
 *   Portions based on the original lirc_imon driver,
 *	Copyright(C) 2004  Venky Raju(dev@venky.ws)
 *
 *   Huge thanks to R. Geoff Newbury for invaluable debugging on the
 *   0xffdc iMON devices, and for sending me one to hack on, without
 *   which the support for them wouldn't be nearly as good. Thanks
 *   also to the numerous 0xffdc device owners that tested auto-config
 *   support for me and provided debug dumps from their devices.
 *
 *   imon is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation; either version 2 of the License, or
 *   (at your option) any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 */

#define pr_fmt(fmt) KBUILD_MODNAME ":%s: " fmt, __func__

#include <linux/errno.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/uaccess.h>
#include <linux/ratelimit.h>

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

#include <linux/time.h>
#include <linux/timer.h>

#define MOD_AUTHOR	"Jarod Wilson <jarod@wilsonet.com>"
#define MOD_DESC	"Driver for SoundGraph iMON MultiMedia IR/Display"
#define MOD_NAME	"imon"
#define MOD_VERSION	"0.9.4"

#define DISPLAY_MINOR_BASE	144
#define DEVICE_NAME	"lcd%d"

#define BUF_CHUNK_SIZE	8
#define BUF_SIZE	128

#define BIT_DURATION	250	/* each bit received is 250us */

#define IMON_CLOCK_ENABLE_PACKETS	2

/*** P R O T O T Y P E S ***/

/* USB Callback prototypes */
static int imon_probe(struct usb_interface *interface,
		      const struct usb_device_id *id);
static void imon_disconnect(struct usb_interface *interface);
static void usb_rx_callback_intf0(struct urb *urb);
static void usb_rx_callback_intf1(struct urb *urb);
static void usb_tx_callback(struct urb *urb);

/* suspend/resume support */
static int imon_resume(struct usb_interface *intf);
static int imon_suspend(struct usb_interface *intf, pm_message_t message);

/* Display file_operations function prototypes */
static int display_open(struct inode *inode, struct file *file);
static int display_close(struct inode *inode, struct file *file);

/* VFD write operation */
static ssize_t vfd_write(struct file *file, const char __user *buf,
			 size_t n_bytes, loff_t *pos);

/* LCD file_operations override function prototypes */
static ssize_t lcd_write(struct file *file, const char __user *buf,
			 size_t n_bytes, loff_t *pos);

/*** G L O B A L S ***/

struct imon_panel_key_table {
	u64 hw_code;
	u32 keycode;
};

struct imon_usb_dev_descr {
	__u16 flags;
#define IMON_NO_FLAGS 0
#define IMON_NEED_20MS_PKT_DELAY 1
#define IMON_IR_RAW 2
	struct imon_panel_key_table key_table[];
};

struct imon_context {
	struct device *dev;
	/* Newer devices have two interfaces */
	struct usb_device *usbdev_intf0;
	struct usb_device *usbdev_intf1;

	bool display_supported;		/* not all controllers do */
	bool display_isopen;		/* display port has been opened */
	bool rf_device;			/* true if iMON 2.4G LT/DT RF device */
	bool rf_isassociating;		/* RF remote associating */
	bool dev_present_intf0;		/* USB device presence, interface 0 */
	bool dev_present_intf1;		/* USB device presence, interface 1 */

	struct mutex lock;		/* to lock this object */
	wait_queue_head_t remove_ok;	/* For unexpected USB disconnects */

	struct usb_endpoint_descriptor *rx_endpoint_intf0;
	struct usb_endpoint_descriptor *rx_endpoint_intf1;
	struct usb_endpoint_descriptor *tx_endpoint;
	struct urb *rx_urb_intf0;
	struct urb *rx_urb_intf1;
	struct urb *tx_urb;
	bool tx_control;
	unsigned char usb_rx_buf[8];
	unsigned char usb_tx_buf[8];
	unsigned int send_packet_delay;

	struct rx_data {
		int count;		/* length of 0 or 1 sequence */
		int prev_bit;		/* logic level of sequence */
		int initial_space;	/* initial space flag */
	} rx;

	struct tx_t {
		unsigned char data_buf[35];	/* user data buffer */
		struct completion finished;	/* wait for write to finish */
		bool busy;			/* write in progress */
		int status;			/* status of tx completion */
	} tx;

	u16 vendor;			/* usb vendor ID */
	u16 product;			/* usb product ID */

	struct rc_dev *rdev;		/* rc-core device for remote */
	struct input_dev *idev;		/* input device for panel & IR mouse */
	struct input_dev *touch;	/* input device for touchscreen */

	spinlock_t kc_lock;		/* make sure we get keycodes right */
	u32 kc;				/* current input keycode */
	u32 last_keycode;		/* last reported input keycode */
	u32 rc_scancode;		/* the computed remote scancode */
	u8 rc_toggle;			/* the computed remote toggle bit */
	u64 rc_type;			/* iMON or MCE (RC6) IR protocol? */
	bool release_code;		/* some keys send a release code */

	u8 display_type;		/* store the display type */
	bool pad_mouse;			/* toggle kbd(0)/mouse(1) mode */

	char name_rdev[128];		/* rc input device name */
	char phys_rdev[64];		/* rc input device phys path */

	char name_idev[128];		/* input device name */
	char phys_idev[64];		/* input device phys path */

	char name_touch[128];		/* touch screen name */
	char phys_touch[64];		/* touch screen phys path */
	struct timer_list ttimer;	/* touch screen timer */
	int touch_x;			/* x coordinate on touchscreen */
	int touch_y;			/* y coordinate on touchscreen */
	struct imon_usb_dev_descr *dev_descr; /* device description with key
						 table for front panels */
};

#define TOUCH_TIMEOUT	(HZ/30)

/* vfd character device file operations */
static const struct file_operations vfd_fops = {
	.owner		= THIS_MODULE,
	.open		= &display_open,
	.write		= &vfd_write,
	.release	= &display_close,
	.llseek		= noop_llseek,
};

/* lcd character device file operations */
static const struct file_operations lcd_fops = {
	.owner		= THIS_MODULE,
	.open		= &display_open,
	.write		= &lcd_write,
	.release	= &display_close,
	.llseek		= noop_llseek,
};

enum {
	IMON_DISPLAY_TYPE_AUTO = 0,
	IMON_DISPLAY_TYPE_VFD  = 1,
	IMON_DISPLAY_TYPE_LCD  = 2,
	IMON_DISPLAY_TYPE_VGA  = 3,
	IMON_DISPLAY_TYPE_NONE = 4,
};

enum {
	IMON_KEY_IMON	= 0,
	IMON_KEY_MCE	= 1,
	IMON_KEY_PANEL	= 2,
};

static struct usb_class_driver imon_vfd_class = {
	.name		= DEVICE_NAME,
	.fops		= &vfd_fops,
	.minor_base	= DISPLAY_MINOR_BASE,
};

static struct usb_class_driver imon_lcd_class = {
	.name		= DEVICE_NAME,
	.fops		= &lcd_fops,
	.minor_base	= DISPLAY_MINOR_BASE,
};

/* imon receiver front panel/knob key table */
static const struct imon_usb_dev_descr imon_default_table = {
	.flags = IMON_NO_FLAGS,
	.key_table = {
		{ 0x000000000f00ffeell, KEY_MEDIA }, /* Go */
		{ 0x000000001200ffeell, KEY_UP },
		{ 0x000000001300ffeell, KEY_DOWN },
		{ 0x000000001400ffeell, KEY_LEFT },
		{ 0x000000001500ffeell, KEY_RIGHT },
		{ 0x000000001600ffeell, KEY_ENTER },
		{ 0x000000001700ffeell, KEY_ESC },
		{ 0x000000001f00ffeell, KEY_AUDIO },
		{ 0x000000002000ffeell, KEY_VIDEO },
		{ 0x000000002100ffeell, KEY_CAMERA },
		{ 0x000000002700ffeell, KEY_DVD },
		{ 0x000000002300ffeell, KEY_TV },
		{ 0x000000002b00ffeell, KEY_EXIT },
		{ 0x000000002c00ffeell, KEY_SELECT },
		{ 0x000000002d00ffeell, KEY_MENU },
		{ 0x000000000500ffeell, KEY_PREVIOUS },
		{ 0x000000000700ffeell, KEY_REWIND },
		{ 0x000000000400ffeell, KEY_STOP },
		{ 0x000000003c00ffeell, KEY_PLAYPAUSE },
		{ 0x000000000800ffeell, KEY_FASTFORWARD },
		{ 0x000000000600ffeell, KEY_NEXT },
		{ 0x000000010000ffeell, KEY_RIGHT },
		{ 0x000001000000ffeell, KEY_LEFT },
		{ 0x000000003d00ffeell, KEY_SELECT },
		{ 0x000100000000ffeell, KEY_VOLUMEUP },
		{ 0x010000000000ffeell, KEY_VOLUMEDOWN },
		{ 0x000000000100ffeell, KEY_MUTE },
		/* 0xffdc iMON MCE VFD */
		{ 0x00010000ffffffeell, KEY_VOLUMEUP },
		{ 0x01000000ffffffeell, KEY_VOLUMEDOWN },
		{ 0x00000001ffffffeell, KEY_MUTE },
		{ 0x0000000fffffffeell, KEY_MEDIA },
		{ 0x00000012ffffffeell, KEY_UP },
		{ 0x00000013ffffffeell, KEY_DOWN },
		{ 0x00000014ffffffeell, KEY_LEFT },
		{ 0x00000015ffffffeell, KEY_RIGHT },
		{ 0x00000016ffffffeell, KEY_ENTER },
		{ 0x00000017ffffffeell, KEY_ESC },
		/* iMON Knob values */
		{ 0x000100ffffffffeell, KEY_VOLUMEUP },
		{ 0x010000ffffffffeell, KEY_VOLUMEDOWN },
		{ 0x000008ffffffffeell, KEY_MUTE },
		{ 0, KEY_RESERVED },
	}
};

static const struct imon_usb_dev_descr imon_OEM_VFD = {
	.flags = IMON_NEED_20MS_PKT_DELAY,
	.key_table = {
		{ 0x000000000f00ffeell, KEY_MEDIA }, /* Go */
		{ 0x000000001200ffeell, KEY_UP },
		{ 0x000000001300ffeell, KEY_DOWN },
		{ 0x000000001400ffeell, KEY_LEFT },
		{ 0x000000001500ffeell, KEY_RIGHT },
		{ 0x000000001600ffeell, KEY_ENTER },
		{ 0x000000001700ffeell, KEY_ESC },
		{ 0x000000001f00ffeell, KEY_AUDIO },
		{ 0x000000002b00ffeell, KEY_EXIT },
		{ 0x000000002c00ffeell, KEY_SELECT },
		{ 0x000000002d00ffeell, KEY_MENU },
		{ 0x000000000500ffeell, KEY_PREVIOUS },
		{ 0x000000000700ffeell, KEY_REWIND },
		{ 0x000000000400ffeell, KEY_STOP },
		{ 0x000000003c00ffeell, KEY_PLAYPAUSE },
		{ 0x000000000800ffeell, KEY_FASTFORWARD },
		{ 0x000000000600ffeell, KEY_NEXT },
		{ 0x000000010000ffeell, KEY_RIGHT },
		{ 0x000001000000ffeell, KEY_LEFT },
		{ 0x000000003d00ffeell, KEY_SELECT },
		{ 0x000100000000ffeell, KEY_VOLUMEUP },
		{ 0x010000000000ffeell, KEY_VOLUMEDOWN },
		{ 0x000000000100ffeell, KEY_MUTE },
		/* 0xffdc iMON MCE VFD */
		{ 0x00010000ffffffeell, KEY_VOLUMEUP },
		{ 0x01000000ffffffeell, KEY_VOLUMEDOWN },
		{ 0x00000001ffffffeell, KEY_MUTE },
		{ 0x0000000fffffffeell, KEY_MEDIA },
		{ 0x00000012ffffffeell, KEY_UP },
		{ 0x00000013ffffffeell, KEY_DOWN },
		{ 0x00000014ffffffeell, KEY_LEFT },
		{ 0x00000015ffffffeell, KEY_RIGHT },
		{ 0x00000016ffffffeell, KEY_ENTER },
		{ 0x00000017ffffffeell, KEY_ESC },
		/* iMON Knob values */
		{ 0x000100ffffffffeell, KEY_VOLUMEUP },
		{ 0x010000ffffffffeell, KEY_VOLUMEDOWN },
		{ 0x000008ffffffffeell, KEY_MUTE },
		{ 0, KEY_RESERVED },
	}
};

/* imon receiver front panel/knob key table for DH102*/
static const struct imon_usb_dev_descr imon_DH102 = {
	.flags = IMON_NO_FLAGS,
	.key_table = {
		{ 0x000100000000ffeell, KEY_VOLUMEUP },
		{ 0x010000000000ffeell, KEY_VOLUMEDOWN },
		{ 0x000000010000ffeell, KEY_MUTE },
		{ 0x0000000f0000ffeell, KEY_MEDIA },
		{ 0x000000120000ffeell, KEY_UP },
		{ 0x000000130000ffeell, KEY_DOWN },
		{ 0x000000140000ffeell, KEY_LEFT },
		{ 0x000000150000ffeell, KEY_RIGHT },
		{ 0x000000160000ffeell, KEY_ENTER },
		{ 0x000000170000ffeell, KEY_ESC },
		{ 0x0000002b0000ffeell, KEY_EXIT },
		{ 0x0000002c0000ffeell, KEY_SELECT },
		{ 0x0000002d0000ffeell, KEY_MENU },
		{ 0, KEY_RESERVED }
	}
};

static const struct imon_usb_dev_descr imon_ir_raw = {
	.flags = IMON_IR_RAW,
};

/*
 * USB Device ID for iMON USB Control Boards
 *
 * The Windows drivers contain 6 different inf files, more or less one for
 * each new device until the 0x0034-0x0046 devices, which all use the same
 * driver. Some of the devices in the 34-46 range haven't been definitively
 * identified yet. Early devices have either a TriGem Computer, Inc. or a
 * Samsung vendor ID (0x0aa8 and 0x04e8 respectively), while all later
 * devices use the SoundGraph vendor ID (0x15c2). This driver only supports
 * the ffdc and later devices, which do onboard decoding.
 */
static struct usb_device_id imon_usb_id_table[] = {
	/*
	 * Several devices with this same device ID, all use iMON_PAD.inf
	 * SoundGraph iMON PAD (IR & VFD)
	 * SoundGraph iMON PAD (IR & LCD)
	 * SoundGraph iMON Knob (IR only)
	 */
	{ USB_DEVICE(0x15c2, 0xffdc),
	  .driver_info = (unsigned long)&imon_default_table },

	/*
	 * Newer devices, all driven by the latest iMON Windows driver, full
	 * list of device IDs extracted via 'strings Setup/data1.hdr |grep 15c2'
	 * Need user input to fill in details on unknown devices.
	 */
	/* SoundGraph iMON OEM Touch LCD (IR & 7" VGA LCD) */
	{ USB_DEVICE(0x15c2, 0x0034),
	  .driver_info = (unsigned long)&imon_DH102 },
	/* SoundGraph iMON OEM Touch LCD (IR & 4.3" VGA LCD) */
	{ USB_DEVICE(0x15c2, 0x0035),
	  .driver_info = (unsigned long)&imon_default_table},
	/* SoundGraph iMON OEM VFD (IR & VFD) */
	{ USB_DEVICE(0x15c2, 0x0036),
	  .driver_info = (unsigned long)&imon_OEM_VFD },
	/* device specifics unknown */
	{ USB_DEVICE(0x15c2, 0x0037),
	  .driver_info = (unsigned long)&imon_default_table},
	/* SoundGraph iMON OEM LCD (IR & LCD) */
	{ USB_DEVICE(0x15c2, 0x0038),
	  .driver_info = (unsigned long)&imon_default_table},
	/* SoundGraph iMON UltraBay (IR & LCD) */
	{ USB_DEVICE(0x15c2, 0x0039),
	  .driver_info = (unsigned long)&imon_default_table},
	/* device specifics unknown */
	{ USB_DEVICE(0x15c2, 0x003a),
	  .driver_info = (unsigned long)&imon_default_table},
	/* device specifics unknown */
	{ USB_DEVICE(0x15c2, 0x003b),
	  .driver_info = (unsigned long)&imon_default_table},
	/* SoundGraph iMON OEM Inside (IR only) */
	{ USB_DEVICE(0x15c2, 0x003c),
	  .driver_info = (unsigned long)&imon_default_table},
	/* device specifics unknown */
	{ USB_DEVICE(0x15c2, 0x003d),
	  .driver_info = (unsigned long)&imon_default_table},
	/* device specifics unknown */
	{ USB_DEVICE(0x15c2, 0x003e),
	  .driver_info = (unsigned long)&imon_default_table},
	/* device specifics unknown */
	{ USB_DEVICE(0x15c2, 0x003f),
	  .driver_info = (unsigned long)&imon_default_table},
	/* device specifics unknown */
	{ USB_DEVICE(0x15c2, 0x0040),
	  .driver_info = (unsigned long)&imon_default_table},
	/* SoundGraph iMON MINI (IR only) */
	{ USB_DEVICE(0x15c2, 0x0041),
	  .driver_info = (unsigned long)&imon_default_table},
	/* Antec Veris Multimedia Station EZ External (IR only) */
	{ USB_DEVICE(0x15c2, 0x0042),
	  .driver_info = (unsigned long)&imon_default_table},
	/* Antec Veris Multimedia Station Basic Internal (IR only) */
	{ USB_DEVICE(0x15c2, 0x0043),
	  .driver_info = (unsigned long)&imon_default_table},
	/* Antec Veris Multimedia Station Elite (IR & VFD) */
	{ USB_DEVICE(0x15c2, 0x0044),
	  .driver_info = (unsigned long)&imon_default_table},
	/* Antec Veris Multimedia Station Premiere (IR & LCD) */
	{ USB_DEVICE(0x15c2, 0x0045),
	  .driver_info = (unsigned long)&imon_default_table},
	/* device specifics unknown */
	{ USB_DEVICE(0x15c2, 0x0046),
	  .driver_info = (unsigned long)&imon_default_table},
	/* TriGem iMON (IR only) -- TG_iMON.inf */
	{ USB_DEVICE(0x0aa8, 0x8001),
	  .driver_info = (unsigned long)&imon_ir_raw},
	/* SoundGraph iMON (IR only) -- sg_imon.inf */
	{ USB_DEVICE(0x04e8, 0xff30),
	  .driver_info = (unsigned long)&imon_ir_raw},
	/* SoundGraph iMON VFD (IR & VFD) -- iMON_VFD.inf */
	{ USB_DEVICE(0x0aa8, 0xffda),
	  .driver_info = (unsigned long)&imon_ir_raw},
	/* SoundGraph iMON SS (IR & VFD) -- iMON_SS.inf */
	{ USB_DEVICE(0x15c2, 0xffda),
	  .driver_info = (unsigned long)&imon_ir_raw},
	{}
};

/* USB Device data */
static struct usb_driver imon_driver = {
	.name		= MOD_NAME,
	.probe		= imon_probe,
	.disconnect	= imon_disconnect,
	.suspend	= imon_suspend,
	.resume		= imon_resume,
	.id_table	= imon_usb_id_table,
};

/* to prevent races between open() and disconnect(), probing, etc */
static DEFINE_MUTEX(driver_lock);

/* Module bookkeeping bits */
MODULE_AUTHOR(MOD_AUTHOR);
MODULE_DESCRIPTION(MOD_DESC);
MODULE_VERSION(MOD_VERSION);
MODULE_LICENSE("GPL");
MODULE_DEVICE_TABLE(usb, imon_usb_id_table);

static bool debug;
module_param(debug, bool, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(debug, "Debug messages: 0=no, 1=yes (default: no)");

/* lcd, vfd, vga or none? should be auto-detected, but can be overridden... */
static int display_type;
module_param(display_type, int, S_IRUGO);
MODULE_PARM_DESC(display_type, "Type of attached display. 0=autodetect, 1=vfd, 2=lcd, 3=vga, 4=none (default: autodetect)");

static int pad_stabilize = 1;
module_param(pad_stabilize, int, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(pad_stabilize, "Apply stabilization algorithm to iMON PAD presses in arrow key mode. 0=disable, 1=enable (default).");

/*
 * In certain use cases, mouse mode isn't really helpful, and could actually
 * cause confusion, so allow disabling it when the IR device is open.
 */
static bool nomouse;
module_param(nomouse, bool, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(nomouse, "Disable mouse input device mode when IR device is open. 0=don't disable, 1=disable. (default: don't disable)");

/* threshold at which a pad push registers as an arrow key in kbd mode */
static int pad_thresh;
module_param(pad_thresh, int, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(pad_thresh, "Threshold at which a pad push registers as an arrow key in kbd mode (default: 28)");


static void free_imon_context(struct imon_context *ictx)
{
	struct device *dev = ictx->dev;

	usb_free_urb(ictx->tx_urb);
	usb_free_urb(ictx->rx_urb_intf0);
	usb_free_urb(ictx->rx_urb_intf1);
	kfree(ictx);

	dev_dbg(dev, "%s: iMON context freed\n", __func__);
}

/**
 * Called when the Display device (e.g. /dev/lcd0)
 * is opened by the application.
 */
static int display_open(struct inode *inode, struct file *file)
{
	struct usb_interface *interface;
	struct imon_context *ictx = NULL;
	int subminor;
	int retval = 0;

	/* prevent races with disconnect */
	mutex_lock(&driver_lock);

	subminor = iminor(inode);
	interface = usb_find_interface(&imon_driver, subminor);
	if (!interface) {
		pr_err("could not find interface for minor %d\n", subminor);
		retval = -ENODEV;
		goto exit;
	}
	ictx = usb_get_intfdata(interface);

	if (!ictx) {
		pr_err("no context found for minor %d\n", subminor);
		retval = -ENODEV;
		goto exit;
	}

	mutex_lock(&ictx->lock);

	if (!ictx->display_supported) {
		pr_err("display not supported by device\n");
		retval = -ENODEV;
	} else if (ictx->display_isopen) {
		pr_err("display port is already open\n");
		retval = -EBUSY;
	} else {
		ictx->display_isopen = true;
		file->private_data = ictx;
		dev_dbg(ictx->dev, "display port opened\n");
	}

	mutex_unlock(&ictx->lock);

exit:
	mutex_unlock(&driver_lock);
	return retval;
}

/**
 * Called when the display device (e.g. /dev/lcd0)
 * is closed by the application.
 */
static int display_close(struct inode *inode, struct file *file)
{
	struct imon_context *ictx = NULL;
	int retval = 0;

	ictx = file->private_data;

	if (!ictx) {
		pr_err("no context for device\n");
		return -ENODEV;
	}

	mutex_lock(&ictx->lock);

	if (!ictx->display_supported) {
		pr_err("display not supported by device\n");
		retval = -ENODEV;
	} else if (!ictx->display_isopen) {
		pr_err("display is not open\n");
		retval = -EIO;
	} else {
		ictx->display_isopen = false;
		dev_dbg(ictx->dev, "display port closed\n");
	}

	mutex_unlock(&ictx->lock);
	return retval;
}

/**
 * Sends a packet to the device -- this function must be called with
 * ictx->lock held, or its unlock/lock sequence while waiting for tx
 * to complete can/will lead to a deadlock.
 */
static int send_packet(struct imon_context *ictx)
{
	unsigned int pipe;
	unsigned long timeout;
	int interval = 0;
	int retval = 0;
	struct usb_ctrlrequest *control_req = NULL;

	/* Check if we need to use control or interrupt urb */
	if (!ictx->tx_control) {
		pipe = usb_sndintpipe(ictx->usbdev_intf0,
				      ictx->tx_endpoint->bEndpointAddress);
		interval = ictx->tx_endpoint->bInterval;

		usb_fill_int_urb(ictx->tx_urb, ictx->usbdev_intf0, pipe,
				 ictx->usb_tx_buf,
				 sizeof(ictx->usb_tx_buf),
				 usb_tx_callback, ictx, interval);

		ictx->tx_urb->actual_length = 0;
	} else {
		/* fill request into kmalloc'ed space: */
		control_req = kmalloc(sizeof(struct usb_ctrlrequest),
				      GFP_KERNEL);
		if (control_req == NULL)
			return -ENOMEM;

		/* setup packet is '21 09 0200 0001 0008' */
		control_req->bRequestType = 0x21;
		control_req->bRequest = 0x09;
		control_req->wValue = cpu_to_le16(0x0200);
		control_req->wIndex = cpu_to_le16(0x0001);
		control_req->wLength = cpu_to_le16(0x0008);

		/* control pipe is endpoint 0x00 */
		pipe = usb_sndctrlpipe(ictx->usbdev_intf0, 0);

		/* build the control urb */
		usb_fill_control_urb(ictx->tx_urb, ictx->usbdev_intf0,
				     pipe, (unsigned char *)control_req,
				     ictx->usb_tx_buf,
				     sizeof(ictx->usb_tx_buf),
				     usb_tx_callback, ictx);
		ictx->tx_urb->actual_length = 0;
	}

	reinit_completion(&ictx->tx.finished);
	ictx->tx.busy = true;
	smp_rmb(); /* ensure later readers know we're busy */

	retval = usb_submit_urb(ictx->tx_urb, GFP_KERNEL);
	if (retval) {
		ictx->tx.busy = false;
		smp_rmb(); /* ensure later readers know we're not busy */
		pr_err_ratelimited("error submitting urb(%d)\n", retval);
	} else {
		/* Wait for transmission to complete (or abort) */
		mutex_unlock(&ictx->lock);
		retval = wait_for_completion_interruptible(
				&ictx->tx.finished);
		if (retval) {
			usb_kill_urb(ictx->tx_urb);
			pr_err_ratelimited("task interrupted\n");
		}
		mutex_lock(&ictx->lock);

		retval = ictx->tx.status;
		if (retval)
			pr_err_ratelimited("packet tx failed (%d)\n", retval);
	}

	kfree(control_req);

	/*
	 * Induce a mandatory delay before returning, as otherwise,
	 * send_packet can get called so rapidly as to overwhelm the device,
	 * particularly on faster systems and/or those with quirky usb.
	 */
	timeout = msecs_to_jiffies(ictx->send_packet_delay);
	set_current_state(TASK_INTERRUPTIBLE);
	schedule_timeout(timeout);

	return retval;
}

/**
 * Sends an associate packet to the iMON 2.4G.
 *
 * This might not be such a good idea, since it has an id collision with
 * some versions of the "IR & VFD" combo. The only way to determine if it
 * is an RF version is to look at the product description string. (Which
 * we currently do not fetch).
 */
static int send_associate_24g(struct imon_context *ictx)
{
	int retval;
	const unsigned char packet[8] = { 0x01, 0x00, 0x00, 0x00,
					  0x00, 0x00, 0x00, 0x20 };

	if (!ictx) {
		pr_err("no context for device\n");
		return -ENODEV;
	}

	if (!ictx->dev_present_intf0) {
		pr_err("no iMON device present\n");
		return -ENODEV;
	}

	memcpy(ictx->usb_tx_buf, packet, sizeof(packet));
	retval = send_packet(ictx);

	return retval;
}

/**
 * Sends packets to setup and show clock on iMON display
 *
 * Arguments: year - last 2 digits of year, month - 1..12,
 * day - 1..31, dow - day of the week (0-Sun...6-Sat),
 * hour - 0..23, minute - 0..59, second - 0..59
 */
static int send_set_imon_clock(struct imon_context *ictx,
			       unsigned int year, unsigned int month,
			       unsigned int day, unsigned int dow,
			       unsigned int hour, unsigned int minute,
			       unsigned int second)
{
	unsigned char clock_enable_pkt[IMON_CLOCK_ENABLE_PACKETS][8];
	int retval = 0;
	int i;

	if (!ictx) {
		pr_err("no context for device\n");
		return -ENODEV;
	}

	switch (ictx->display_type) {
	case IMON_DISPLAY_TYPE_LCD:
		clock_enable_pkt[0][0] = 0x80;
		clock_enable_pkt[0][1] = year;
		clock_enable_pkt[0][2] = month-1;
		clock_enable_pkt[0][3] = day;
		clock_enable_pkt[0][4] = hour;
		clock_enable_pkt[0][5] = minute;
		clock_enable_pkt[0][6] = second;

		clock_enable_pkt[1][0] = 0x80;
		clock_enable_pkt[1][1] = 0;
		clock_enable_pkt[1][2] = 0;
		clock_enable_pkt[1][3] = 0;
		clock_enable_pkt[1][4] = 0;
		clock_enable_pkt[1][5] = 0;
		clock_enable_pkt[1][6] = 0;

		if (ictx->product == 0xffdc) {
			clock_enable_pkt[0][7] = 0x50;
			clock_enable_pkt[1][7] = 0x51;
		} else {
			clock_enable_pkt[0][7] = 0x88;
			clock_enable_pkt[1][7] = 0x8a;
		}

		break;

	case IMON_DISPLAY_TYPE_VFD:
		clock_enable_pkt[0][0] = year;
		clock_enable_pkt[0][1] = month-1;
		clock_enable_pkt[0][2] = day;
		clock_enable_pkt[0][3] = dow;
		clock_enable_pkt[0][4] = hour;
		clock_enable_pkt[0][5] = minute;
		clock_enable_pkt[0][6] = second;
		clock_enable_pkt[0][7] = 0x40;

		clock_enable_pkt[1][0] = 0;
		clock_enable_pkt[1][1] = 0;
		clock_enable_pkt[1][2] = 1;
		clock_enable_pkt[1][3] = 0;
		clock_enable_pkt[1][4] = 0;
		clock_enable_pkt[1][5] = 0;
		clock_enable_pkt[1][6] = 0;
		clock_enable_pkt[1][7] = 0x42;

		break;

	default:
		return -ENODEV;
	}

	for (i = 0; i < IMON_CLOCK_ENABLE_PACKETS; i++) {
		memcpy(ictx->usb_tx_buf, clock_enable_pkt[i], 8);
		retval = send_packet(ictx);
		if (retval) {
			pr_err("send_packet failed for packet %d\n", i);
			break;
		}
	}

	return retval;
}

/**
 * These are the sysfs functions to handle the association on the iMON 2.4G LT.
 */
static ssize_t show_associate_remote(struct device *d,
				     struct device_attribute *attr,
				     char *buf)
{
	struct imon_context *ictx = dev_get_drvdata(d);

	if (!ictx)
		return -ENODEV;

	mutex_lock(&ictx->lock);
	if (ictx->rf_isassociating)
		strcpy(buf, "associating\n");
	else
		strcpy(buf, "closed\n");

	dev_info(d, "Visit http://www.lirc.org/html/imon-24g.html for instructions on how to associate your iMON 2.4G DT/LT remote\n");
	mutex_unlock(&ictx->lock);
	return strlen(buf);
}

static ssize_t store_associate_remote(struct device *d,
				      struct device_attribute *attr,
				      const char *buf, size_t count)
{
	struct imon_context *ictx;

	ictx = dev_get_drvdata(d);

	if (!ictx)
		return -ENODEV;

	mutex_lock(&ictx->lock);
	ictx->rf_isassociating = true;
	send_associate_24g(ictx);
	mutex_unlock(&ictx->lock);

	return count;
}

/**
 * sysfs functions to control internal imon clock
 */
static ssize_t show_imon_clock(struct device *d,
			       struct device_attribute *attr, char *buf)
{
	struct imon_context *ictx = dev_get_drvdata(d);
	size_t len;

	if (!ictx)
		return -ENODEV;

	mutex_lock(&ictx->lock);

	if (!ictx->display_supported) {
		len = snprintf(buf, PAGE_SIZE, "Not supported.");
	} else {
		len = snprintf(buf, PAGE_SIZE,
			"To set the clock on your iMON display:\n"
			"# date \"+%%y %%m %%d %%w %%H %%M %%S\" > imon_clock\n"
			"%s", ictx->display_isopen ?
			"\nNOTE: imon device must be closed\n" : "");
	}

	mutex_unlock(&ictx->lock);

	return len;
}

static ssize_t store_imon_clock(struct device *d,
				struct device_attribute *attr,
				const char *buf, size_t count)
{
	struct imon_context *ictx = dev_get_drvdata(d);
	ssize_t retval;
	unsigned int year, month, day, dow, hour, minute, second;

	if (!ictx)
		return -ENODEV;

	mutex_lock(&ictx->lock);

	if (!ictx->display_supported) {
		retval = -ENODEV;
		goto exit;
	} else if (ictx->display_isopen) {
		retval = -EBUSY;
		goto exit;
	}

	if (sscanf(buf, "%u %u %u %u %u %u %u",	&year, &month, &day, &dow,
		   &hour, &minute, &second) != 7) {
		retval = -EINVAL;
		goto exit;
	}

	if ((month < 1 || month > 12) ||
	    (day < 1 || day > 31) || (dow > 6) ||
	    (hour > 23) || (minute > 59) || (second > 59)) {
		retval = -EINVAL;
		goto exit;
	}

	retval = send_set_imon_clock(ictx, year, month, day, dow,
				     hour, minute, second);
	if (retval)
		goto exit;

	retval = count;
exit:
	mutex_unlock(&ictx->lock);

	return retval;
}


static DEVICE_ATTR(imon_clock, S_IWUSR | S_IRUGO, show_imon_clock,
		   store_imon_clock);

static DEVICE_ATTR(associate_remote, S_IWUSR | S_IRUGO, show_associate_remote,
		   store_associate_remote);

static struct attribute *imon_display_sysfs_entries[] = {
	&dev_attr_imon_clock.attr,
	NULL
};

static struct attribute_group imon_display_attr_group = {
	.attrs = imon_display_sysfs_entries
};

static struct attribute *imon_rf_sysfs_entries[] = {
	&dev_attr_associate_remote.attr,
	NULL
};

static struct attribute_group imon_rf_attr_group = {
	.attrs = imon_rf_sysfs_entries
};

/**
 * Writes data to the VFD.  The iMON VFD is 2x16 characters
 * and requires data in 5 consecutive USB interrupt packets,
 * each packet but the last carrying 7 bytes.
 *
 * I don't know if the VFD board supports features such as
 * scrolling, clearing rows, blanking, etc. so at
 * the caller must provide a full screen of data.  If fewer
 * than 32 bytes are provided spaces will be appended to
 * generate a full screen.
 */
static ssize_t vfd_write(struct file *file, const char __user *buf,
			 size_t n_bytes, loff_t *pos)
{
	int i;
	int offset;
	int seq;
	int retval = 0;
	struct imon_context *ictx;
	const unsigned char vfd_packet6[] = {
		0x01, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF };

	ictx = file->private_data;
	if (!ictx) {
		pr_err_ratelimited("no context for device\n");
		return -ENODEV;
	}

	mutex_lock(&ictx->lock);

	if (!ictx->dev_present_intf0) {
		pr_err_ratelimited("no iMON device present\n");
		retval = -ENODEV;
		goto exit;
	}

	if (n_bytes <= 0 || n_bytes > 32) {
		pr_err_ratelimited("invalid payload size\n");
		retval = -EINVAL;
		goto exit;
	}

	if (copy_from_user(ictx->tx.data_buf, buf, n_bytes)) {
		retval = -EFAULT;
		goto exit;
	}

	/* Pad with spaces */
	for (i = n_bytes; i < 32; ++i)
		ictx->tx.data_buf[i] = ' ';

	for (i = 32; i < 35; ++i)
		ictx->tx.data_buf[i] = 0xFF;

	offset = 0;
	seq = 0;

	do {
		memcpy(ictx->usb_tx_buf, ictx->tx.data_buf + offset, 7);
		ictx->usb_tx_buf[7] = (unsigned char) seq;

		retval = send_packet(ictx);
		if (retval) {
			pr_err_ratelimited("send packet #%d failed\n", seq / 2);
			goto exit;
		} else {
			seq += 2;
			offset += 7;
		}

	} while (offset < 35);

	/* Send packet #6 */
	memcpy(ictx->usb_tx_buf, &vfd_packet6, sizeof(vfd_packet6));
	ictx->usb_tx_buf[7] = (unsigned char) seq;
	retval = send_packet(ictx);
	if (retval)
		pr_err_ratelimited("send packet #%d failed\n", seq / 2);

exit:
	mutex_unlock(&ictx->lock);

	return (!retval) ? n_bytes : retval;
}

/**
 * Writes data to the LCD.  The iMON OEM LCD screen expects 8-byte
 * packets. We accept data as 16 hexadecimal digits, followed by a
 * newline (to make it easy to drive the device from a command-line
 * -- even though the actual binary data is a bit complicated).
 *
 * The device itself is not a "traditional" text-mode display. It's
 * actually a 16x96 pixel bitmap display. That means if you want to
 * display text, you've got to have your own "font" and translate the
 * text into bitmaps for display. This is really flexible (you can
 * display whatever diacritics you need, and so on), but it's also
 * a lot more complicated than most LCDs...
 */
static ssize_t lcd_write(struct file *file, const char __user *buf,
			 size_t n_bytes, loff_t *pos)
{
	int retval = 0;
	struct imon_context *ictx;

	ictx = file->private_data;
	if (!ictx) {
		pr_err_ratelimited("no context for device\n");
		return -ENODEV;
	}

	mutex_lock(&ictx->lock);

	if (!ictx->display_supported) {
		pr_err_ratelimited("no iMON display present\n");
		retval = -ENODEV;
		goto exit;
	}

	if (n_bytes != 8) {
		pr_err_ratelimited("invalid payload size: %d (expected 8)\n",
				   (int)n_bytes);
		retval = -EINVAL;
		goto exit;
	}

	if (copy_from_user(ictx->usb_tx_buf, buf, 8)) {
		retval = -EFAULT;
		goto exit;
	}

	retval = send_packet(ictx);
	if (retval) {
		pr_err_ratelimited("send packet failed!\n");
		goto exit;
	} else {
		dev_dbg(ictx->dev, "%s: write %d bytes to LCD\n",
			__func__, (int) n_bytes);
	}
exit:
	mutex_unlock(&ictx->lock);
	return (!retval) ? n_bytes : retval;
}

/**
 * Callback function for USB core API: transmit data
 */
static void usb_tx_callback(struct urb *urb)
{
	struct imon_context *ictx;

	if (!urb)
		return;
	ictx = (struct imon_context *)urb->context;
	if (!ictx)
		return;

	ictx->tx.status = urb->status;

	/* notify waiters that write has finished */
	ictx->tx.busy = false;
	smp_rmb(); /* ensure later readers know we're not busy */
	complete(&ictx->tx.finished);
}

/**
 * report touchscreen input
 */
static void imon_touch_display_timeout(unsigned long data)
{
	struct imon_context *ictx = (struct imon_context *)data;

	if (ictx->display_type != IMON_DISPLAY_TYPE_VGA)
		return;

	input_report_abs(ictx->touch, ABS_X, ictx->touch_x);
	input_report_abs(ictx->touch, ABS_Y, ictx->touch_y);
	input_report_key(ictx->touch, BTN_TOUCH, 0x00);
	input_sync(ictx->touch);
}

/**
 * iMON IR receivers support two different signal sets -- those used by
 * the iMON remotes, and those used by the Windows MCE remotes (which is
 * really just RC-6), but only one or the other at a time, as the signals
 * are decoded onboard the receiver.
 *
 * This function gets called two different ways, one way is from
 * rc_register_device, for initial protocol selection/setup, and the other is
 * via a userspace-initiated protocol change request, either by direct sysfs
 * prodding or by something like ir-keytable. In the rc_register_device case,
 * the imon context lock is already held, but when initiated from userspace,
 * it is not, so we must acquire it prior to calling send_packet, which
 * requires that the lock is held.
 */
static int imon_ir_change_protocol(struct rc_dev *rc, u64 *rc_type)
{
	int retval;
	struct imon_context *ictx = rc->priv;
	struct device *dev = ictx->dev;
	bool unlock = false;
	unsigned char ir_proto_packet[] = {
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86 };

	if (*rc_type && !(*rc_type & rc->allowed_protocols))
		dev_warn(dev, "Looks like you're trying to use an IR protocol this device does not support\n");

	if (*rc_type & RC_BIT_RC6_MCE) {
		dev_dbg(dev, "Configuring IR receiver for MCE protocol\n");
		ir_proto_packet[0] = 0x01;
		*rc_type = RC_BIT_RC6_MCE;
	} else if (*rc_type & RC_BIT_OTHER) {
		dev_dbg(dev, "Configuring IR receiver for iMON protocol\n");
		if (!pad_stabilize)
			dev_dbg(dev, "PAD stabilize functionality disabled\n");
		/* ir_proto_packet[0] = 0x00; // already the default */
		*rc_type = RC_BIT_OTHER;
	} else {
		dev_warn(dev, "Unsupported IR protocol specified, overriding to iMON IR protocol\n");
		if (!pad_stabilize)
			dev_dbg(dev, "PAD stabilize functionality disabled\n");
		/* ir_proto_packet[0] = 0x00; // already the default */
		*rc_type = RC_BIT_OTHER;
	}

	memcpy(ictx->usb_tx_buf, &ir_proto_packet, sizeof(ir_proto_packet));

	if (!mutex_is_locked(&ictx->lock)) {
		unlock = true;
		mutex_lock(&ictx->lock);
	}

	retval = send_packet(ictx);
	if (retval)
		goto out;

	ictx->rc_type = *rc_type;
	ictx->pad_mouse = false;

out:
	if (unlock)
		mutex_unlock(&ictx->lock);

	return retval;
}

static inline int tv2int(const struct timeval *a, const struct timeval *b)
{
	int usecs = 0;
	int sec   = 0;

	if (b->tv_usec > a->tv_usec) {
		usecs = 1000000;
		sec--;
	}

	usecs += a->tv_usec - b->tv_usec;

	sec += a->tv_sec - b->tv_sec;
	sec *= 1000;
	usecs /= 1000;
	sec += usecs;

	if (sec < 0)
		sec = 1000;

	return sec;
}

/**
 * The directional pad behaves a bit differently, depending on whether this is
 * one of the older ffdc devices or a newer device. Newer devices appear to
 * have a higher resolution matrix for more precise mouse movement, but it
 * makes things overly sensitive in keyboard mode, so we do some interesting
 * contortions to make it less touchy. Older devices run through the same
 * routine with shorter timeout and a smaller threshold.
 */
static int stabilize(int a, int b, u16 timeout, u16 threshold)
{
	struct timeval ct;
	static struct timeval prev_time = {0, 0};
	static struct timeval hit_time  = {0, 0};
	static int x, y, prev_result, hits;
	int result = 0;
	int msec, msec_hit;

	do_gettimeofday(&ct);
	msec = tv2int(&ct, &prev_time);
	msec_hit = tv2int(&ct, &hit_time);

	if (msec > 100) {
		x = 0;
		y = 0;
		hits = 0;
	}

	x += a;
	y += b;

	prev_time = ct;

	if (abs(x) > threshold || abs(y) > threshold) {
		if (abs(y) > abs(x))
			result = (y > 0) ? 0x7F : 0x80;
		else
			result = (x > 0) ? 0x7F00 : 0x8000;

		x = 0;
		y = 0;

		if (result == prev_result) {
			hits++;

			if (hits > 3) {
				switch (result) {
				case 0x7F:
					y = 17 * threshold / 30;
					break;
				case 0x80:
					y -= 17 * threshold / 30;
					break;
				case 0x7F00:
					x = 17 * threshold / 30;
					break;
				case 0x8000:
					x -= 17 * threshold / 30;
					break;
				}
			}

			if (hits == 2 && msec_hit < timeout) {
				result = 0;
				hits = 1;
			}
		} else {
			prev_result = result;
			hits = 1;
			hit_time = ct;
		}
	}

	return result;
}

static u32 imon_remote_key_lookup(struct imon_context *ictx, u32 scancode)
{
	u32 keycode;
	u32 release;
	bool is_release_code = false;

	/* Look for the initial press of a button */
	keycode = rc_g_keycode_from_table(ictx->rdev, scancode);
	ictx->rc_toggle = 0x0;
	ictx->rc_scancode = scancode;

	/* Look for the release of a button */
	if (keycode == KEY_RESERVED) {
		release = scancode & ~0x4000;
		keycode = rc_g_keycode_from_table(ictx->rdev, release);
		if (keycode != KEY_RESERVED)
			is_release_code = true;
	}

	ictx->release_code = is_release_code;

	return keycode;
}

static u32 imon_mce_key_lookup(struct imon_context *ictx, u32 scancode)
{
	u32 keycode;

#define MCE_KEY_MASK 0x7000
#define MCE_TOGGLE_BIT 0x8000

	/*
	 * On some receivers, mce keys decode to 0x8000f04xx and 0x8000f84xx
	 * (the toggle bit flipping between alternating key presses), while
	 * on other receivers, we see 0x8000f74xx and 0x8000ff4xx. To keep
	 * the table trim, we always or in the bits to look up 0x8000ff4xx,
	 * but we can't or them into all codes, as some keys are decoded in
	 * a different way w/o the same use of the toggle bit...
	 */
	if (scancode & 0x80000000)
		scancode = scancode | MCE_KEY_MASK | MCE_TOGGLE_BIT;

	ictx->rc_scancode = scancode;
	keycode = rc_g_keycode_from_table(ictx->rdev, scancode);

	/* not used in mce mode, but make sure we know its false */
	ictx->release_code = false;

	return keycode;
}

static u32 imon_panel_key_lookup(struct imon_context *ictx, u64 code)
{
	int i;
	u32 keycode = KEY_RESERVED;
	struct imon_panel_key_table *key_table = ictx->dev_descr->key_table;

	for (i = 0; key_table[i].hw_code != 0; i++) {
		if (key_table[i].hw_code == (code | 0xffee)) {
			keycode = key_table[i].keycode;
			break;
		}
	}
	ictx->release_code = false;
	return keycode;
}

static bool imon_mouse_event(struct imon_context *ictx,
			     unsigned char *buf, int len)
{
	signed char rel_x = 0x00, rel_y = 0x00;
	u8 right_shift = 1;
	bool mouse_input = true;
	int dir = 0;
	unsigned long flags;

	spin_lock_irqsave(&ictx->kc_lock, flags);

	/* newer iMON device PAD or mouse button */
	if (ictx->product != 0xffdc && (buf[0] & 0x01) && len == 5) {
		rel_x = buf[2];
		rel_y = buf[3];
		right_shift = 1;
	/* 0xffdc iMON PAD or mouse button input */
	} else if (ictx->product == 0xffdc && (buf[0] & 0x40) &&
			!((buf[1] & 0x01) || ((buf[1] >> 2) & 0x01))) {
		rel_x = (buf[1] & 0x08) | (buf[1] & 0x10) >> 2 |
			(buf[1] & 0x20) >> 4 | (buf[1] & 0x40) >> 6;
		if (buf[0] & 0x02)
			rel_x |= ~0x0f;
		rel_x = rel_x + rel_x / 2;
		rel_y = (buf[2] & 0x08) | (buf[2] & 0x10) >> 2 |
			(buf[2] & 0x20) >> 4 | (buf[2] & 0x40) >> 6;
		if (buf[0] & 0x01)
			rel_y |= ~0x0f;
		rel_y = rel_y + rel_y / 2;
		right_shift = 2;
	/* some ffdc devices decode mouse buttons differently... */
	} else if (ictx->product == 0xffdc && (buf[0] == 0x68)) {
		right_shift = 2;
	/* ch+/- buttons, which we use for an emulated scroll wheel */
	} else if (ictx->kc == KEY_CHANNELUP && (buf[2] & 0x40) != 0x40) {
		dir = 1;
	} else if (ictx->kc == KEY_CHANNELDOWN && (buf[2] & 0x40) != 0x40) {
		dir = -1;
	} else
		mouse_input = false;

	spin_unlock_irqrestore(&ictx->kc_lock, flags);

	if (mouse_input) {
		dev_dbg(ictx->dev, "sending mouse data via input subsystem\n");

		if (dir) {
			input_report_rel(ictx->idev, REL_WHEEL, dir);
		} else if (rel_x || rel_y) {
			input_report_rel(ictx->idev, REL_X, rel_x);
			input_report_rel(ictx->idev, REL_Y, rel_y);
		} else {
			input_report_key(ictx->idev, BTN_LEFT, buf[1] & 0x1);
			input_report_key(ictx->idev, BTN_RIGHT,
					 buf[1] >> right_shift & 0x1);
		}
		input_sync(ictx->idev);
		spin_lock_irqsave(&ictx->kc_lock, flags);
		ictx->last_keycode = ictx->kc;
		spin_unlock_irqrestore(&ictx->kc_lock, flags);
	}

	return mouse_input;
}

static void imon_touch_event(struct imon_context *ictx, unsigned char *buf)
{
	mod_timer(&ictx->ttimer, jiffies + TOUCH_TIMEOUT);
	ictx->touch_x = (buf[0] << 4) | (buf[1] >> 4);
	ictx->touch_y = 0xfff - ((buf[2] << 4) | (buf[1] & 0xf));
	input_report_abs(ictx->touch, ABS_X, ictx->touch_x);
	input_report_abs(ictx->touch, ABS_Y, ictx->touch_y);
	input_report_key(ictx->touch, BTN_TOUCH, 0x01);
	input_sync(ictx->touch);
}

static void imon_pad_to_keys(struct imon_context *ictx, unsigned char *buf)
{
	int dir = 0;
	signed char rel_x = 0x00, rel_y = 0x00;
	u16 timeout, threshold;
	u32 scancode = KEY_RESERVED;
	unsigned long flags;

	/*
	 * The imon directional pad functions more like a touchpad. Bytes 3 & 4
	 * contain a position coordinate (x,y), with each component ranging
	 * from -14 to 14. We want to down-sample this to only 4 discrete values
	 * for up/down/left/right arrow keys. Also, when you get too close to
	 * diagonals, it has a tendency to jump back and forth, so lets try to
	 * ignore when they get too close.
	 */
	if (ictx->product != 0xffdc) {
		/* first, pad to 8 bytes so it conforms with everything else */
		buf[5] = buf[6] = buf[7] = 0;
		timeout = 500;	/* in msecs */
		/* (2*threshold) x (2*threshold) square */
		threshold = pad_thresh ? pad_thresh : 28;
		rel_x = buf[2];
		rel_y = buf[3];

		if (ictx->rc_type == RC_BIT_OTHER && pad_stabilize) {
			if ((buf[1] == 0) && ((rel_x != 0) || (rel_y != 0))) {
				dir = stabilize((int)rel_x, (int)rel_y,
						timeout, threshold);
				if (!dir) {
					spin_lock_irqsave(&ictx->kc_lock,
							  flags);
					ictx->kc = KEY_UNKNOWN;
					spin_unlock_irqrestore(&ictx->kc_lock,
							       flags);
					return;
				}
				buf[2] = dir & 0xFF;
				buf[3] = (dir >> 8) & 0xFF;
				scancode = be32_to_cpu(*((__be32 *)buf));
			}
		} else {
			/*
			 * Hack alert: instead of using keycodes, we have
			 * to use hard-coded scancodes here...
			 */
			if (abs(rel_y) > abs(rel_x)) {
				buf[2] = (rel_y > 0) ? 0x7F : 0x80;
				buf[3] = 0;
				if (rel_y > 0)
					scancode = 0x01007f00; /* KEY_DOWN */
				else
					scancode = 0x01008000; /* KEY_UP */
			} else {
				buf[2] = 0;
				buf[3] = (rel_x > 0) ? 0x7F : 0x80;
				if (rel_x > 0)
					scancode = 0x0100007f; /* KEY_RIGHT */
				else
					scancode = 0x01000080; /* KEY_LEFT */
			}
		}

	/*
	 * Handle on-board decoded pad events for e.g. older VFD/iMON-Pad
	 * device (15c2:ffdc). The remote generates various codes from
	 * 0x68nnnnB7 to 0x6AnnnnB7, the left mouse button generates
	 * 0x688301b7 and the right one 0x688481b7. All other keys generate
	 * 0x2nnnnnnn. Position coordinate is encoded in buf[1] and buf[2] with
	 * reversed endianness. Extract direction from buffer, rotate endianness,
	 * adjust sign and feed the values into stabilize(). The resulting codes
	 * will be 0x01008000, 0x01007F00, which match the newer devices.
	 */
	} else {
		timeout = 10;	/* in msecs */
		/* (2*threshold) x (2*threshold) square */
		threshold = pad_thresh ? pad_thresh : 15;

		/* buf[1] is x */
		rel_x = (buf[1] & 0x08) | (buf[1] & 0x10) >> 2 |
			(buf[1] & 0x20) >> 4 | (buf[1] & 0x40) >> 6;
		if (buf[0] & 0x02)
			rel_x |= ~0x10+1;
		/* buf[2] is y */
		rel_y = (buf[2] & 0x08) | (buf[2] & 0x10) >> 2 |
			(buf[2] & 0x20) >> 4 | (buf[2] & 0x40) >> 6;
		if (buf[0] & 0x01)
			rel_y |= ~0x10+1;

		buf[0] = 0x01;
		buf[1] = buf[4] = buf[5] = buf[6] = buf[7] = 0;

		if (ictx->rc_type == RC_BIT_OTHER && pad_stabilize) {
			dir = stabilize((int)rel_x, (int)rel_y,
					timeout, threshold);
			if (!dir) {
				spin_lock_irqsave(&ictx->kc_lock, flags);
				ictx->kc = KEY_UNKNOWN;
				spin_unlock_irqrestore(&ictx->kc_lock, flags);
				return;
			}
			buf[2] = dir & 0xFF;
			buf[3] = (dir >> 8) & 0xFF;
			scancode = be32_to_cpu(*((__be32 *)buf));
		} else {
			/*
			 * Hack alert: instead of using keycodes, we have
			 * to use hard-coded scancodes here...
			 */
			if (abs(rel_y) > abs(rel_x)) {
				buf[2] = (rel_y > 0) ? 0x7F : 0x80;
				buf[3] = 0;
				if (rel_y > 0)
					scancode = 0x01007f00; /* KEY_DOWN */
				else
					scancode = 0x01008000; /* KEY_UP */
			} else {
				buf[2] = 0;
				buf[3] = (rel_x > 0) ? 0x7F : 0x80;
				if (rel_x > 0)
					scancode = 0x0100007f; /* KEY_RIGHT */
				else
					scancode = 0x01000080; /* KEY_LEFT */
			}
		}
	}

	if (scancode) {
		spin_lock_irqsave(&ictx->kc_lock, flags);
		ictx->kc = imon_remote_key_lookup(ictx, scancode);
		spin_unlock_irqrestore(&ictx->kc_lock, flags);
	}
}

/**
 * figure out if these is a press or a release. We don't actually
 * care about repeats, as those will be auto-generated within the IR
 * subsystem for repeating scancodes.
 */
static int imon_parse_press_type(struct imon_context *ictx,
				 unsigned char *buf, u8 ktype)
{
	int press_type = 0;
	unsigned long flags;

	spin_lock_irqsave(&ictx->kc_lock, flags);

	/* key release of 0x02XXXXXX key */
	if (ictx->kc == KEY_RESERVED && buf[0] == 0x02 && buf[3] == 0x00)
		ictx->kc = ictx->last_keycode;

	/* mouse button release on (some) 0xffdc devices */
	else if (ictx->kc == KEY_RESERVED && buf[0] == 0x68 && buf[1] == 0x82 &&
		 buf[2] == 0x81 && buf[3] == 0xb7)
		ictx->kc = ictx->last_keycode;

	/* mouse button release on (some other) 0xffdc devices */
	else if (ictx->kc == KEY_RESERVED && buf[0] == 0x01 && buf[1] == 0x00 &&
		 buf[2] == 0x81 && buf[3] == 0xb7)
		ictx->kc = ictx->last_keycode;

	/* mce-specific button handling, no keyup events */
	else if (ktype == IMON_KEY_MCE) {
		ictx->rc_toggle = buf[2];
		press_type = 1;

	/* incoherent or irrelevant data */
	} else if (ictx->kc == KEY_RESERVED)
		press_type = -EINVAL;

	/* key release of 0xXXXXXXb7 key */
	else if (ictx->release_code)
		press_type = 0;

	/* this is a button press */
	else
		press_type = 1;

	spin_unlock_irqrestore(&ictx->kc_lock, flags);

	return press_type;
}

/**
 * Process the incoming packet
 */
/**
 * Convert bit count to time duration (in us) and submit
 * the value to lirc_dev.
 */
static void submit_data(struct imon_context *context)
{
	DEFINE_IR_RAW_EVENT(ev);

	ev.pulse = context->rx.prev_bit;
	ev.duration = US_TO_NS(context->rx.count * BIT_DURATION);
	ir_raw_event_store_with_filter(context->rdev, &ev);
}

/**
 * Process the incoming packet
 */
static void imon_incoming_ir_raw(struct imon_context *context,
				 struct urb *urb, int intf)
{
	int len = urb->actual_length;
	unsigned char *buf = urb->transfer_buffer;
	struct device *dev = context->dev;
	int octet, bit;
	unsigned char mask;

	if (len != 8) {
		dev_warn(dev, "imon %s: invalid incoming packet size (len = %d, intf%d)\n",
			 __func__, len, intf);
		return;
	}

	if (debug)
		dev_info(dev, "raw packet: %*ph\n", len, buf);
	/*
	 * Translate received data to pulse and space lengths.
	 * Received data is active low, i.e. pulses are 0 and
	 * spaces are 1.
	 *
	 * My original algorithm was essentially similar to
	 * Changwoo Ryu's with the exception that he switched
	 * the incoming bits to active high and also fed an
	 * initial space to LIRC at the start of a new sequence
	 * if the previous bit was a pulse.
	 *
	 * I've decided to adopt his algorithm.
	 */

	if (buf[7] == 1 && context->rx.initial_space) {
		/* LIRC requires a leading space */
		context->rx.prev_bit = 0;
		context->rx.count = 4;
		submit_data(context);
		context->rx.count = 0;
	}

	for (octet = 0; octet < 5; ++octet) {
		mask = 0x80;
		for (bit = 0; bit < 8; ++bit) {
			int curr_bit = !(buf[octet] & mask);

			if (curr_bit != context->rx.prev_bit) {
				if (context->rx.count) {
					submit_data(context);
					context->rx.count = 0;
				}
				context->rx.prev_bit = curr_bit;
			}
			++context->rx.count;
			mask >>= 1;
		}
	}

	if (buf[7] == 10) {
		if (context->rx.count) {
			submit_data(context);
			context->rx.count = 0;
		}
		context->rx.initial_space = context->rx.prev_bit;
	}

	ir_raw_event_handle(context->rdev);
}

static void imon_incoming_scancode(struct imon_context *ictx,
				   struct urb *urb, int intf)
{
	int len = urb->actual_length;
	unsigned char *buf = urb->transfer_buffer;
	struct device *dev = ictx->dev;
	unsigned long flags;
	u32 kc;
	u64 scancode;
	int press_type = 0;
	int msec;
	struct timeval t;
	static struct timeval prev_time = { 0, 0 };
	u8 ktype;

	/* filter out junk data on the older 0xffdc imon devices */
	if ((buf[0] == 0xff) && (buf[1] == 0xff) && (buf[2] == 0xff))
		return;

	/* Figure out what key was pressed */
	if (len == 8 && buf[7] == 0xee) {
		scancode = be64_to_cpu(*((__be64 *)buf));
		ktype = IMON_KEY_PANEL;
		kc = imon_panel_key_lookup(ictx, scancode);
		ictx->release_code = false;
	} else {
		scancode = be32_to_cpu(*((__be32 *)buf));
		if (ictx->rc_type == RC_BIT_RC6_MCE) {
			ktype = IMON_KEY_IMON;
			if (buf[0] == 0x80)
				ktype = IMON_KEY_MCE;
			kc = imon_mce_key_lookup(ictx, scancode);
		} else {
			ktype = IMON_KEY_IMON;
			kc = imon_remote_key_lookup(ictx, scancode);
		}
	}

	spin_lock_irqsave(&ictx->kc_lock, flags);
	/* keyboard/mouse mode toggle button */
	if (kc == KEY_KEYBOARD && !ictx->release_code) {
		ictx->last_keycode = kc;
		if (!nomouse) {
			ictx->pad_mouse = !ictx->pad_mouse;
			dev_dbg(dev, "toggling to %s mode\n",
				ictx->pad_mouse ? "mouse" : "keyboard");
			spin_unlock_irqrestore(&ictx->kc_lock, flags);
			return;
		} else {
			ictx->pad_mouse = false;
			dev_dbg(dev, "mouse mode disabled, passing key value\n");
		}
	}

	ictx->kc = kc;
	spin_unlock_irqrestore(&ictx->kc_lock, flags);

	/* send touchscreen events through input subsystem if touchpad data */
	if (ictx->display_type == IMON_DISPLAY_TYPE_VGA && len == 8 &&
	    buf[7] == 0x86) {
		imon_touch_event(ictx, buf);
		return;

	/* look for mouse events with pad in mouse mode */
	} else if (ictx->pad_mouse) {
		if (imon_mouse_event(ictx, buf, len))
			return;
	}

	/* Now for some special handling to convert pad input to arrow keys */
	if (((len == 5) && (buf[0] == 0x01) && (buf[4] == 0x00)) ||
	    ((len == 8) && (buf[0] & 0x40) &&
	     !(buf[1] & 0x1 || buf[1] >> 2 & 0x1))) {
		len = 8;
		imon_pad_to_keys(ictx, buf);
	}

	if (debug) {
		printk(KERN_INFO "intf%d decoded packet: %*ph\n",
		       intf, len, buf);
	}

	press_type = imon_parse_press_type(ictx, buf, ktype);
	if (press_type < 0)
		goto not_input_data;

	if (ktype != IMON_KEY_PANEL) {
		if (press_type == 0)
			rc_keyup(ictx->rdev);
		else {
			if (ictx->rc_type == RC_BIT_RC6_MCE ||
			    ictx->rc_type == RC_BIT_OTHER)
				rc_keydown(ictx->rdev,
					   ictx->rc_type == RC_BIT_RC6_MCE ? RC_TYPE_RC6_MCE : RC_TYPE_OTHER,
					   ictx->rc_scancode, ictx->rc_toggle);
			spin_lock_irqsave(&ictx->kc_lock, flags);
			ictx->last_keycode = ictx->kc;
			spin_unlock_irqrestore(&ictx->kc_lock, flags);
		}
		return;
	}

	/* Only panel type events left to process now */
	spin_lock_irqsave(&ictx->kc_lock, flags);

	do_gettimeofday(&t);
	/* KEY_MUTE repeats from knob need to be suppressed */
	if (ictx->kc == KEY_MUTE && ictx->kc == ictx->last_keycode) {
		msec = tv2int(&t, &prev_time);
		if (msec < ictx->idev->rep[REP_DELAY]) {
			spin_unlock_irqrestore(&ictx->kc_lock, flags);
			return;
		}
	}
	prev_time = t;
	kc = ictx->kc;

	spin_unlock_irqrestore(&ictx->kc_lock, flags);

	input_report_key(ictx->idev, kc, press_type);
	input_sync(ictx->idev);

	/* panel keys don't generate a release */
	input_report_key(ictx->idev, kc, 0);
	input_sync(ictx->idev);

	spin_lock_irqsave(&ictx->kc_lock, flags);
	ictx->last_keycode = kc;
	spin_unlock_irqrestore(&ictx->kc_lock, flags);

	return;

not_input_data:
	if (len != 8) {
		dev_warn(dev, "imon %s: invalid incoming packet size (len = %d, intf%d)\n",
			 __func__, len, intf);
		return;
	}

	/* iMON 2.4G associate frame */
	if (buf[0] == 0x00 &&
	    buf[2] == 0xFF &&				/* REFID */
	    buf[3] == 0xFF &&
	    buf[4] == 0xFF &&
	    buf[5] == 0xFF &&				/* iMON 2.4G */
	   ((buf[6] == 0x4E && buf[7] == 0xDF) ||	/* LT */
	    (buf[6] == 0x5E && buf[7] == 0xDF))) {	/* DT */
		dev_warn(dev, "%s: remote associated refid=%02X\n",
			 __func__, buf[1]);
		ictx->rf_isassociating = false;
	}
}

/**
 * Callback function for USB core API: receive data
 */
static void usb_rx_callback_intf0(struct urb *urb)
{
	struct imon_context *ictx;
	int intfnum = 0;

	if (!urb)
		return;

	ictx = (struct imon_context *)urb->context;
	if (!ictx)
		return;

	/*
	 * if we get a callback before we're done configuring the hardware, we
	 * can't yet process the data, as there's nowhere to send it, but we
	 * still need to submit a new rx URB to avoid wedging the hardware
	 */
	if (!ictx->dev_present_intf0)
		goto out;

	switch (urb->status) {
	case -ENOENT:		/* usbcore unlink successful! */
		return;

	case -ESHUTDOWN:	/* transport endpoint was shut down */
		break;

	case 0:
		if (ictx->rdev->driver_type == RC_DRIVER_IR_RAW)
			imon_incoming_ir_raw(ictx, urb, intfnum);
		else
			imon_incoming_scancode(ictx, urb, intfnum);
		break;

	default:
		dev_warn(ictx->dev, "imon %s: status(%d): ignored\n",
			 __func__, urb->status);
		break;
	}

out:
	usb_submit_urb(ictx->rx_urb_intf0, GFP_ATOMIC);
}

static void usb_rx_callback_intf1(struct urb *urb)
{
	struct imon_context *ictx;
	int intfnum = 1;

	if (!urb)
		return;

	ictx = (struct imon_context *)urb->context;
	if (!ictx)
		return;

	/*
	 * if we get a callback before we're done configuring the hardware, we
	 * can't yet process the data, as there's nowhere to send it, but we
	 * still need to submit a new rx URB to avoid wedging the hardware
	 */
	if (!ictx->dev_present_intf1)
		goto out;

	switch (urb->status) {
	case -ENOENT:		/* usbcore unlink successful! */
		return;

	case -ESHUTDOWN:	/* transport endpoint was shut down */
		break;

	case 0:
		if (ictx->rdev->driver_type == RC_DRIVER_IR_RAW)
			imon_incoming_ir_raw(ictx, urb, intfnum);
		else
			imon_incoming_scancode(ictx, urb, intfnum);
		break;

	default:
		dev_warn(ictx->dev, "imon %s: status(%d): ignored\n",
			 __func__, urb->status);
		break;
	}

out:
	usb_submit_urb(ictx->rx_urb_intf1, GFP_ATOMIC);
}

/*
 * The 0x15c2:0xffdc device ID was used for umpteen different imon
 * devices, and all of them constantly spew interrupts, even when there
 * is no actual data to report. However, byte 6 of this buffer looks like
 * its unique across device variants, so we're trying to key off that to
 * figure out which display type (if any) and what IR protocol the device
 * actually supports. These devices have their IR protocol hard-coded into
 * their firmware, they can't be changed on the fly like the newer hardware.
 */
static void imon_get_ffdc_type(struct imon_context *ictx)
{
	u8 ffdc_cfg_byte = ictx->usb_rx_buf[6];
	u8 detected_display_type = IMON_DISPLAY_TYPE_NONE;
	u64 allowed_protos = RC_BIT_OTHER;

	switch (ffdc_cfg_byte) {
	/* iMON Knob, no display, iMON IR + vol knob */
	case 0x21:
		dev_info(ictx->dev, "0xffdc iMON Knob, iMON IR");
		ictx->display_supported = false;
		break;
	/* iMON 2.4G LT (usb stick), no display, iMON RF */
	case 0x4e:
		dev_info(ictx->dev, "0xffdc iMON 2.4G LT, iMON RF");
		ictx->display_supported = false;
		ictx->rf_device = true;
		break;
	/* iMON VFD, no IR (does have vol knob tho) */
	case 0x35:
		dev_info(ictx->dev, "0xffdc iMON VFD + knob, no IR");
		detected_display_type = IMON_DISPLAY_TYPE_VFD;
		break;
	/* iMON VFD, iMON IR */
	case 0x24:
	case 0x85:
		dev_info(ictx->dev, "0xffdc iMON VFD, iMON IR");
		detected_display_type = IMON_DISPLAY_TYPE_VFD;
		break;
	/* iMON VFD, MCE IR */
	case 0x46:
	case 0x7e:
	case 0x9e:
		dev_info(ictx->dev, "0xffdc iMON VFD, MCE IR");
		detected_display_type = IMON_DISPLAY_TYPE_VFD;
		allowed_protos = RC_BIT_RC6_MCE;
		break;
	/* iMON LCD, MCE IR */
	case 0x9f:
		dev_info(ictx->dev, "0xffdc iMON LCD, MCE IR");
		detected_display_type = IMON_DISPLAY_TYPE_LCD;
		allowed_protos = RC_BIT_RC6_MCE;
		break;
	default:
		dev_info(ictx->dev, "Unknown 0xffdc device, defaulting to VFD and iMON IR");
		detected_display_type = IMON_DISPLAY_TYPE_VFD;
		/* We don't know which one it is, allow user to set the
		 * RC6 one from userspace if OTHER wasn't correct. */
		allowed_protos |= RC_BIT_RC6_MCE;
		break;
	}

	printk(KERN_CONT " (id 0x%02x)\n", ffdc_cfg_byte);

	ictx->display_type = detected_display_type;
	ictx->rc_type = allowed_protos;
}

static void imon_set_display_type(struct imon_context *ictx)
{
	u8 configured_display_type = IMON_DISPLAY_TYPE_VFD;

	/*
	 * Try to auto-detect the type of display if the user hasn't set
	 * it by hand via the display_type modparam. Default is VFD.
	 */

	if (display_type == IMON_DISPLAY_TYPE_AUTO) {
		switch (ictx->product) {
		case 0xffdc:
			/* set in imon_get_ffdc_type() */
			configured_display_type = ictx->display_type;
			break;
		case 0x0034:
		case 0x0035:
			configured_display_type = IMON_DISPLAY_TYPE_VGA;
			break;
		case 0x0038:
		case 0x0039:
		case 0x0045:
			configured_display_type = IMON_DISPLAY_TYPE_LCD;
			break;
		case 0x003c:
		case 0x0041:
		case 0x0042:
		case 0x0043:
		case 0x8001:
		case 0xff30:
			configured_display_type = IMON_DISPLAY_TYPE_NONE;
			ictx->display_supported = false;
			break;
		case 0x0036:
		case 0x0044:
		case 0xffda:
		default:
			configured_display_type = IMON_DISPLAY_TYPE_VFD;
			break;
		}
	} else {
		configured_display_type = display_type;
		if (display_type == IMON_DISPLAY_TYPE_NONE)
			ictx->display_supported = false;
		else
			ictx->display_supported = true;
		dev_info(ictx->dev, "%s: overriding display type to %d via modparam\n",
			 __func__, display_type);
	}

	ictx->display_type = configured_display_type;
}

static struct rc_dev *imon_init_rdev(struct imon_context *ictx)
{
	struct rc_dev *rdev;
	int ret;
	const unsigned char fp_packet[] = { 0x40, 0x00, 0x00, 0x00,
					    0x00, 0x00, 0x00, 0x88 };

	rdev = rc_allocate_device(ictx->dev_descr->flags & IMON_IR_RAW ?
				  RC_DRIVER_IR_RAW : RC_DRIVER_SCANCODE);
	if (!rdev) {
		dev_err(ictx->dev, "remote control dev allocation failed\n");
		goto out;
	}

	snprintf(ictx->name_rdev, sizeof(ictx->name_rdev),
		 "iMON Remote (%04x:%04x)", ictx->vendor, ictx->product);
	usb_make_path(ictx->usbdev_intf0, ictx->phys_rdev,
		      sizeof(ictx->phys_rdev));
	strlcat(ictx->phys_rdev, "/input0", sizeof(ictx->phys_rdev));

	rdev->input_name = ictx->name_rdev;
	rdev->input_phys = ictx->phys_rdev;
	usb_to_input_id(ictx->usbdev_intf0, &rdev->input_id);
	rdev->dev.parent = ictx->dev;

	rdev->priv = ictx;
	if (ictx->dev_descr->flags & IMON_IR_RAW)
		rdev->allowed_protocols = RC_BIT_ALL_IR_DECODER;
	else
		/* iMON PAD or MCE */
		rdev->allowed_protocols = RC_BIT_OTHER | RC_BIT_RC6_MCE;
	rdev->change_protocol = imon_ir_change_protocol;
	rdev->driver_name = MOD_NAME;

	/* Enable front-panel buttons and/or knobs */
	memcpy(ictx->usb_tx_buf, &fp_packet, sizeof(fp_packet));
	ret = send_packet(ictx);
	/* Not fatal, but warn about it */
	if (ret)
		dev_info(ictx->dev, "panel buttons/knobs setup failed\n");

	if (ictx->product == 0xffdc) {
		imon_get_ffdc_type(ictx);
		rdev->allowed_protocols = ictx->rc_type;
	}

	imon_set_display_type(ictx);

	if (ictx->rc_type == RC_BIT_RC6_MCE ||
	    ictx->dev_descr->flags & IMON_IR_RAW)
		rdev->map_name = RC_MAP_IMON_MCE;
	else
		rdev->map_name = RC_MAP_IMON_PAD;

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

	return rdev;

out:
	rc_free_device(rdev);
	return NULL;
}

static struct input_dev *imon_init_idev(struct imon_context *ictx)
{
	struct imon_panel_key_table *key_table = ictx->dev_descr->key_table;
	struct input_dev *idev;
	int ret, i;

	idev = input_allocate_device();
	if (!idev)
		goto out;

	snprintf(ictx->name_idev, sizeof(ictx->name_idev),
		 "iMON Panel, Knob and Mouse(%04x:%04x)",
		 ictx->vendor, ictx->product);
	idev->name = ictx->name_idev;

	usb_make_path(ictx->usbdev_intf0, ictx->phys_idev,
		      sizeof(ictx->phys_idev));
	strlcat(ictx->phys_idev, "/input1", sizeof(ictx->phys_idev));
	idev->phys = ictx->phys_idev;

	idev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP) | BIT_MASK(EV_REL);

	idev->keybit[BIT_WORD(BTN_MOUSE)] =
		BIT_MASK(BTN_LEFT) | BIT_MASK(BTN_RIGHT);
	idev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y) |
		BIT_MASK(REL_WHEEL);

	/* panel and/or knob code support */
	for (i = 0; key_table[i].hw_code != 0; i++) {
		u32 kc = key_table[i].keycode;
		__set_bit(kc, idev->keybit);
	}

	usb_to_input_id(ictx->usbdev_intf0, &idev->id);
	idev->dev.parent = ictx->dev;
	input_set_drvdata(idev, ictx);

	ret = input_register_device(idev);
	if (ret < 0) {
		dev_err(ictx->dev, "input dev register failed\n");
		goto out;
	}

	return idev;

out:
	input_free_device(idev);
	return NULL;
}

static struct input_dev *imon_init_touch(struct imon_context *ictx)
{
	struct input_dev *touch;
	int ret;

	touch = input_allocate_device();
	if (!touch)
		goto touch_alloc_failed;

	snprintf(ictx->name_touch, sizeof(ictx->name_touch),
		 "iMON USB Touchscreen (%04x:%04x)",
		 ictx->vendor, ictx->product);
	touch->name = ictx->name_touch;

	usb_make_path(ictx->usbdev_intf1, ictx->phys_touch,
		      sizeof(ictx->phys_touch));
	strlcat(ictx->phys_touch, "/input2", sizeof(ictx->phys_touch));
	touch->phys = ictx->phys_touch;

	touch->evbit[0] =
		BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
	touch->keybit[BIT_WORD(BTN_TOUCH)] =
		BIT_MASK(BTN_TOUCH);
	input_set_abs_params(touch, ABS_X,
			     0x00, 0xfff, 0, 0);
	input_set_abs_params(touch, ABS_Y,
			     0x00, 0xfff, 0, 0);

	input_set_drvdata(touch, ictx);

	usb_to_input_id(ictx->usbdev_intf1, &touch->id);
	touch->dev.parent = ictx->dev;
	ret = input_register_device(touch);
	if (ret <  0) {
		dev_info(ictx->dev, "touchscreen input dev register failed\n");
		goto touch_register_failed;
	}

	return touch;

touch_register_failed:
	input_free_device(touch);

touch_alloc_failed:
	return NULL;
}

static bool imon_find_endpoints(struct imon_context *ictx,
				struct usb_host_interface *iface_desc)
{
	struct usb_endpoint_descriptor *ep;
	struct usb_endpoint_descriptor *rx_endpoint = NULL;
	struct usb_endpoint_descriptor *tx_endpoint = NULL;
	int ifnum = iface_desc->desc.bInterfaceNumber;
	int num_endpts = iface_desc->desc.bNumEndpoints;
	int i, ep_dir, ep_type;
	bool ir_ep_found = false;
	bool display_ep_found = false;
	bool tx_control = false;

	/*
	 * Scan the endpoint list and set:
	 *	first input endpoint = IR endpoint
	 *	first output endpoint = display endpoint
	 */
	for (i = 0; i < num_endpts && !(ir_ep_found && display_ep_found); ++i) {
		ep = &iface_desc->endpoint[i].desc;
		ep_dir = ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK;
		ep_type = usb_endpoint_type(ep);

		if (!ir_ep_found && ep_dir == USB_DIR_IN &&
		    ep_type == USB_ENDPOINT_XFER_INT) {

			rx_endpoint = ep;
			ir_ep_found = true;
			dev_dbg(ictx->dev, "%s: found IR endpoint\n", __func__);

		} else if (!display_ep_found && ep_dir == USB_DIR_OUT &&
			   ep_type == USB_ENDPOINT_XFER_INT) {
			tx_endpoint = ep;
			display_ep_found = true;
			dev_dbg(ictx->dev, "%s: found display endpoint\n", __func__);
		}
	}

	if (ifnum == 0) {
		ictx->rx_endpoint_intf0 = rx_endpoint;
		/*
		 * tx is used to send characters to lcd/vfd, associate RF
		 * remotes, set IR protocol, and maybe more...
		 */
		ictx->tx_endpoint = tx_endpoint;
	} else {
		ictx->rx_endpoint_intf1 = rx_endpoint;
	}

	/*
	 * If we didn't find a display endpoint, this is probably one of the
	 * newer iMON devices that use control urb instead of interrupt
	 */
	if (!display_ep_found) {
		tx_control = true;
		display_ep_found = true;
		dev_dbg(ictx->dev, "%s: device uses control endpoint, not interface OUT endpoint\n",
			__func__);
	}

	/*
	 * Some iMON receivers have no display. Unfortunately, it seems
	 * that SoundGraph recycles device IDs between devices both with
	 * and without... :\
	 */
	if (ictx->display_type == IMON_DISPLAY_TYPE_NONE) {
		display_ep_found = false;
		dev_dbg(ictx->dev, "%s: device has no display\n", __func__);
	}

	/*
	 * iMON Touch devices have a VGA touchscreen, but no "display", as
	 * that refers to e.g. /dev/lcd0 (a character device LCD or VFD).
	 */
	if (ictx->display_type == IMON_DISPLAY_TYPE_VGA) {
		display_ep_found = false;
		dev_dbg(ictx->dev, "%s: iMON Touch device found\n", __func__);
	}

	/* Input endpoint is mandatory */
	if (!ir_ep_found)
		pr_err("no valid input (IR) endpoint found\n");

	ictx->tx_control = tx_control;

	if (display_ep_found)
		ictx->display_supported = true;

	return ir_ep_found;

}

static struct imon_context *imon_init_intf0(struct usb_interface *intf,
					    const struct usb_device_id *id)
{
	struct imon_context *ictx;
	struct urb *rx_urb;
	struct urb *tx_urb;
	struct device *dev = &intf->dev;
	struct usb_host_interface *iface_desc;
	int ret = -ENOMEM;

	ictx = kzalloc(sizeof(struct imon_context), GFP_KERNEL);
	if (!ictx) {
		dev_err(dev, "%s: kzalloc failed for context", __func__);
		goto exit;
	}
	rx_urb = usb_alloc_urb(0, GFP_KERNEL);
	if (!rx_urb)
		goto rx_urb_alloc_failed;
	tx_urb = usb_alloc_urb(0, GFP_KERNEL);
	if (!tx_urb)
		goto tx_urb_alloc_failed;

	mutex_init(&ictx->lock);
	spin_lock_init(&ictx->kc_lock);

	mutex_lock(&ictx->lock);

	ictx->dev = dev;
	ictx->usbdev_intf0 = usb_get_dev(interface_to_usbdev(intf));
	ictx->rx_urb_intf0 = rx_urb;
	ictx->tx_urb = tx_urb;
	ictx->rf_device = false;

	init_completion(&ictx->tx.finished);

	ictx->vendor  = le16_to_cpu(ictx->usbdev_intf0->descriptor.idVendor);
	ictx->product = le16_to_cpu(ictx->usbdev_intf0->descriptor.idProduct);

	/* save drive info for later accessing the panel/knob key table */
	ictx->dev_descr = (struct imon_usb_dev_descr *)id->driver_info;
	/* default send_packet delay is 5ms but some devices need more */
	ictx->send_packet_delay = ictx->dev_descr->flags &
				  IMON_NEED_20MS_PKT_DELAY ? 20 : 5;

	ret = -ENODEV;
	iface_desc = intf->cur_altsetting;
	if (!imon_find_endpoints(ictx, iface_desc)) {
		goto find_endpoint_failed;
	}

	usb_fill_int_urb(ictx->rx_urb_intf0, ictx->usbdev_intf0,
		usb_rcvintpipe(ictx->usbdev_intf0,
			ictx->rx_endpoint_intf0->bEndpointAddress),
		ictx->usb_rx_buf, sizeof(ictx->usb_rx_buf),
		usb_rx_callback_intf0, ictx,
		ictx->rx_endpoint_intf0->bInterval);

	ret = usb_submit_urb(ictx->rx_urb_intf0, GFP_KERNEL);
	if (ret) {
		pr_err("usb_submit_urb failed for intf0 (%d)\n", ret);
		goto urb_submit_failed;
	}

	ictx->idev = imon_init_idev(ictx);
	if (!ictx->idev) {
		dev_err(dev, "%s: input device setup failed\n", __func__);
		goto idev_setup_failed;
	}

	ictx->rdev = imon_init_rdev(ictx);
	if (!ictx->rdev) {
		dev_err(dev, "%s: rc device setup failed\n", __func__);
		goto rdev_setup_failed;
	}

	ictx->dev_present_intf0 = true;

	mutex_unlock(&ictx->lock);
	return ictx;

rdev_setup_failed:
	input_unregister_device(ictx->idev);
idev_setup_failed:
	usb_kill_urb(ictx->rx_urb_intf0);
urb_submit_failed:
find_endpoint_failed:
	usb_put_dev(ictx->usbdev_intf0);
	mutex_unlock(&ictx->lock);
	usb_free_urb(tx_urb);
tx_urb_alloc_failed:
	usb_free_urb(rx_urb);
rx_urb_alloc_failed:
	kfree(ictx);
exit:
	dev_err(dev, "unable to initialize intf0, err %d\n", ret);

	return NULL;
}

static struct imon_context *imon_init_intf1(struct usb_interface *intf,
					    struct imon_context *ictx)
{
	struct urb *rx_urb;
	struct usb_host_interface *iface_desc;
	int ret = -ENOMEM;

	rx_urb = usb_alloc_urb(0, GFP_KERNEL);
	if (!rx_urb)
		goto rx_urb_alloc_failed;

	mutex_lock(&ictx->lock);

	if (ictx->display_type == IMON_DISPLAY_TYPE_VGA) {
		setup_timer(&ictx->ttimer, imon_touch_display_timeout,
			    (unsigned long)ictx);
	}

	ictx->usbdev_intf1 = usb_get_dev(interface_to_usbdev(intf));
	ictx->rx_urb_intf1 = rx_urb;

	ret = -ENODEV;
	iface_desc = intf->cur_altsetting;
	if (!imon_find_endpoints(ictx, iface_desc))
		goto find_endpoint_failed;

	if (ictx->display_type == IMON_DISPLAY_TYPE_VGA) {
		ictx->touch = imon_init_touch(ictx);
		if (!ictx->touch)
			goto touch_setup_failed;
	} else
		ictx->touch = NULL;

	usb_fill_int_urb(ictx->rx_urb_intf1, ictx->usbdev_intf1,
		usb_rcvintpipe(ictx->usbdev_intf1,
			ictx->rx_endpoint_intf1->bEndpointAddress),
		ictx->usb_rx_buf, sizeof(ictx->usb_rx_buf),
		usb_rx_callback_intf1, ictx,
		ictx->rx_endpoint_intf1->bInterval);

	ret = usb_submit_urb(ictx->rx_urb_intf1, GFP_KERNEL);

	if (ret) {
		pr_err("usb_submit_urb failed for intf1 (%d)\n", ret);
		goto urb_submit_failed;
	}

	ictx->dev_present_intf1 = true;

	mutex_unlock(&ictx->lock);
	return ictx;

urb_submit_failed:
	if (ictx->touch)
		input_unregister_device(ictx->touch);
touch_setup_failed:
find_endpoint_failed:
	usb_put_dev(ictx->usbdev_intf1);
	mutex_unlock(&ictx->lock);
	usb_free_urb(rx_urb);
rx_urb_alloc_failed:
	dev_err(ictx->dev, "unable to initialize intf1, err %d\n", ret);

	return NULL;
}

static void imon_init_display(struct imon_context *ictx,
			      struct usb_interface *intf)
{
	int ret;

	dev_dbg(ictx->dev, "Registering iMON display with sysfs\n");

	/* set up sysfs entry for built-in clock */
	ret = sysfs_create_group(&intf->dev.kobj, &imon_display_attr_group);
	if (ret)
		dev_err(ictx->dev, "Could not create display sysfs entries(%d)",
			ret);

	if (ictx->display_type == IMON_DISPLAY_TYPE_LCD)
		ret = usb_register_dev(intf, &imon_lcd_class);
	else
		ret = usb_register_dev(intf, &imon_vfd_class);
	if (ret)
		/* Not a fatal error, so ignore */
		dev_info(ictx->dev, "could not get a minor number for display\n");

}

/**
 * Callback function for USB core API: Probe
 */
static int imon_probe(struct usb_interface *interface,
		      const struct usb_device_id *id)
{
	struct usb_device *usbdev = NULL;
	struct usb_host_interface *iface_desc = NULL;
	struct usb_interface *first_if;
	struct device *dev = &interface->dev;
	int ifnum, sysfs_err;
	int ret = 0;
	struct imon_context *ictx = NULL;
	struct imon_context *first_if_ctx = NULL;
	u16 vendor, product;

	usbdev     = usb_get_dev(interface_to_usbdev(interface));
	iface_desc = interface->cur_altsetting;
	ifnum      = iface_desc->desc.bInterfaceNumber;
	vendor     = le16_to_cpu(usbdev->descriptor.idVendor);
	product    = le16_to_cpu(usbdev->descriptor.idProduct);

	dev_dbg(dev, "%s: found iMON device (%04x:%04x, intf%d)\n",
		__func__, vendor, product, ifnum);

	/* prevent races probing devices w/multiple interfaces */
	mutex_lock(&driver_lock);

	first_if = usb_ifnum_to_if(usbdev, 0);
	first_if_ctx = usb_get_intfdata(first_if);

	if (ifnum == 0) {
		ictx = imon_init_intf0(interface, id);
		if (!ictx) {
			pr_err("failed to initialize context!\n");
			ret = -ENODEV;
			goto fail;
		}

	} else {
		/* this is the secondary interface on the device */

		/* fail early if first intf failed to register */
		if (!first_if_ctx) {
			ret = -ENODEV;
			goto fail;
		}

		ictx = imon_init_intf1(interface, first_if_ctx);
		if (!ictx) {
			pr_err("failed to attach to context!\n");
			ret = -ENODEV;
			goto fail;
		}

	}

	usb_set_intfdata(interface, ictx);

	if (ifnum == 0) {
		mutex_lock(&ictx->lock);

		if (product == 0xffdc && ictx->rf_device) {
			sysfs_err = sysfs_create_group(&interface->dev.kobj,
						       &imon_rf_attr_group);
			if (sysfs_err)
				pr_err("Could not create RF sysfs entries(%d)\n",
				       sysfs_err);
		}

		if (ictx->display_supported)
			imon_init_display(ictx, interface);

		mutex_unlock(&ictx->lock);
	}

	dev_info(dev, "iMON device (%04x:%04x, intf%d) on usb<%d:%d> initialized\n",
		 vendor, product, ifnum,
		 usbdev->bus->busnum, usbdev->devnum);

	mutex_unlock(&driver_lock);
	usb_put_dev(usbdev);

	return 0;

fail:
	mutex_unlock(&driver_lock);
	usb_put_dev(usbdev);
	dev_err(dev, "unable to register, err %d\n", ret);

	return ret;
}

/**
 * Callback function for USB core API: disconnect
 */
static void imon_disconnect(struct usb_interface *interface)
{
	struct imon_context *ictx;
	struct device *dev;
	int ifnum;

	/* prevent races with multi-interface device probing and display_open */
	mutex_lock(&driver_lock);

	ictx = usb_get_intfdata(interface);
	dev = ictx->dev;
	ifnum = interface->cur_altsetting->desc.bInterfaceNumber;

	/*
	 * sysfs_remove_group is safe to call even if sysfs_create_group
	 * hasn't been called
	 */
	sysfs_remove_group(&interface->dev.kobj, &imon_display_attr_group);
	sysfs_remove_group(&interface->dev.kobj, &imon_rf_attr_group);

	usb_set_intfdata(interface, NULL);

	/* Abort ongoing write */
	if (ictx->tx.busy) {
		usb_kill_urb(ictx->tx_urb);
		complete(&ictx->tx.finished);
	}

	if (ifnum == 0) {
		ictx->dev_present_intf0 = false;
		usb_kill_urb(ictx->rx_urb_intf0);
		usb_put_dev(ictx->usbdev_intf0);
		input_unregister_device(ictx->idev);
		rc_unregister_device(ictx->rdev);
		if (ictx->display_supported) {
			if (ictx->display_type == IMON_DISPLAY_TYPE_LCD)
				usb_deregister_dev(interface, &imon_lcd_class);
			else if (ictx->display_type == IMON_DISPLAY_TYPE_VFD)
				usb_deregister_dev(interface, &imon_vfd_class);
		}
	} else {
		ictx->dev_present_intf1 = false;
		usb_kill_urb(ictx->rx_urb_intf1);
		usb_put_dev(ictx->usbdev_intf1);
		if (ictx->display_type == IMON_DISPLAY_TYPE_VGA) {
			input_unregister_device(ictx->touch);
			del_timer_sync(&ictx->ttimer);
		}
	}

	if (!ictx->dev_present_intf0 && !ictx->dev_present_intf1)
		free_imon_context(ictx);

	mutex_unlock(&driver_lock);

	dev_dbg(dev, "%s: iMON device (intf%d) disconnected\n",
		__func__, ifnum);
}

static int imon_suspend(struct usb_interface *intf, pm_message_t message)
{
	struct imon_context *ictx = usb_get_intfdata(intf);
	int ifnum = intf->cur_altsetting->desc.bInterfaceNumber;

	if (ifnum == 0)
		usb_kill_urb(ictx->rx_urb_intf0);
	else
		usb_kill_urb(ictx->rx_urb_intf1);

	return 0;
}

static int imon_resume(struct usb_interface *intf)
{
	int rc = 0;
	struct imon_context *ictx = usb_get_intfdata(intf);
	int ifnum = intf->cur_altsetting->desc.bInterfaceNumber;

	if (ifnum == 0) {
		usb_fill_int_urb(ictx->rx_urb_intf0, ictx->usbdev_intf0,
			usb_rcvintpipe(ictx->usbdev_intf0,
				ictx->rx_endpoint_intf0->bEndpointAddress),
			ictx->usb_rx_buf, sizeof(ictx->usb_rx_buf),
			usb_rx_callback_intf0, ictx,
			ictx->rx_endpoint_intf0->bInterval);

		rc = usb_submit_urb(ictx->rx_urb_intf0, GFP_ATOMIC);

	} else {
		usb_fill_int_urb(ictx->rx_urb_intf1, ictx->usbdev_intf1,
			usb_rcvintpipe(ictx->usbdev_intf1,
				ictx->rx_endpoint_intf1->bEndpointAddress),
			ictx->usb_rx_buf, sizeof(ictx->usb_rx_buf),
			usb_rx_callback_intf1, ictx,
			ictx->rx_endpoint_intf1->bInterval);

		rc = usb_submit_urb(ictx->rx_urb_intf1, GFP_ATOMIC);
	}

	return rc;
}

module_usb_driver(imon_driver);
