PageRenderTime 103ms CodeModel.GetById 23ms app.highlight 70ms RepoModel.GetById 0ms app.codeStats 1ms

/drivers/media/rc/imon.c

https://bitbucket.org/wisechild/galaxy-nexus
C | 2476 lines | 1757 code | 388 blank | 331 comment | 362 complexity | bf7ad5071e25001540135eba23591f23 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.0, AGPL-1.0

Large files files are truncated, but you can click here to view the full file

   1/*
   2 *   imon.c:	input and display driver for SoundGraph iMON IR/VFD/LCD
   3 *
   4 *   Copyright(C) 2010  Jarod Wilson <jarod@wilsonet.com>
   5 *   Portions based on the original lirc_imon driver,
   6 *	Copyright(C) 2004  Venky Raju(dev@venky.ws)
   7 *
   8 *   Huge thanks to R. Geoff Newbury for invaluable debugging on the
   9 *   0xffdc iMON devices, and for sending me one to hack on, without
  10 *   which the support for them wouldn't be nearly as good. Thanks
  11 *   also to the numerous 0xffdc device owners that tested auto-config
  12 *   support for me and provided debug dumps from their devices.
  13 *
  14 *   imon is free software; you can redistribute it and/or modify
  15 *   it under the terms of the GNU General Public License as published by
  16 *   the Free Software Foundation; either version 2 of the License, or
  17 *   (at your option) any later version.
  18 *
  19 *   This program is distributed in the hope that it will be useful,
  20 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
  21 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  22 *   GNU General Public License for more details.
  23 *
  24 *   You should have received a copy of the GNU General Public License
  25 *   along with this program; if not, write to the Free Software
  26 *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  27 */
  28
  29#define pr_fmt(fmt) KBUILD_MODNAME ":%s: " fmt, __func__
  30
  31#include <linux/errno.h>
  32#include <linux/init.h>
  33#include <linux/kernel.h>
  34#include <linux/module.h>
  35#include <linux/slab.h>
  36#include <linux/uaccess.h>
  37
  38#include <linux/input.h>
  39#include <linux/usb.h>
  40#include <linux/usb/input.h>
  41#include <media/rc-core.h>
  42
  43#include <linux/time.h>
  44#include <linux/timer.h>
  45
  46#define MOD_AUTHOR	"Jarod Wilson <jarod@wilsonet.com>"
  47#define MOD_DESC	"Driver for SoundGraph iMON MultiMedia IR/Display"
  48#define MOD_NAME	"imon"
  49#define MOD_VERSION	"0.9.3"
  50
  51#define DISPLAY_MINOR_BASE	144
  52#define DEVICE_NAME	"lcd%d"
  53
  54#define BUF_CHUNK_SIZE	8
  55#define BUF_SIZE	128
  56
  57#define BIT_DURATION	250	/* each bit received is 250us */
  58
  59#define IMON_CLOCK_ENABLE_PACKETS	2
  60
  61/*** P R O T O T Y P E S ***/
  62
  63/* USB Callback prototypes */
  64static int imon_probe(struct usb_interface *interface,
  65		      const struct usb_device_id *id);
  66static void imon_disconnect(struct usb_interface *interface);
  67static void usb_rx_callback_intf0(struct urb *urb);
  68static void usb_rx_callback_intf1(struct urb *urb);
  69static void usb_tx_callback(struct urb *urb);
  70
  71/* suspend/resume support */
  72static int imon_resume(struct usb_interface *intf);
  73static int imon_suspend(struct usb_interface *intf, pm_message_t message);
  74
  75/* Display file_operations function prototypes */
  76static int display_open(struct inode *inode, struct file *file);
  77static int display_close(struct inode *inode, struct file *file);
  78
  79/* VFD write operation */
  80static ssize_t vfd_write(struct file *file, const char *buf,
  81			 size_t n_bytes, loff_t *pos);
  82
  83/* LCD file_operations override function prototypes */
  84static ssize_t lcd_write(struct file *file, const char *buf,
  85			 size_t n_bytes, loff_t *pos);
  86
  87/*** G L O B A L S ***/
  88
  89struct imon_context {
  90	struct device *dev;
  91	/* Newer devices have two interfaces */
  92	struct usb_device *usbdev_intf0;
  93	struct usb_device *usbdev_intf1;
  94
  95	bool display_supported;		/* not all controllers do */
  96	bool display_isopen;		/* display port has been opened */
  97	bool rf_device;			/* true if iMON 2.4G LT/DT RF device */
  98	bool rf_isassociating;		/* RF remote associating */
  99	bool dev_present_intf0;		/* USB device presence, interface 0 */
 100	bool dev_present_intf1;		/* USB device presence, interface 1 */
 101
 102	struct mutex lock;		/* to lock this object */
 103	wait_queue_head_t remove_ok;	/* For unexpected USB disconnects */
 104
 105	struct usb_endpoint_descriptor *rx_endpoint_intf0;
 106	struct usb_endpoint_descriptor *rx_endpoint_intf1;
 107	struct usb_endpoint_descriptor *tx_endpoint;
 108	struct urb *rx_urb_intf0;
 109	struct urb *rx_urb_intf1;
 110	struct urb *tx_urb;
 111	bool tx_control;
 112	unsigned char usb_rx_buf[8];
 113	unsigned char usb_tx_buf[8];
 114
 115	struct tx_t {
 116		unsigned char data_buf[35];	/* user data buffer */
 117		struct completion finished;	/* wait for write to finish */
 118		bool busy;			/* write in progress */
 119		int status;			/* status of tx completion */
 120	} tx;
 121
 122	u16 vendor;			/* usb vendor ID */
 123	u16 product;			/* usb product ID */
 124
 125	struct rc_dev *rdev;		/* rc-core device for remote */
 126	struct input_dev *idev;		/* input device for panel & IR mouse */
 127	struct input_dev *touch;	/* input device for touchscreen */
 128
 129	spinlock_t kc_lock;		/* make sure we get keycodes right */
 130	u32 kc;				/* current input keycode */
 131	u32 last_keycode;		/* last reported input keycode */
 132	u32 rc_scancode;		/* the computed remote scancode */
 133	u8 rc_toggle;			/* the computed remote toggle bit */
 134	u64 rc_type;			/* iMON or MCE (RC6) IR protocol? */
 135	bool release_code;		/* some keys send a release code */
 136
 137	u8 display_type;		/* store the display type */
 138	bool pad_mouse;			/* toggle kbd(0)/mouse(1) mode */
 139
 140	char name_rdev[128];		/* rc input device name */
 141	char phys_rdev[64];		/* rc input device phys path */
 142
 143	char name_idev[128];		/* input device name */
 144	char phys_idev[64];		/* input device phys path */
 145
 146	char name_touch[128];		/* touch screen name */
 147	char phys_touch[64];		/* touch screen phys path */
 148	struct timer_list ttimer;	/* touch screen timer */
 149	int touch_x;			/* x coordinate on touchscreen */
 150	int touch_y;			/* y coordinate on touchscreen */
 151};
 152
 153#define TOUCH_TIMEOUT	(HZ/30)
 154
 155/* vfd character device file operations */
 156static const struct file_operations vfd_fops = {
 157	.owner		= THIS_MODULE,
 158	.open		= &display_open,
 159	.write		= &vfd_write,
 160	.release	= &display_close,
 161	.llseek		= noop_llseek,
 162};
 163
 164/* lcd character device file operations */
 165static const struct file_operations lcd_fops = {
 166	.owner		= THIS_MODULE,
 167	.open		= &display_open,
 168	.write		= &lcd_write,
 169	.release	= &display_close,
 170	.llseek		= noop_llseek,
 171};
 172
 173enum {
 174	IMON_DISPLAY_TYPE_AUTO = 0,
 175	IMON_DISPLAY_TYPE_VFD  = 1,
 176	IMON_DISPLAY_TYPE_LCD  = 2,
 177	IMON_DISPLAY_TYPE_VGA  = 3,
 178	IMON_DISPLAY_TYPE_NONE = 4,
 179};
 180
 181enum {
 182	IMON_KEY_IMON	= 0,
 183	IMON_KEY_MCE	= 1,
 184	IMON_KEY_PANEL	= 2,
 185};
 186
 187/*
 188 * USB Device ID for iMON USB Control Boards
 189 *
 190 * The Windows drivers contain 6 different inf files, more or less one for
 191 * each new device until the 0x0034-0x0046 devices, which all use the same
 192 * driver. Some of the devices in the 34-46 range haven't been definitively
 193 * identified yet. Early devices have either a TriGem Computer, Inc. or a
 194 * Samsung vendor ID (0x0aa8 and 0x04e8 respectively), while all later
 195 * devices use the SoundGraph vendor ID (0x15c2). This driver only supports
 196 * the ffdc and later devices, which do onboard decoding.
 197 */
 198static struct usb_device_id imon_usb_id_table[] = {
 199	/*
 200	 * Several devices with this same device ID, all use iMON_PAD.inf
 201	 * SoundGraph iMON PAD (IR & VFD)
 202	 * SoundGraph iMON PAD (IR & LCD)
 203	 * SoundGraph iMON Knob (IR only)
 204	 */
 205	{ USB_DEVICE(0x15c2, 0xffdc) },
 206
 207	/*
 208	 * Newer devices, all driven by the latest iMON Windows driver, full
 209	 * list of device IDs extracted via 'strings Setup/data1.hdr |grep 15c2'
 210	 * Need user input to fill in details on unknown devices.
 211	 */
 212	/* SoundGraph iMON OEM Touch LCD (IR & 7" VGA LCD) */
 213	{ USB_DEVICE(0x15c2, 0x0034) },
 214	/* SoundGraph iMON OEM Touch LCD (IR & 4.3" VGA LCD) */
 215	{ USB_DEVICE(0x15c2, 0x0035) },
 216	/* SoundGraph iMON OEM VFD (IR & VFD) */
 217	{ USB_DEVICE(0x15c2, 0x0036) },
 218	/* device specifics unknown */
 219	{ USB_DEVICE(0x15c2, 0x0037) },
 220	/* SoundGraph iMON OEM LCD (IR & LCD) */
 221	{ USB_DEVICE(0x15c2, 0x0038) },
 222	/* SoundGraph iMON UltraBay (IR & LCD) */
 223	{ USB_DEVICE(0x15c2, 0x0039) },
 224	/* device specifics unknown */
 225	{ USB_DEVICE(0x15c2, 0x003a) },
 226	/* device specifics unknown */
 227	{ USB_DEVICE(0x15c2, 0x003b) },
 228	/* SoundGraph iMON OEM Inside (IR only) */
 229	{ USB_DEVICE(0x15c2, 0x003c) },
 230	/* device specifics unknown */
 231	{ USB_DEVICE(0x15c2, 0x003d) },
 232	/* device specifics unknown */
 233	{ USB_DEVICE(0x15c2, 0x003e) },
 234	/* device specifics unknown */
 235	{ USB_DEVICE(0x15c2, 0x003f) },
 236	/* device specifics unknown */
 237	{ USB_DEVICE(0x15c2, 0x0040) },
 238	/* SoundGraph iMON MINI (IR only) */
 239	{ USB_DEVICE(0x15c2, 0x0041) },
 240	/* Antec Veris Multimedia Station EZ External (IR only) */
 241	{ USB_DEVICE(0x15c2, 0x0042) },
 242	/* Antec Veris Multimedia Station Basic Internal (IR only) */
 243	{ USB_DEVICE(0x15c2, 0x0043) },
 244	/* Antec Veris Multimedia Station Elite (IR & VFD) */
 245	{ USB_DEVICE(0x15c2, 0x0044) },
 246	/* Antec Veris Multimedia Station Premiere (IR & LCD) */
 247	{ USB_DEVICE(0x15c2, 0x0045) },
 248	/* device specifics unknown */
 249	{ USB_DEVICE(0x15c2, 0x0046) },
 250	{}
 251};
 252
 253/* USB Device data */
 254static struct usb_driver imon_driver = {
 255	.name		= MOD_NAME,
 256	.probe		= imon_probe,
 257	.disconnect	= imon_disconnect,
 258	.suspend	= imon_suspend,
 259	.resume		= imon_resume,
 260	.id_table	= imon_usb_id_table,
 261};
 262
 263static struct usb_class_driver imon_vfd_class = {
 264	.name		= DEVICE_NAME,
 265	.fops		= &vfd_fops,
 266	.minor_base	= DISPLAY_MINOR_BASE,
 267};
 268
 269static struct usb_class_driver imon_lcd_class = {
 270	.name		= DEVICE_NAME,
 271	.fops		= &lcd_fops,
 272	.minor_base	= DISPLAY_MINOR_BASE,
 273};
 274
 275/* imon receiver front panel/knob key table */
 276static const struct {
 277	u64 hw_code;
 278	u32 keycode;
 279} imon_panel_key_table[] = {
 280	{ 0x000000000f00ffeell, KEY_MEDIA }, /* Go */
 281	{ 0x000000001200ffeell, KEY_UP },
 282	{ 0x000000001300ffeell, KEY_DOWN },
 283	{ 0x000000001400ffeell, KEY_LEFT },
 284	{ 0x000000001500ffeell, KEY_RIGHT },
 285	{ 0x000000001600ffeell, KEY_ENTER },
 286	{ 0x000000001700ffeell, KEY_ESC },
 287	{ 0x000000001f00ffeell, KEY_AUDIO },
 288	{ 0x000000002000ffeell, KEY_VIDEO },
 289	{ 0x000000002100ffeell, KEY_CAMERA },
 290	{ 0x000000002700ffeell, KEY_DVD },
 291	{ 0x000000002300ffeell, KEY_TV },
 292	{ 0x000000002b00ffeell, KEY_EXIT },
 293	{ 0x000000002c00ffeell, KEY_SELECT },
 294	{ 0x000000002d00ffeell, KEY_MENU },
 295	{ 0x000000000500ffeell, KEY_PREVIOUS },
 296	{ 0x000000000700ffeell, KEY_REWIND },
 297	{ 0x000000000400ffeell, KEY_STOP },
 298	{ 0x000000003c00ffeell, KEY_PLAYPAUSE },
 299	{ 0x000000000800ffeell, KEY_FASTFORWARD },
 300	{ 0x000000000600ffeell, KEY_NEXT },
 301	{ 0x000000010000ffeell, KEY_RIGHT },
 302	{ 0x000001000000ffeell, KEY_LEFT },
 303	{ 0x000000003d00ffeell, KEY_SELECT },
 304	{ 0x000100000000ffeell, KEY_VOLUMEUP },
 305	{ 0x010000000000ffeell, KEY_VOLUMEDOWN },
 306	{ 0x000000000100ffeell, KEY_MUTE },
 307	/* 0xffdc iMON MCE VFD */
 308	{ 0x00010000ffffffeell, KEY_VOLUMEUP },
 309	{ 0x01000000ffffffeell, KEY_VOLUMEDOWN },
 310	{ 0x00000001ffffffeell, KEY_MUTE },
 311	{ 0x0000000fffffffeell, KEY_MEDIA },
 312	{ 0x00000012ffffffeell, KEY_UP },
 313	{ 0x00000013ffffffeell, KEY_DOWN },
 314	{ 0x00000014ffffffeell, KEY_LEFT },
 315	{ 0x00000015ffffffeell, KEY_RIGHT },
 316	{ 0x00000016ffffffeell, KEY_ENTER },
 317	{ 0x00000017ffffffeell, KEY_ESC },
 318	/* iMON Knob values */
 319	{ 0x000100ffffffffeell, KEY_VOLUMEUP },
 320	{ 0x010000ffffffffeell, KEY_VOLUMEDOWN },
 321	{ 0x000008ffffffffeell, KEY_MUTE },
 322};
 323
 324/* to prevent races between open() and disconnect(), probing, etc */
 325static DEFINE_MUTEX(driver_lock);
 326
 327/* Module bookkeeping bits */
 328MODULE_AUTHOR(MOD_AUTHOR);
 329MODULE_DESCRIPTION(MOD_DESC);
 330MODULE_VERSION(MOD_VERSION);
 331MODULE_LICENSE("GPL");
 332MODULE_DEVICE_TABLE(usb, imon_usb_id_table);
 333
 334static bool debug;
 335module_param(debug, bool, S_IRUGO | S_IWUSR);
 336MODULE_PARM_DESC(debug, "Debug messages: 0=no, 1=yes (default: no)");
 337
 338/* lcd, vfd, vga or none? should be auto-detected, but can be overridden... */
 339static int display_type;
 340module_param(display_type, int, S_IRUGO);
 341MODULE_PARM_DESC(display_type, "Type of attached display. 0=autodetect, "
 342		 "1=vfd, 2=lcd, 3=vga, 4=none (default: autodetect)");
 343
 344static int pad_stabilize = 1;
 345module_param(pad_stabilize, int, S_IRUGO | S_IWUSR);
 346MODULE_PARM_DESC(pad_stabilize, "Apply stabilization algorithm to iMON PAD "
 347		 "presses in arrow key mode. 0=disable, 1=enable (default).");
 348
 349/*
 350 * In certain use cases, mouse mode isn't really helpful, and could actually
 351 * cause confusion, so allow disabling it when the IR device is open.
 352 */
 353static bool nomouse;
 354module_param(nomouse, bool, S_IRUGO | S_IWUSR);
 355MODULE_PARM_DESC(nomouse, "Disable mouse input device mode when IR device is "
 356		 "open. 0=don't disable, 1=disable. (default: don't disable)");
 357
 358/* threshold at which a pad push registers as an arrow key in kbd mode */
 359static int pad_thresh;
 360module_param(pad_thresh, int, S_IRUGO | S_IWUSR);
 361MODULE_PARM_DESC(pad_thresh, "Threshold at which a pad push registers as an "
 362		 "arrow key in kbd mode (default: 28)");
 363
 364
 365static void free_imon_context(struct imon_context *ictx)
 366{
 367	struct device *dev = ictx->dev;
 368
 369	usb_free_urb(ictx->tx_urb);
 370	usb_free_urb(ictx->rx_urb_intf0);
 371	usb_free_urb(ictx->rx_urb_intf1);
 372	kfree(ictx);
 373
 374	dev_dbg(dev, "%s: iMON context freed\n", __func__);
 375}
 376
 377/**
 378 * Called when the Display device (e.g. /dev/lcd0)
 379 * is opened by the application.
 380 */
 381static int display_open(struct inode *inode, struct file *file)
 382{
 383	struct usb_interface *interface;
 384	struct imon_context *ictx = NULL;
 385	int subminor;
 386	int retval = 0;
 387
 388	/* prevent races with disconnect */
 389	mutex_lock(&driver_lock);
 390
 391	subminor = iminor(inode);
 392	interface = usb_find_interface(&imon_driver, subminor);
 393	if (!interface) {
 394		pr_err("could not find interface for minor %d\n", subminor);
 395		retval = -ENODEV;
 396		goto exit;
 397	}
 398	ictx = usb_get_intfdata(interface);
 399
 400	if (!ictx) {
 401		pr_err("no context found for minor %d\n", subminor);
 402		retval = -ENODEV;
 403		goto exit;
 404	}
 405
 406	mutex_lock(&ictx->lock);
 407
 408	if (!ictx->display_supported) {
 409		pr_err("display not supported by device\n");
 410		retval = -ENODEV;
 411	} else if (ictx->display_isopen) {
 412		pr_err("display port is already open\n");
 413		retval = -EBUSY;
 414	} else {
 415		ictx->display_isopen = true;
 416		file->private_data = ictx;
 417		dev_dbg(ictx->dev, "display port opened\n");
 418	}
 419
 420	mutex_unlock(&ictx->lock);
 421
 422exit:
 423	mutex_unlock(&driver_lock);
 424	return retval;
 425}
 426
 427/**
 428 * Called when the display device (e.g. /dev/lcd0)
 429 * is closed by the application.
 430 */
 431static int display_close(struct inode *inode, struct file *file)
 432{
 433	struct imon_context *ictx = NULL;
 434	int retval = 0;
 435
 436	ictx = file->private_data;
 437
 438	if (!ictx) {
 439		pr_err("no context for device\n");
 440		return -ENODEV;
 441	}
 442
 443	mutex_lock(&ictx->lock);
 444
 445	if (!ictx->display_supported) {
 446		pr_err("display not supported by device\n");
 447		retval = -ENODEV;
 448	} else if (!ictx->display_isopen) {
 449		pr_err("display is not open\n");
 450		retval = -EIO;
 451	} else {
 452		ictx->display_isopen = false;
 453		dev_dbg(ictx->dev, "display port closed\n");
 454	}
 455
 456	mutex_unlock(&ictx->lock);
 457	return retval;
 458}
 459
 460/**
 461 * Sends a packet to the device -- this function must be called with
 462 * ictx->lock held, or its unlock/lock sequence while waiting for tx
 463 * to complete can/will lead to a deadlock.
 464 */
 465static int send_packet(struct imon_context *ictx)
 466{
 467	unsigned int pipe;
 468	unsigned long timeout;
 469	int interval = 0;
 470	int retval = 0;
 471	struct usb_ctrlrequest *control_req = NULL;
 472
 473	/* Check if we need to use control or interrupt urb */
 474	if (!ictx->tx_control) {
 475		pipe = usb_sndintpipe(ictx->usbdev_intf0,
 476				      ictx->tx_endpoint->bEndpointAddress);
 477		interval = ictx->tx_endpoint->bInterval;
 478
 479		usb_fill_int_urb(ictx->tx_urb, ictx->usbdev_intf0, pipe,
 480				 ictx->usb_tx_buf,
 481				 sizeof(ictx->usb_tx_buf),
 482				 usb_tx_callback, ictx, interval);
 483
 484		ictx->tx_urb->actual_length = 0;
 485	} else {
 486		/* fill request into kmalloc'ed space: */
 487		control_req = kmalloc(sizeof(struct usb_ctrlrequest),
 488				      GFP_KERNEL);
 489		if (control_req == NULL)
 490			return -ENOMEM;
 491
 492		/* setup packet is '21 09 0200 0001 0008' */
 493		control_req->bRequestType = 0x21;
 494		control_req->bRequest = 0x09;
 495		control_req->wValue = cpu_to_le16(0x0200);
 496		control_req->wIndex = cpu_to_le16(0x0001);
 497		control_req->wLength = cpu_to_le16(0x0008);
 498
 499		/* control pipe is endpoint 0x00 */
 500		pipe = usb_sndctrlpipe(ictx->usbdev_intf0, 0);
 501
 502		/* build the control urb */
 503		usb_fill_control_urb(ictx->tx_urb, ictx->usbdev_intf0,
 504				     pipe, (unsigned char *)control_req,
 505				     ictx->usb_tx_buf,
 506				     sizeof(ictx->usb_tx_buf),
 507				     usb_tx_callback, ictx);
 508		ictx->tx_urb->actual_length = 0;
 509	}
 510
 511	init_completion(&ictx->tx.finished);
 512	ictx->tx.busy = true;
 513	smp_rmb(); /* ensure later readers know we're busy */
 514
 515	retval = usb_submit_urb(ictx->tx_urb, GFP_KERNEL);
 516	if (retval) {
 517		ictx->tx.busy = false;
 518		smp_rmb(); /* ensure later readers know we're not busy */
 519		pr_err("error submitting urb(%d)\n", retval);
 520	} else {
 521		/* Wait for transmission to complete (or abort) */
 522		mutex_unlock(&ictx->lock);
 523		retval = wait_for_completion_interruptible(
 524				&ictx->tx.finished);
 525		if (retval)
 526			pr_err("task interrupted\n");
 527		mutex_lock(&ictx->lock);
 528
 529		retval = ictx->tx.status;
 530		if (retval)
 531			pr_err("packet tx failed (%d)\n", retval);
 532	}
 533
 534	kfree(control_req);
 535
 536	/*
 537	 * Induce a mandatory 5ms delay before returning, as otherwise,
 538	 * send_packet can get called so rapidly as to overwhelm the device,
 539	 * particularly on faster systems and/or those with quirky usb.
 540	 */
 541	timeout = msecs_to_jiffies(5);
 542	set_current_state(TASK_UNINTERRUPTIBLE);
 543	schedule_timeout(timeout);
 544
 545	return retval;
 546}
 547
 548/**
 549 * Sends an associate packet to the iMON 2.4G.
 550 *
 551 * This might not be such a good idea, since it has an id collision with
 552 * some versions of the "IR & VFD" combo. The only way to determine if it
 553 * is an RF version is to look at the product description string. (Which
 554 * we currently do not fetch).
 555 */
 556static int send_associate_24g(struct imon_context *ictx)
 557{
 558	int retval;
 559	const unsigned char packet[8] = { 0x01, 0x00, 0x00, 0x00,
 560					  0x00, 0x00, 0x00, 0x20 };
 561
 562	if (!ictx) {
 563		pr_err("no context for device\n");
 564		return -ENODEV;
 565	}
 566
 567	if (!ictx->dev_present_intf0) {
 568		pr_err("no iMON device present\n");
 569		return -ENODEV;
 570	}
 571
 572	memcpy(ictx->usb_tx_buf, packet, sizeof(packet));
 573	retval = send_packet(ictx);
 574
 575	return retval;
 576}
 577
 578/**
 579 * Sends packets to setup and show clock on iMON display
 580 *
 581 * Arguments: year - last 2 digits of year, month - 1..12,
 582 * day - 1..31, dow - day of the week (0-Sun...6-Sat),
 583 * hour - 0..23, minute - 0..59, second - 0..59
 584 */
 585static int send_set_imon_clock(struct imon_context *ictx,
 586			       unsigned int year, unsigned int month,
 587			       unsigned int day, unsigned int dow,
 588			       unsigned int hour, unsigned int minute,
 589			       unsigned int second)
 590{
 591	unsigned char clock_enable_pkt[IMON_CLOCK_ENABLE_PACKETS][8];
 592	int retval = 0;
 593	int i;
 594
 595	if (!ictx) {
 596		pr_err("no context for device\n");
 597		return -ENODEV;
 598	}
 599
 600	switch (ictx->display_type) {
 601	case IMON_DISPLAY_TYPE_LCD:
 602		clock_enable_pkt[0][0] = 0x80;
 603		clock_enable_pkt[0][1] = year;
 604		clock_enable_pkt[0][2] = month-1;
 605		clock_enable_pkt[0][3] = day;
 606		clock_enable_pkt[0][4] = hour;
 607		clock_enable_pkt[0][5] = minute;
 608		clock_enable_pkt[0][6] = second;
 609
 610		clock_enable_pkt[1][0] = 0x80;
 611		clock_enable_pkt[1][1] = 0;
 612		clock_enable_pkt[1][2] = 0;
 613		clock_enable_pkt[1][3] = 0;
 614		clock_enable_pkt[1][4] = 0;
 615		clock_enable_pkt[1][5] = 0;
 616		clock_enable_pkt[1][6] = 0;
 617
 618		if (ictx->product == 0xffdc) {
 619			clock_enable_pkt[0][7] = 0x50;
 620			clock_enable_pkt[1][7] = 0x51;
 621		} else {
 622			clock_enable_pkt[0][7] = 0x88;
 623			clock_enable_pkt[1][7] = 0x8a;
 624		}
 625
 626		break;
 627
 628	case IMON_DISPLAY_TYPE_VFD:
 629		clock_enable_pkt[0][0] = year;
 630		clock_enable_pkt[0][1] = month-1;
 631		clock_enable_pkt[0][2] = day;
 632		clock_enable_pkt[0][3] = dow;
 633		clock_enable_pkt[0][4] = hour;
 634		clock_enable_pkt[0][5] = minute;
 635		clock_enable_pkt[0][6] = second;
 636		clock_enable_pkt[0][7] = 0x40;
 637
 638		clock_enable_pkt[1][0] = 0;
 639		clock_enable_pkt[1][1] = 0;
 640		clock_enable_pkt[1][2] = 1;
 641		clock_enable_pkt[1][3] = 0;
 642		clock_enable_pkt[1][4] = 0;
 643		clock_enable_pkt[1][5] = 0;
 644		clock_enable_pkt[1][6] = 0;
 645		clock_enable_pkt[1][7] = 0x42;
 646
 647		break;
 648
 649	default:
 650		return -ENODEV;
 651	}
 652
 653	for (i = 0; i < IMON_CLOCK_ENABLE_PACKETS; i++) {
 654		memcpy(ictx->usb_tx_buf, clock_enable_pkt[i], 8);
 655		retval = send_packet(ictx);
 656		if (retval) {
 657			pr_err("send_packet failed for packet %d\n", i);
 658			break;
 659		}
 660	}
 661
 662	return retval;
 663}
 664
 665/**
 666 * These are the sysfs functions to handle the association on the iMON 2.4G LT.
 667 */
 668static ssize_t show_associate_remote(struct device *d,
 669				     struct device_attribute *attr,
 670				     char *buf)
 671{
 672	struct imon_context *ictx = dev_get_drvdata(d);
 673
 674	if (!ictx)
 675		return -ENODEV;
 676
 677	mutex_lock(&ictx->lock);
 678	if (ictx->rf_isassociating)
 679		strcpy(buf, "associating\n");
 680	else
 681		strcpy(buf, "closed\n");
 682
 683	dev_info(d, "Visit http://www.lirc.org/html/imon-24g.html for "
 684		 "instructions on how to associate your iMON 2.4G DT/LT "
 685		 "remote\n");
 686	mutex_unlock(&ictx->lock);
 687	return strlen(buf);
 688}
 689
 690static ssize_t store_associate_remote(struct device *d,
 691				      struct device_attribute *attr,
 692				      const char *buf, size_t count)
 693{
 694	struct imon_context *ictx;
 695
 696	ictx = dev_get_drvdata(d);
 697
 698	if (!ictx)
 699		return -ENODEV;
 700
 701	mutex_lock(&ictx->lock);
 702	ictx->rf_isassociating = true;
 703	send_associate_24g(ictx);
 704	mutex_unlock(&ictx->lock);
 705
 706	return count;
 707}
 708
 709/**
 710 * sysfs functions to control internal imon clock
 711 */
 712static ssize_t show_imon_clock(struct device *d,
 713			       struct device_attribute *attr, char *buf)
 714{
 715	struct imon_context *ictx = dev_get_drvdata(d);
 716	size_t len;
 717
 718	if (!ictx)
 719		return -ENODEV;
 720
 721	mutex_lock(&ictx->lock);
 722
 723	if (!ictx->display_supported) {
 724		len = snprintf(buf, PAGE_SIZE, "Not supported.");
 725	} else {
 726		len = snprintf(buf, PAGE_SIZE,
 727			"To set the clock on your iMON display:\n"
 728			"# date \"+%%y %%m %%d %%w %%H %%M %%S\" > imon_clock\n"
 729			"%s", ictx->display_isopen ?
 730			"\nNOTE: imon device must be closed\n" : "");
 731	}
 732
 733	mutex_unlock(&ictx->lock);
 734
 735	return len;
 736}
 737
 738static ssize_t store_imon_clock(struct device *d,
 739				struct device_attribute *attr,
 740				const char *buf, size_t count)
 741{
 742	struct imon_context *ictx = dev_get_drvdata(d);
 743	ssize_t retval;
 744	unsigned int year, month, day, dow, hour, minute, second;
 745
 746	if (!ictx)
 747		return -ENODEV;
 748
 749	mutex_lock(&ictx->lock);
 750
 751	if (!ictx->display_supported) {
 752		retval = -ENODEV;
 753		goto exit;
 754	} else if (ictx->display_isopen) {
 755		retval = -EBUSY;
 756		goto exit;
 757	}
 758
 759	if (sscanf(buf, "%u %u %u %u %u %u %u",	&year, &month, &day, &dow,
 760		   &hour, &minute, &second) != 7) {
 761		retval = -EINVAL;
 762		goto exit;
 763	}
 764
 765	if ((month < 1 || month > 12) ||
 766	    (day < 1 || day > 31) || (dow > 6) ||
 767	    (hour > 23) || (minute > 59) || (second > 59)) {
 768		retval = -EINVAL;
 769		goto exit;
 770	}
 771
 772	retval = send_set_imon_clock(ictx, year, month, day, dow,
 773				     hour, minute, second);
 774	if (retval)
 775		goto exit;
 776
 777	retval = count;
 778exit:
 779	mutex_unlock(&ictx->lock);
 780
 781	return retval;
 782}
 783
 784
 785static DEVICE_ATTR(imon_clock, S_IWUSR | S_IRUGO, show_imon_clock,
 786		   store_imon_clock);
 787
 788static DEVICE_ATTR(associate_remote, S_IWUSR | S_IRUGO, show_associate_remote,
 789		   store_associate_remote);
 790
 791static struct attribute *imon_display_sysfs_entries[] = {
 792	&dev_attr_imon_clock.attr,
 793	NULL
 794};
 795
 796static struct attribute_group imon_display_attr_group = {
 797	.attrs = imon_display_sysfs_entries
 798};
 799
 800static struct attribute *imon_rf_sysfs_entries[] = {
 801	&dev_attr_associate_remote.attr,
 802	NULL
 803};
 804
 805static struct attribute_group imon_rf_attr_group = {
 806	.attrs = imon_rf_sysfs_entries
 807};
 808
 809/**
 810 * Writes data to the VFD.  The iMON VFD is 2x16 characters
 811 * and requires data in 5 consecutive USB interrupt packets,
 812 * each packet but the last carrying 7 bytes.
 813 *
 814 * I don't know if the VFD board supports features such as
 815 * scrolling, clearing rows, blanking, etc. so at
 816 * the caller must provide a full screen of data.  If fewer
 817 * than 32 bytes are provided spaces will be appended to
 818 * generate a full screen.
 819 */
 820static ssize_t vfd_write(struct file *file, const char *buf,
 821			 size_t n_bytes, loff_t *pos)
 822{
 823	int i;
 824	int offset;
 825	int seq;
 826	int retval = 0;
 827	struct imon_context *ictx;
 828	const unsigned char vfd_packet6[] = {
 829		0x01, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF };
 830
 831	ictx = file->private_data;
 832	if (!ictx) {
 833		pr_err("no context for device\n");
 834		return -ENODEV;
 835	}
 836
 837	mutex_lock(&ictx->lock);
 838
 839	if (!ictx->dev_present_intf0) {
 840		pr_err("no iMON device present\n");
 841		retval = -ENODEV;
 842		goto exit;
 843	}
 844
 845	if (n_bytes <= 0 || n_bytes > 32) {
 846		pr_err("invalid payload size\n");
 847		retval = -EINVAL;
 848		goto exit;
 849	}
 850
 851	if (copy_from_user(ictx->tx.data_buf, buf, n_bytes)) {
 852		retval = -EFAULT;
 853		goto exit;
 854	}
 855
 856	/* Pad with spaces */
 857	for (i = n_bytes; i < 32; ++i)
 858		ictx->tx.data_buf[i] = ' ';
 859
 860	for (i = 32; i < 35; ++i)
 861		ictx->tx.data_buf[i] = 0xFF;
 862
 863	offset = 0;
 864	seq = 0;
 865
 866	do {
 867		memcpy(ictx->usb_tx_buf, ictx->tx.data_buf + offset, 7);
 868		ictx->usb_tx_buf[7] = (unsigned char) seq;
 869
 870		retval = send_packet(ictx);
 871		if (retval) {
 872			pr_err("send packet failed for packet #%d\n", seq / 2);
 873			goto exit;
 874		} else {
 875			seq += 2;
 876			offset += 7;
 877		}
 878
 879	} while (offset < 35);
 880
 881	/* Send packet #6 */
 882	memcpy(ictx->usb_tx_buf, &vfd_packet6, sizeof(vfd_packet6));
 883	ictx->usb_tx_buf[7] = (unsigned char) seq;
 884	retval = send_packet(ictx);
 885	if (retval)
 886		pr_err("send packet failed for packet #%d\n", seq / 2);
 887
 888exit:
 889	mutex_unlock(&ictx->lock);
 890
 891	return (!retval) ? n_bytes : retval;
 892}
 893
 894/**
 895 * Writes data to the LCD.  The iMON OEM LCD screen expects 8-byte
 896 * packets. We accept data as 16 hexadecimal digits, followed by a
 897 * newline (to make it easy to drive the device from a command-line
 898 * -- even though the actual binary data is a bit complicated).
 899 *
 900 * The device itself is not a "traditional" text-mode display. It's
 901 * actually a 16x96 pixel bitmap display. That means if you want to
 902 * display text, you've got to have your own "font" and translate the
 903 * text into bitmaps for display. This is really flexible (you can
 904 * display whatever diacritics you need, and so on), but it's also
 905 * a lot more complicated than most LCDs...
 906 */
 907static ssize_t lcd_write(struct file *file, const char *buf,
 908			 size_t n_bytes, loff_t *pos)
 909{
 910	int retval = 0;
 911	struct imon_context *ictx;
 912
 913	ictx = file->private_data;
 914	if (!ictx) {
 915		pr_err("no context for device\n");
 916		return -ENODEV;
 917	}
 918
 919	mutex_lock(&ictx->lock);
 920
 921	if (!ictx->display_supported) {
 922		pr_err("no iMON display present\n");
 923		retval = -ENODEV;
 924		goto exit;
 925	}
 926
 927	if (n_bytes != 8) {
 928		pr_err("invalid payload size: %d (expected 8)\n", (int)n_bytes);
 929		retval = -EINVAL;
 930		goto exit;
 931	}
 932
 933	if (copy_from_user(ictx->usb_tx_buf, buf, 8)) {
 934		retval = -EFAULT;
 935		goto exit;
 936	}
 937
 938	retval = send_packet(ictx);
 939	if (retval) {
 940		pr_err("send packet failed!\n");
 941		goto exit;
 942	} else {
 943		dev_dbg(ictx->dev, "%s: write %d bytes to LCD\n",
 944			__func__, (int) n_bytes);
 945	}
 946exit:
 947	mutex_unlock(&ictx->lock);
 948	return (!retval) ? n_bytes : retval;
 949}
 950
 951/**
 952 * Callback function for USB core API: transmit data
 953 */
 954static void usb_tx_callback(struct urb *urb)
 955{
 956	struct imon_context *ictx;
 957
 958	if (!urb)
 959		return;
 960	ictx = (struct imon_context *)urb->context;
 961	if (!ictx)
 962		return;
 963
 964	ictx->tx.status = urb->status;
 965
 966	/* notify waiters that write has finished */
 967	ictx->tx.busy = false;
 968	smp_rmb(); /* ensure later readers know we're not busy */
 969	complete(&ictx->tx.finished);
 970}
 971
 972/**
 973 * report touchscreen input
 974 */
 975static void imon_touch_display_timeout(unsigned long data)
 976{
 977	struct imon_context *ictx = (struct imon_context *)data;
 978
 979	if (ictx->display_type != IMON_DISPLAY_TYPE_VGA)
 980		return;
 981
 982	input_report_abs(ictx->touch, ABS_X, ictx->touch_x);
 983	input_report_abs(ictx->touch, ABS_Y, ictx->touch_y);
 984	input_report_key(ictx->touch, BTN_TOUCH, 0x00);
 985	input_sync(ictx->touch);
 986}
 987
 988/**
 989 * iMON IR receivers support two different signal sets -- those used by
 990 * the iMON remotes, and those used by the Windows MCE remotes (which is
 991 * really just RC-6), but only one or the other at a time, as the signals
 992 * are decoded onboard the receiver.
 993 *
 994 * This function gets called two different ways, one way is from
 995 * rc_register_device, for initial protocol selection/setup, and the other is
 996 * via a userspace-initiated protocol change request, either by direct sysfs
 997 * prodding or by something like ir-keytable. In the rc_register_device case,
 998 * the imon context lock is already held, but when initiated from userspace,
 999 * it is not, so we must acquire it prior to calling send_packet, which
1000 * requires that the lock is held.
1001 */
1002static int imon_ir_change_protocol(struct rc_dev *rc, u64 rc_type)
1003{
1004	int retval;
1005	struct imon_context *ictx = rc->priv;
1006	struct device *dev = ictx->dev;
1007	bool unlock = false;
1008	unsigned char ir_proto_packet[] = {
1009		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86 };
1010
1011	if (rc_type && !(rc_type & rc->allowed_protos))
1012		dev_warn(dev, "Looks like you're trying to use an IR protocol "
1013			 "this device does not support\n");
1014
1015	switch (rc_type) {
1016	case RC_TYPE_RC6:
1017		dev_dbg(dev, "Configuring IR receiver for MCE protocol\n");
1018		ir_proto_packet[0] = 0x01;
1019		break;
1020	case RC_TYPE_UNKNOWN:
1021	case RC_TYPE_OTHER:
1022		dev_dbg(dev, "Configuring IR receiver for iMON protocol\n");
1023		if (!pad_stabilize)
1024			dev_dbg(dev, "PAD stabilize functionality disabled\n");
1025		/* ir_proto_packet[0] = 0x00; // already the default */
1026		rc_type = RC_TYPE_OTHER;
1027		break;
1028	default:
1029		dev_warn(dev, "Unsupported IR protocol specified, overriding "
1030			 "to iMON IR protocol\n");
1031		if (!pad_stabilize)
1032			dev_dbg(dev, "PAD stabilize functionality disabled\n");
1033		/* ir_proto_packet[0] = 0x00; // already the default */
1034		rc_type = RC_TYPE_OTHER;
1035		break;
1036	}
1037
1038	memcpy(ictx->usb_tx_buf, &ir_proto_packet, sizeof(ir_proto_packet));
1039
1040	if (!mutex_is_locked(&ictx->lock)) {
1041		unlock = true;
1042		mutex_lock(&ictx->lock);
1043	}
1044
1045	retval = send_packet(ictx);
1046	if (retval)
1047		goto out;
1048
1049	ictx->rc_type = rc_type;
1050	ictx->pad_mouse = false;
1051
1052out:
1053	if (unlock)
1054		mutex_unlock(&ictx->lock);
1055
1056	return retval;
1057}
1058
1059static inline int tv2int(const struct timeval *a, const struct timeval *b)
1060{
1061	int usecs = 0;
1062	int sec   = 0;
1063
1064	if (b->tv_usec > a->tv_usec) {
1065		usecs = 1000000;
1066		sec--;
1067	}
1068
1069	usecs += a->tv_usec - b->tv_usec;
1070
1071	sec += a->tv_sec - b->tv_sec;
1072	sec *= 1000;
1073	usecs /= 1000;
1074	sec += usecs;
1075
1076	if (sec < 0)
1077		sec = 1000;
1078
1079	return sec;
1080}
1081
1082/**
1083 * The directional pad behaves a bit differently, depending on whether this is
1084 * one of the older ffdc devices or a newer device. Newer devices appear to
1085 * have a higher resolution matrix for more precise mouse movement, but it
1086 * makes things overly sensitive in keyboard mode, so we do some interesting
1087 * contortions to make it less touchy. Older devices run through the same
1088 * routine with shorter timeout and a smaller threshold.
1089 */
1090static int stabilize(int a, int b, u16 timeout, u16 threshold)
1091{
1092	struct timeval ct;
1093	static struct timeval prev_time = {0, 0};
1094	static struct timeval hit_time  = {0, 0};
1095	static int x, y, prev_result, hits;
1096	int result = 0;
1097	int msec, msec_hit;
1098
1099	do_gettimeofday(&ct);
1100	msec = tv2int(&ct, &prev_time);
1101	msec_hit = tv2int(&ct, &hit_time);
1102
1103	if (msec > 100) {
1104		x = 0;
1105		y = 0;
1106		hits = 0;
1107	}
1108
1109	x += a;
1110	y += b;
1111
1112	prev_time = ct;
1113
1114	if (abs(x) > threshold || abs(y) > threshold) {
1115		if (abs(y) > abs(x))
1116			result = (y > 0) ? 0x7F : 0x80;
1117		else
1118			result = (x > 0) ? 0x7F00 : 0x8000;
1119
1120		x = 0;
1121		y = 0;
1122
1123		if (result == prev_result) {
1124			hits++;
1125
1126			if (hits > 3) {
1127				switch (result) {
1128				case 0x7F:
1129					y = 17 * threshold / 30;
1130					break;
1131				case 0x80:
1132					y -= 17 * threshold / 30;
1133					break;
1134				case 0x7F00:
1135					x = 17 * threshold / 30;
1136					break;
1137				case 0x8000:
1138					x -= 17 * threshold / 30;
1139					break;
1140				}
1141			}
1142
1143			if (hits == 2 && msec_hit < timeout) {
1144				result = 0;
1145				hits = 1;
1146			}
1147		} else {
1148			prev_result = result;
1149			hits = 1;
1150			hit_time = ct;
1151		}
1152	}
1153
1154	return result;
1155}
1156
1157static u32 imon_remote_key_lookup(struct imon_context *ictx, u32 scancode)
1158{
1159	u32 keycode;
1160	u32 release;
1161	bool is_release_code = false;
1162
1163	/* Look for the initial press of a button */
1164	keycode = rc_g_keycode_from_table(ictx->rdev, scancode);
1165	ictx->rc_toggle = 0x0;
1166	ictx->rc_scancode = scancode;
1167
1168	/* Look for the release of a button */
1169	if (keycode == KEY_RESERVED) {
1170		release = scancode & ~0x4000;
1171		keycode = rc_g_keycode_from_table(ictx->rdev, release);
1172		if (keycode != KEY_RESERVED)
1173			is_release_code = true;
1174	}
1175
1176	ictx->release_code = is_release_code;
1177
1178	return keycode;
1179}
1180
1181static u32 imon_mce_key_lookup(struct imon_context *ictx, u32 scancode)
1182{
1183	u32 keycode;
1184
1185#define MCE_KEY_MASK 0x7000
1186#define MCE_TOGGLE_BIT 0x8000
1187
1188	/*
1189	 * On some receivers, mce keys decode to 0x8000f04xx and 0x8000f84xx
1190	 * (the toggle bit flipping between alternating key presses), while
1191	 * on other receivers, we see 0x8000f74xx and 0x8000ff4xx. To keep
1192	 * the table trim, we always or in the bits to look up 0x8000ff4xx,
1193	 * but we can't or them into all codes, as some keys are decoded in
1194	 * a different way w/o the same use of the toggle bit...
1195	 */
1196	if (scancode & 0x80000000)
1197		scancode = scancode | MCE_KEY_MASK | MCE_TOGGLE_BIT;
1198
1199	ictx->rc_scancode = scancode;
1200	keycode = rc_g_keycode_from_table(ictx->rdev, scancode);
1201
1202	/* not used in mce mode, but make sure we know its false */
1203	ictx->release_code = false;
1204
1205	return keycode;
1206}
1207
1208static u32 imon_panel_key_lookup(u64 code)
1209{
1210	int i;
1211	u32 keycode = KEY_RESERVED;
1212
1213	for (i = 0; i < ARRAY_SIZE(imon_panel_key_table); i++) {
1214		if (imon_panel_key_table[i].hw_code == (code | 0xffee)) {
1215			keycode = imon_panel_key_table[i].keycode;
1216			break;
1217		}
1218	}
1219
1220	return keycode;
1221}
1222
1223static bool imon_mouse_event(struct imon_context *ictx,
1224			     unsigned char *buf, int len)
1225{
1226	char rel_x = 0x00, rel_y = 0x00;
1227	u8 right_shift = 1;
1228	bool mouse_input = true;
1229	int dir = 0;
1230	unsigned long flags;
1231
1232	spin_lock_irqsave(&ictx->kc_lock, flags);
1233
1234	/* newer iMON device PAD or mouse button */
1235	if (ictx->product != 0xffdc && (buf[0] & 0x01) && len == 5) {
1236		rel_x = buf[2];
1237		rel_y = buf[3];
1238		right_shift = 1;
1239	/* 0xffdc iMON PAD or mouse button input */
1240	} else if (ictx->product == 0xffdc && (buf[0] & 0x40) &&
1241			!((buf[1] & 0x01) || ((buf[1] >> 2) & 0x01))) {
1242		rel_x = (buf[1] & 0x08) | (buf[1] & 0x10) >> 2 |
1243			(buf[1] & 0x20) >> 4 | (buf[1] & 0x40) >> 6;
1244		if (buf[0] & 0x02)
1245			rel_x |= ~0x0f;
1246		rel_x = rel_x + rel_x / 2;
1247		rel_y = (buf[2] & 0x08) | (buf[2] & 0x10) >> 2 |
1248			(buf[2] & 0x20) >> 4 | (buf[2] & 0x40) >> 6;
1249		if (buf[0] & 0x01)
1250			rel_y |= ~0x0f;
1251		rel_y = rel_y + rel_y / 2;
1252		right_shift = 2;
1253	/* some ffdc devices decode mouse buttons differently... */
1254	} else if (ictx->product == 0xffdc && (buf[0] == 0x68)) {
1255		right_shift = 2;
1256	/* ch+/- buttons, which we use for an emulated scroll wheel */
1257	} else if (ictx->kc == KEY_CHANNELUP && (buf[2] & 0x40) != 0x40) {
1258		dir = 1;
1259	} else if (ictx->kc == KEY_CHANNELDOWN && (buf[2] & 0x40) != 0x40) {
1260		dir = -1;
1261	} else
1262		mouse_input = false;
1263
1264	spin_unlock_irqrestore(&ictx->kc_lock, flags);
1265
1266	if (mouse_input) {
1267		dev_dbg(ictx->dev, "sending mouse data via input subsystem\n");
1268
1269		if (dir) {
1270			input_report_rel(ictx->idev, REL_WHEEL, dir);
1271		} else if (rel_x || rel_y) {
1272			input_report_rel(ictx->idev, REL_X, rel_x);
1273			input_report_rel(ictx->idev, REL_Y, rel_y);
1274		} else {
1275			input_report_key(ictx->idev, BTN_LEFT, buf[1] & 0x1);
1276			input_report_key(ictx->idev, BTN_RIGHT,
1277					 buf[1] >> right_shift & 0x1);
1278		}
1279		input_sync(ictx->idev);
1280		spin_lock_irqsave(&ictx->kc_lock, flags);
1281		ictx->last_keycode = ictx->kc;
1282		spin_unlock_irqrestore(&ictx->kc_lock, flags);
1283	}
1284
1285	return mouse_input;
1286}
1287
1288static void imon_touch_event(struct imon_context *ictx, unsigned char *buf)
1289{
1290	mod_timer(&ictx->ttimer, jiffies + TOUCH_TIMEOUT);
1291	ictx->touch_x = (buf[0] << 4) | (buf[1] >> 4);
1292	ictx->touch_y = 0xfff - ((buf[2] << 4) | (buf[1] & 0xf));
1293	input_report_abs(ictx->touch, ABS_X, ictx->touch_x);
1294	input_report_abs(ictx->touch, ABS_Y, ictx->touch_y);
1295	input_report_key(ictx->touch, BTN_TOUCH, 0x01);
1296	input_sync(ictx->touch);
1297}
1298
1299static void imon_pad_to_keys(struct imon_context *ictx, unsigned char *buf)
1300{
1301	int dir = 0;
1302	char rel_x = 0x00, rel_y = 0x00;
1303	u16 timeout, threshold;
1304	u32 scancode = KEY_RESERVED;
1305	unsigned long flags;
1306
1307	/*
1308	 * The imon directional pad functions more like a touchpad. Bytes 3 & 4
1309	 * contain a position coordinate (x,y), with each component ranging
1310	 * from -14 to 14. We want to down-sample this to only 4 discrete values
1311	 * for up/down/left/right arrow keys. Also, when you get too close to
1312	 * diagonals, it has a tendency to jump back and forth, so lets try to
1313	 * ignore when they get too close.
1314	 */
1315	if (ictx->product != 0xffdc) {
1316		/* first, pad to 8 bytes so it conforms with everything else */
1317		buf[5] = buf[6] = buf[7] = 0;
1318		timeout = 500;	/* in msecs */
1319		/* (2*threshold) x (2*threshold) square */
1320		threshold = pad_thresh ? pad_thresh : 28;
1321		rel_x = buf[2];
1322		rel_y = buf[3];
1323
1324		if (ictx->rc_type == RC_TYPE_OTHER && pad_stabilize) {
1325			if ((buf[1] == 0) && ((rel_x != 0) || (rel_y != 0))) {
1326				dir = stabilize((int)rel_x, (int)rel_y,
1327						timeout, threshold);
1328				if (!dir) {
1329					spin_lock_irqsave(&ictx->kc_lock,
1330							  flags);
1331					ictx->kc = KEY_UNKNOWN;
1332					spin_unlock_irqrestore(&ictx->kc_lock,
1333							       flags);
1334					return;
1335				}
1336				buf[2] = dir & 0xFF;
1337				buf[3] = (dir >> 8) & 0xFF;
1338				scancode = be32_to_cpu(*((u32 *)buf));
1339			}
1340		} else {
1341			/*
1342			 * Hack alert: instead of using keycodes, we have
1343			 * to use hard-coded scancodes here...
1344			 */
1345			if (abs(rel_y) > abs(rel_x)) {
1346				buf[2] = (rel_y > 0) ? 0x7F : 0x80;
1347				buf[3] = 0;
1348				if (rel_y > 0)
1349					scancode = 0x01007f00; /* KEY_DOWN */
1350				else
1351					scancode = 0x01008000; /* KEY_UP */
1352			} else {
1353				buf[2] = 0;
1354				buf[3] = (rel_x > 0) ? 0x7F : 0x80;
1355				if (rel_x > 0)
1356					scancode = 0x0100007f; /* KEY_RIGHT */
1357				else
1358					scancode = 0x01000080; /* KEY_LEFT */
1359			}
1360		}
1361
1362	/*
1363	 * Handle on-board decoded pad events for e.g. older VFD/iMON-Pad
1364	 * device (15c2:ffdc). The remote generates various codes from
1365	 * 0x68nnnnB7 to 0x6AnnnnB7, the left mouse button generates
1366	 * 0x688301b7 and the right one 0x688481b7. All other keys generate
1367	 * 0x2nnnnnnn. Position coordinate is encoded in buf[1] and buf[2] with
1368	 * reversed endianess. Extract direction from buffer, rotate endianess,
1369	 * adjust sign and feed the values into stabilize(). The resulting codes
1370	 * will be 0x01008000, 0x01007F00, which match the newer devices.
1371	 */
1372	} else {
1373		timeout = 10;	/* in msecs */
1374		/* (2*threshold) x (2*threshold) square */
1375		threshold = pad_thresh ? pad_thresh : 15;
1376
1377		/* buf[1] is x */
1378		rel_x = (buf[1] & 0x08) | (buf[1] & 0x10) >> 2 |
1379			(buf[1] & 0x20) >> 4 | (buf[1] & 0x40) >> 6;
1380		if (buf[0] & 0x02)
1381			rel_x |= ~0x10+1;
1382		/* buf[2] is y */
1383		rel_y = (buf[2] & 0x08) | (buf[2] & 0x10) >> 2 |
1384			(buf[2] & 0x20) >> 4 | (buf[2] & 0x40) >> 6;
1385		if (buf[0] & 0x01)
1386			rel_y |= ~0x10+1;
1387
1388		buf[0] = 0x01;
1389		buf[1] = buf[4] = buf[5] = buf[6] = buf[7] = 0;
1390
1391		if (ictx->rc_type == RC_TYPE_OTHER && pad_stabilize) {
1392			dir = stabilize((int)rel_x, (int)rel_y,
1393					timeout, threshold);
1394			if (!dir) {
1395				spin_lock_irqsave(&ictx->kc_lock, flags);
1396				ictx->kc = KEY_UNKNOWN;
1397				spin_unlock_irqrestore(&ictx->kc_lock, flags);
1398				return;
1399			}
1400			buf[2] = dir & 0xFF;
1401			buf[3] = (dir >> 8) & 0xFF;
1402			scancode = be32_to_cpu(*((u32 *)buf));
1403		} else {
1404			/*
1405			 * Hack alert: instead of using keycodes, we have
1406			 * to use hard-coded scancodes here...
1407			 */
1408			if (abs(rel_y) > abs(rel_x)) {
1409				buf[2] = (rel_y > 0) ? 0x7F : 0x80;
1410				buf[3] = 0;
1411				if (rel_y > 0)
1412					scancode = 0x01007f00; /* KEY_DOWN */
1413				else
1414					scancode = 0x01008000; /* KEY_UP */
1415			} else {
1416				buf[2] = 0;
1417				buf[3] = (rel_x > 0) ? 0x7F : 0x80;
1418				if (rel_x > 0)
1419					scancode = 0x0100007f; /* KEY_RIGHT */
1420				else
1421					scancode = 0x01000080; /* KEY_LEFT */
1422			}
1423		}
1424	}
1425
1426	if (scancode) {
1427		spin_lock_irqsave(&ictx->kc_lock, flags);
1428		ictx->kc = imon_remote_key_lookup(ictx, scancode);
1429		spin_unlock_irqrestore(&ictx->kc_lock, flags);
1430	}
1431}
1432
1433/**
1434 * figure out if these is a press or a release. We don't actually
1435 * care about repeats, as those will be auto-generated within the IR
1436 * subsystem for repeating scancodes.
1437 */
1438static int imon_parse_press_type(struct imon_context *ictx,
1439				 unsigned char *buf, u8 ktype)
1440{
1441	int press_type = 0;
1442	unsigned long flags;
1443
1444	spin_lock_irqsave(&ictx->kc_lock, flags);
1445
1446	/* key release of 0x02XXXXXX key */
1447	if (ictx->kc == KEY_RESERVED && buf[0] == 0x02 && buf[3] == 0x00)
1448		ictx->kc = ictx->last_keycode;
1449
1450	/* mouse button release on (some) 0xffdc devices */
1451	else if (ictx->kc == KEY_RESERVED && buf[0] == 0x68 && buf[1] == 0x82 &&
1452		 buf[2] == 0x81 && buf[3] == 0xb7)
1453		ictx->kc = ictx->last_keycode;
1454
1455	/* mouse button release on (some other) 0xffdc devices */
1456	else if (ictx->kc == KEY_RESERVED && buf[0] == 0x01 && buf[1] == 0x00 &&
1457		 buf[2] == 0x81 && buf[3] == 0xb7)
1458		ictx->kc = ictx->last_keycode;
1459
1460	/* mce-specific button handling, no keyup events */
1461	else if (ktype == IMON_KEY_MCE) {
1462		ictx->rc_toggle = buf[2];
1463		press_type = 1;
1464
1465	/* incoherent or irrelevant data */
1466	} else if (ictx->kc == KEY_RESERVED)
1467		press_type = -EINVAL;
1468
1469	/* key release of 0xXXXXXXb7 key */
1470	else if (ictx->release_code)
1471		press_type = 0;
1472
1473	/* this is a button press */
1474	else
1475		press_type = 1;
1476
1477	spin_unlock_irqrestore(&ictx->kc_lock, flags);
1478
1479	return press_type;
1480}
1481
1482/**
1483 * Process the incoming packet
1484 */
1485static void imon_incoming_packet(struct imon_context *ictx,
1486				 struct urb *urb, int intf)
1487{
1488	int len = urb->actual_length;
1489	unsigned char *buf = urb->transfer_buffer;
1490	struct device *dev = ictx->dev;
1491	unsigned long flags;
1492	u32 kc;
1493	int i;
1494	u64 scancode;
1495	int press_type = 0;
1496	int msec;
1497	struct timeval t;
1498	static struct timeval prev_time = { 0, 0 };
1499	u8 ktype;
1500
1501	/* filter out junk data on the older 0xffdc imon devices */
1502	if ((buf[0] == 0xff) && (buf[1] == 0xff) && (buf[2] == 0xff))
1503		return;
1504
1505	/* Figure out what key was pressed */
1506	if (len == 8 && buf[7] == 0xee) {
1507		scancode = be64_to_cpu(*((u64 *)buf));
1508		ktype = IMON_KEY_PANEL;
1509		kc = imon_panel_key_lookup(scancode);
1510	} else {
1511		scancode = be32_to_cpu(*((u32 *)buf));
1512		if (ictx->rc_type == RC_TYPE_RC6) {
1513			ktype = IMON_KEY_IMON;
1514			if (buf[0] == 0x80)
1515				ktype = IMON_KEY_MCE;
1516			kc = imon_mce_key_lookup(ictx, scancode);
1517		} else {
1518			ktype = IMON_KEY_IMON;
1519			kc = imon_remote_key_lookup(ictx, scancode);
1520		}
1521	}
1522
1523	spin_lock_irqsave(&ictx->kc_lock, flags);
1524	/* keyboard/mouse mode toggle button */
1525	if (kc == KEY_KEYBOARD && !ictx->release_code) {
1526		ictx->last_keycode = kc;
1527		if (!nomouse) {
1528			ictx->pad_mouse = ~(ictx->pad_mouse) & 0x1;
1529			dev_dbg(dev, "toggling to %s mode\n",
1530				ictx->pad_mouse ? "mouse" : "keyboard");
1531			spin_unlock_irqrestore(&ictx->kc_lock, flags);
1532			return;
1533		} else {
1534			ictx->pad_mouse = false;
1535			dev_dbg(dev, "mouse mode disabled, passing key value\n");
1536		}
1537	}
1538
1539	ictx->kc = kc;
1540	spin_unlock_irqrestore(&ictx->kc_lock, flags);
1541
1542	/* send touchscreen events through input subsystem if touchpad data */
1543	if (ictx->display_type == IMON_DISPLAY_TYPE_VGA && len == 8 &&
1544	    buf[7] == 0x86) {
1545		imon_touch_event(ictx, buf);
1546		return;
1547
1548	/* look for mouse events with pad in mouse mode */
1549	} else if (ictx->pad_mouse) {
1550		if (imon_mouse_event(ictx, buf, len))
1551			return;
1552	}
1553
1554	/* Now for some special handling to convert pad input to arrow keys */
1555	if (((len == 5) && (buf[0] == 0x01) && (buf[4] == 0x00)) ||
1556	    ((len == 8) && (buf[0] & 0x40) &&
1557	     !(buf[1] & 0x1 || buf[1] >> 2 & 0x1))) {
1558		len = 8;
1559		imon_pad_to_keys(ictx, buf);
1560	}
1561
1562	if (debug) {
1563		printk(KERN_INFO "intf%d decoded packet: ", intf);
1564		for (i = 0; i < len; ++i)
1565			printk("%02x ", buf[i]);
1566		printk("\n");
1567	}
1568
1569	press_type = imon_parse_press_type(ictx, buf, ktype);
1570	if (press_type < 0)
1571		goto not_input_data;
1572
1573	spin_lock_irqsave(&ictx->kc_lock, flags);
1574	if (ictx->kc == KEY_UNKNOWN)
1575		goto unknown_key;
1576	spin_unlock_irqrestore(&ictx->kc_lock, flags);
1577
1578	if (ktype != IMON_KEY_PANEL) {
1579		if (press_type == 0)
1580			rc_keyup(ictx->rdev);
1581		else {
1582			rc_keydown(ictx->rdev, ictx->rc_scancode, ictx->rc_toggle);
1583			spin_lock_irqsave(&ictx->kc_lock, flags);
1584			ictx->last_keycode = ictx->kc;
1585			spin_unlock_irqrestore(&ictx->kc_lock, flags);
1586		}
1587		return;
1588	}
1589
1590	/* Only panel type events left to process now */
1591	spin_lock_irqsave(&ictx->kc_lock, flags);
1592
1593	do_gettimeofday(&t);
1594	/* KEY_MUTE repeats from knob need to be suppressed */
1595	if (ictx->kc == KEY_MUTE && ictx->kc == ictx->last_keycode) {
1596		msec = tv2int(&t, &prev_time);
1597		if (msec < ictx->idev->rep[REP_DELAY]) {
1598			spin_unlock_irqrestore(&ictx->kc_lock, flags);
1599			return;
1600		}
1601	}
1602	prev_time = t;
1603	kc = ictx->kc;
1604
1605	spin_unlock_irqrestore(&ictx->kc_lock, flags);
1606
1607	input_report_key(ictx->idev, kc, press_type);
1608	input_sync(ictx->idev);
1609
1610	/* panel keys don't generate a release */
1611	input_report_key(ictx->idev, kc, 0);
1612	input_sync(ictx->idev);
1613
1614	spin_lock_irqsave(&ictx->kc_lock, flags);
1615	ictx->last_keycode = kc;
1616	spin_unlock_irqrestore(&ictx->kc_lock, flags);
1617
1618	return;
1619
1620unknown_key:
1621	spin_unlock_irqrestore(&ictx->kc_lock, flags);
1622	dev_info(dev, "%s: unknown keypress, code 0x%llx\n", __func__,
1623		 (long long)scancode);
1624	return;
1625
1626not_input_data:
1627	if (len != 8) {
1628		dev_warn(dev, "imon %s: invalid incoming packet "
1629			 "size (len = %d, intf%d)\n", __func__, len, intf);
1630		return;
1631	}
1632
1633	/* iMON 2.4G associate frame */
1634	if (buf[0] == 0x00 &&
1635	    buf[2] == 0xFF &&				/* REFID */
1636	    buf[3] == 0xFF &&
1637	    buf[4] == 0xFF &&
1638	    buf[5] == 0xFF &&				/* iMON 2.4G */
1639	   ((buf[6] == 0x4E && buf[7] == 0xDF) ||	/* LT */
1640	    (buf[6] == 0x5E && buf[7] == 0xDF))) {	/* DT */
1641		dev_warn(dev, "%s: remote associated refid=%02X\n",
1642			 __func__, buf[1]);
1643		ictx->rf_isassociating = false;
1644	}
1645}
1646
1647/**
1648 * Callback function for USB core API: receive data
1649 */
1650static void usb_rx_callback_intf0(struct urb *urb)
1651{
1652	struct imon_context *ictx;
1653	int intfnum = 0;
1654
1655	if (!urb)
1656		return;
1657
1658	ictx = (struct imon_context *)urb->context;
1659	if (!ictx)
1660		return;
1661
1662	switch (urb->status) {
1663	case -ENOENT:		/* usbcore unlink successful! */
1664		return;
1665
1666	case -ESHUTDOWN:	/* transport endpoint was shut down */
1667		break;
1668
1669	case 0:
1670		imon_incoming_packet(ictx, urb, intfnum);
1671		break;
1672
1673	default:
1674		dev_warn(ictx->dev, "imon %s: status(%d): ignored\n",
1675			 __func__, urb->status);
1676		break;
1677	}
1678
1679	usb_submit_urb(ictx->rx_urb_intf0, GFP_ATOMIC);
1680}
1681
1682static void usb_rx_callback_intf1(struct urb *urb)
1683{
1684	struct imon_context *ictx;
1685	int intfnum = 1;
1686
1687	if (!urb)
1688		return;
1689
1690	ictx = (struct imon_context *)urb->context;
1691	if (!ictx)
1692		return;
1693
1694	switch (urb->status) {
1695	case -ENOENT:		/* usbcore unlink successful! */
1696		return;
1697
1698	case -ESHUTDOWN:	/* transport endpoint was shut down */
1699		break;
1700
1701	case 0:
1702		imon_incoming_packet(ictx, urb, intfnum);
1703		break;
1704
1705	default:
1706		dev_warn(ictx->dev, "imon %s: status(%d): ignored\n",
1707			 __func__, urb->status);
1708		break;
1709	}
1710
1711	usb_submit_urb(ictx->rx_urb_intf1, GFP_ATOMIC);
1712}
1713
1714/*
1715 * The 0x15c2:0xffdc device ID was used for umpteen different imon
1716 * devices, and all of them constantly spew interrupts, even when there
1717 * is no actual data to report. However, byte 6 of this buffer looks like
1718 * its unique across device variants, so we're trying to key off that to
1719 * figure out which display type (if any) and what IR protocol the device
1720 * actually supports. These devices have their IR protocol hard-coded into
1721 * their firmware, they can't be changed on the fly like the newer hardware.
1722 */
1723static void imon_get_ffdc_type(struct imon_context *ictx)
1724{
1725	u8 ffdc_cfg_byte = ictx->usb_rx_buf[6];
1726	u8 detected_display_type = IMON_DISPLAY_TYPE_NONE;
1727	u64 allowed_protos = RC_TYPE_OTHER;
1728
1729	switch (ffdc_cfg_byte) {
1730	/* iMON Knob, no display, iMON IR + vol knob */
1731	case 0x21:
1732		dev_info(ictx->dev, "0xffdc iMON Knob, iMON IR");
1733		ictx->display_supported = false;
1734		break;
1735	/* iMON 2.4G LT (usb stick), no display, iMON RF */
1736	case 0x4e:
1737		dev_info(ictx->dev, "0xffdc iMON 2.4G LT, iMON RF");
1738		ictx->display_supported = false;
1739		ictx->rf_device = true;
1740		break;
1741	/* iMON VFD, no IR (does have vol knob tho) */
1742	case 0x35:
1743		dev_info(ictx->dev, "0xffdc iMON VFD + knob, no IR");
1744		detected_display_type = IMON_DISPLAY_TYPE_VFD;
1745		break;
1746	/* iMON VFD, iMON IR */
1747	case 0x24:
1748	case 0x85:
1749		dev_info(ictx->dev, "0xffdc iMON VFD, iMON IR");
1750		detected_display_type = IMON_DISPLAY_TYPE_VFD;
1751		break;
1752	/* iMON VFD, MCE IR */
1753	case 0x46:
1754	case 0x7e:
1755	case 0x9e:
1756		dev_info(ictx->dev, "0xffdc iMON VFD, MCE IR");
1757		detected_display_type = IMON_DISPLAY_TYPE_VFD;
1758		allowed_protos = RC_TYPE_RC6;
1759		break;
1760	/* iMON LCD, MCE IR */
1761	case 0x9f:
1762		dev_info(ictx->dev, "0xffdc iMON LCD, MCE IR");
1763		detected_display_type = IMON_DISPLAY_TYPE_LCD;
1764		allowed_protos = RC_TYPE_RC6;
1765		break;
1766	default:
1767		dev_info(ictx->dev, "Unknown 0xffdc device, "
1768			 "defaulting to VFD and iMON IR");
1769		detected_display_type = IMON_DISPLAY_TYPE_VFD;
1770		/* We don't know which one it is, allow user to set the
1771		 * RC6 one from userspace if OTHER wasn't correct. */
1772		allowed_protos |= RC_TYPE_RC6;
1773		break;
1774	}
1775
1776	printk(KERN_CONT " (id 0x%02x)\n", ffdc_cfg_byte);
1777
1778	ictx->display_type = detected_display_type;
1779	ictx->rc_type = allowed_protos;
1780}
1781
1782static void imon_set_display_type(struct imon_context *ictx)
1783{
1784	u8 configured_display_type = IMON_DISPLAY_TYPE_VFD;
1785
1786	/*
1787	 * Try to auto-detect the type of display if the user hasn't set
1788	 * it by hand via the display_type modparam. Default is VFD.
1789	 */
1790
1791	if (display_type == IMON_DISPLAY_TYPE_AUTO) {
1792		switch (ictx->product) {
1793		case 0xffdc:
1794			/* set in imon_get_ffdc_type() */
1795			configured_display_type = ictx->display_type;
1796			break;
1797		case 0x0034:
1798		case 0x0035:
1799			configured_display_type = IMON_DISPLAY_TYPE_VGA;
1800			break;
1801		case 0x0038:
1802		case 0x0039:
1803		case 0x0045:
1804			configured_display_type = IMON_DISPLAY_TYPE_LCD;
1805			break;
1806		case 0x003c:
1807		case 0x0041:
1808		case 0x0042:
1809		case 0x0043:
1810			configured_display_type = IMON_DISPLAY_TYPE_NONE;
1811			ictx->display_supported = false;
1812			break;
1813		case 0x0036:
1814		case 0x0044:
1815		default:
1816			configured_display_type = IMON_DISPLAY_TYPE_VFD;
1817			break;
1818		}
1819	} else {
1820		configured_display_type = display_type;
1821		if (display_type == IMON_DISPLAY_TYPE_NONE)
1822			ictx->display_supported = false;
1823		else
1824			ictx->display_supported = true;
1825		dev_info(ictx->dev, "%s: overriding display type to %d via "
1826			 "modparam\n", __func__, display_type);
1827	}
1828
1829	ictx->display_type = configured_display_type;
1830}
1831
1832static struct rc_dev *imon_init_rdev(struct imon_context *ictx)
1833{
1834	struct rc_dev *rdev;
1835	int ret;
1836	const unsigned char fp_packet[] = { 0x40, 0x00, 0x00, 0x00,
1837					    0x00, 0x00, 0x00, 

Large files files are truncated, but you can click here to view the full file