aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/media/IR/Kconfig12
-rw-r--r--drivers/media/IR/Makefile3
-rw-r--r--drivers/media/IR/imon.c2417
3 files changed, 2432 insertions, 0 deletions
diff --git a/drivers/media/IR/Kconfig b/drivers/media/IR/Kconfig
index ee66d16d9ff2..dae5ea113867 100644
--- a/drivers/media/IR/Kconfig
+++ b/drivers/media/IR/Kconfig
@@ -36,3 +36,15 @@ config IR_RC6_DECODER
36 ---help--- 36 ---help---
37 Enable this option if you have an infrared remote control which 37 Enable this option if you have an infrared remote control which
38 uses the RC6 protocol, and you need software decoding support. 38 uses the RC6 protocol, and you need software decoding support.
39
40config IR_IMON
41 tristate "SoundGraph iMON Receiver and Display"
42 depends on USB_ARCH_HAS_HCD
43 depends on IR_CORE
44 select USB
45 ---help---
46 Say Y here if you want to use a SoundGraph iMON (aka Antec Veris)
47 IR Receiver and/or LCD/VFD/VGA display.
48
49 To compile this driver as a module, choose M here: the
50 module will be called imon.
diff --git a/drivers/media/IR/Makefile b/drivers/media/IR/Makefile
index 792d9cad7efc..57b145515d4f 100644
--- a/drivers/media/IR/Makefile
+++ b/drivers/media/IR/Makefile
@@ -8,3 +8,6 @@ obj-$(CONFIG_VIDEO_IR) += ir-common.o
8obj-$(CONFIG_IR_NEC_DECODER) += ir-nec-decoder.o 8obj-$(CONFIG_IR_NEC_DECODER) += ir-nec-decoder.o
9obj-$(CONFIG_IR_RC5_DECODER) += ir-rc5-decoder.o 9obj-$(CONFIG_IR_RC5_DECODER) += ir-rc5-decoder.o
10obj-$(CONFIG_IR_RC6_DECODER) += ir-rc6-decoder.o 10obj-$(CONFIG_IR_RC6_DECODER) += ir-rc6-decoder.o
11
12# stand-alone IR receivers/transmitters
13obj-$(CONFIG_IR_IMON) += imon.o
diff --git a/drivers/media/IR/imon.c b/drivers/media/IR/imon.c
new file mode 100644
index 000000000000..170fb9f2ca26
--- /dev/null
+++ b/drivers/media/IR/imon.c
@@ -0,0 +1,2417 @@
1/*
2 * imon.c: input and display driver for SoundGraph iMON IR/VFD/LCD
3 *
4 * Copyright(C) 2009 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#include <linux/errno.h>
30#include <linux/init.h>
31#include <linux/kernel.h>
32#include <linux/module.h>
33#include <linux/slab.h>
34#include <linux/uaccess.h>
35
36#include <linux/input.h>
37#include <linux/usb.h>
38#include <linux/usb/input.h>
39#include <media/ir-core.h>
40
41#include <linux/time.h>
42#include <linux/timer.h>
43
44#define MOD_AUTHOR "Jarod Wilson <jarod@wilsonet.com>"
45#define MOD_DESC "Driver for SoundGraph iMON MultiMedia IR/Display"
46#define MOD_NAME "imon"
47#define MOD_VERSION "0.9.1"
48
49#define DISPLAY_MINOR_BASE 144
50#define DEVICE_NAME "lcd%d"
51
52#define BUF_CHUNK_SIZE 8
53#define BUF_SIZE 128
54
55#define BIT_DURATION 250 /* each bit received is 250us */
56
57#define IMON_CLOCK_ENABLE_PACKETS 2
58#define IMON_KEY_RELEASE_OFFSET 1000
59
60/*** P R O T O T Y P E S ***/
61
62/* USB Callback prototypes */
63static int imon_probe(struct usb_interface *interface,
64 const struct usb_device_id *id);
65static void imon_disconnect(struct usb_interface *interface);
66static void usb_rx_callback_intf0(struct urb *urb);
67static void usb_rx_callback_intf1(struct urb *urb);
68static void usb_tx_callback(struct urb *urb);
69
70/* suspend/resume support */
71static int imon_resume(struct usb_interface *intf);
72static int imon_suspend(struct usb_interface *intf, pm_message_t message);
73
74/* Display file_operations function prototypes */
75static int display_open(struct inode *inode, struct file *file);
76static int display_close(struct inode *inode, struct file *file);
77
78/* VFD write operation */
79static ssize_t vfd_write(struct file *file, const char *buf,
80 size_t n_bytes, loff_t *pos);
81
82/* LCD file_operations override function prototypes */
83static ssize_t lcd_write(struct file *file, const char *buf,
84 size_t n_bytes, loff_t *pos);
85
86/*** G L O B A L S ***/
87
88struct imon_context {
89 struct device *dev;
90 struct ir_dev_props *props;
91 struct ir_input_dev *ir;
92 /* Newer devices have two interfaces */
93 struct usb_device *usbdev_intf0;
94 struct usb_device *usbdev_intf1;
95
96 bool display_supported; /* not all controllers do */
97 bool display_isopen; /* display port has been opened */
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 input_dev *idev; /* input device for remote */
126 struct input_dev *touch; /* input device for touchscreen */
127
128 u32 kc; /* current input keycode */
129 u32 last_keycode; /* last reported input keycode */
130 u8 ir_protocol; /* iMON or MCE (RC6) IR protocol? */
131 u8 ir_proto_mask; /* supported IR protocol mask */
132 u8 mce_toggle_bit; /* last mce toggle bit */
133 bool release_code; /* some keys send a release code */
134
135 u8 display_type; /* store the display type */
136 bool pad_mouse; /* toggle kbd(0)/mouse(1) mode */
137
138 char name_idev[128]; /* input device name */
139 char phys_idev[64]; /* input device phys path */
140 struct timer_list itimer; /* input device timer, need for rc6 */
141
142 char name_touch[128]; /* touch screen name */
143 char phys_touch[64]; /* touch screen phys path */
144 struct timer_list ttimer; /* touch screen timer */
145 int touch_x; /* x coordinate on touchscreen */
146 int touch_y; /* y coordinate on touchscreen */
147};
148
149#define TOUCH_TIMEOUT (HZ/30)
150#define MCE_TIMEOUT_MS 200
151
152/* vfd character device file operations */
153static const struct file_operations vfd_fops = {
154 .owner = THIS_MODULE,
155 .open = &display_open,
156 .write = &vfd_write,
157 .release = &display_close
158};
159
160/* lcd character device file operations */
161static const struct file_operations lcd_fops = {
162 .owner = THIS_MODULE,
163 .open = &display_open,
164 .write = &lcd_write,
165 .release = &display_close
166};
167
168enum {
169 IMON_DISPLAY_TYPE_AUTO = 0,
170 IMON_DISPLAY_TYPE_VFD = 1,
171 IMON_DISPLAY_TYPE_LCD = 2,
172 IMON_DISPLAY_TYPE_VGA = 3,
173 IMON_DISPLAY_TYPE_NONE = 4,
174};
175
176enum {
177 IMON_IR_PROTOCOL_AUTO = 0x0,
178 IMON_IR_PROTOCOL_MCE = 0x1,
179 IMON_IR_PROTOCOL_IMON = 0x2,
180 IMON_IR_PROTOCOL_IMON_NOPAD = 0x4,
181};
182
183enum {
184 IMON_IR_PROTO_MASK_NONE = 0x0,
185 IMON_IR_PROTO_MASK_MCE = IMON_IR_PROTOCOL_MCE,
186 IMON_IR_PROTO_MASK_IMON = IMON_IR_PROTOCOL_IMON |
187 IMON_IR_PROTOCOL_IMON_NOPAD,
188};
189
190enum {
191 IMON_KEY_IMON = 0,
192 IMON_KEY_MCE = 1,
193 IMON_KEY_PANEL = 2,
194};
195
196/*
197 * USB Device ID for iMON USB Control Boards
198 *
199 * The Windows drivers contain 6 different inf files, more or less one for
200 * each new device until the 0x0034-0x0046 devices, which all use the same
201 * driver. Some of the devices in the 34-46 range haven't been definitively
202 * identified yet. Early devices have either a TriGem Computer, Inc. or a
203 * Samsung vendor ID (0x0aa8 and 0x04e8 respectively), while all later
204 * devices use the SoundGraph vendor ID (0x15c2). This driver only supports
205 * the ffdc and later devices, which do onboard decoding.
206 */
207static struct usb_device_id imon_usb_id_table[] = {
208 /*
209 * Several devices with this same device ID, all use iMON_PAD.inf
210 * SoundGraph iMON PAD (IR & VFD)
211 * SoundGraph iMON PAD (IR & LCD)
212 * SoundGraph iMON Knob (IR only)
213 */
214 { USB_DEVICE(0x15c2, 0xffdc) },
215
216 /*
217 * Newer devices, all driven by the latest iMON Windows driver, full
218 * list of device IDs extracted via 'strings Setup/data1.hdr |grep 15c2'
219 * Need user input to fill in details on unknown devices.
220 */
221 /* SoundGraph iMON OEM Touch LCD (IR & 7" VGA LCD) */
222 { USB_DEVICE(0x15c2, 0x0034) },
223 /* SoundGraph iMON OEM Touch LCD (IR & 4.3" VGA LCD) */
224 { USB_DEVICE(0x15c2, 0x0035) },
225 /* SoundGraph iMON OEM VFD (IR & VFD) */
226 { USB_DEVICE(0x15c2, 0x0036) },
227 /* device specifics unknown */
228 { USB_DEVICE(0x15c2, 0x0037) },
229 /* SoundGraph iMON OEM LCD (IR & LCD) */
230 { USB_DEVICE(0x15c2, 0x0038) },
231 /* SoundGraph iMON UltraBay (IR & LCD) */
232 { USB_DEVICE(0x15c2, 0x0039) },
233 /* device specifics unknown */
234 { USB_DEVICE(0x15c2, 0x003a) },
235 /* device specifics unknown */
236 { USB_DEVICE(0x15c2, 0x003b) },
237 /* SoundGraph iMON OEM Inside (IR only) */
238 { USB_DEVICE(0x15c2, 0x003c) },
239 /* device specifics unknown */
240 { USB_DEVICE(0x15c2, 0x003d) },
241 /* device specifics unknown */
242 { USB_DEVICE(0x15c2, 0x003e) },
243 /* device specifics unknown */
244 { USB_DEVICE(0x15c2, 0x003f) },
245 /* device specifics unknown */
246 { USB_DEVICE(0x15c2, 0x0040) },
247 /* SoundGraph iMON MINI (IR only) */
248 { USB_DEVICE(0x15c2, 0x0041) },
249 /* Antec Veris Multimedia Station EZ External (IR only) */
250 { USB_DEVICE(0x15c2, 0x0042) },
251 /* Antec Veris Multimedia Station Basic Internal (IR only) */
252 { USB_DEVICE(0x15c2, 0x0043) },
253 /* Antec Veris Multimedia Station Elite (IR & VFD) */
254 { USB_DEVICE(0x15c2, 0x0044) },
255 /* Antec Veris Multimedia Station Premiere (IR & LCD) */
256 { USB_DEVICE(0x15c2, 0x0045) },
257 /* device specifics unknown */
258 { USB_DEVICE(0x15c2, 0x0046) },
259 {}
260};
261
262/* USB Device data */
263static struct usb_driver imon_driver = {
264 .name = MOD_NAME,
265 .probe = imon_probe,
266 .disconnect = imon_disconnect,
267 .suspend = imon_suspend,
268 .resume = imon_resume,
269 .id_table = imon_usb_id_table,
270};
271
272static struct usb_class_driver imon_vfd_class = {
273 .name = DEVICE_NAME,
274 .fops = &vfd_fops,
275 .minor_base = DISPLAY_MINOR_BASE,
276};
277
278static struct usb_class_driver imon_lcd_class = {
279 .name = DEVICE_NAME,
280 .fops = &lcd_fops,
281 .minor_base = DISPLAY_MINOR_BASE,
282};
283
284/* imon receiver front panel/knob key table */
285static const struct {
286 u64 hw_code;
287 u32 keycode;
288} imon_panel_key_table[] = {
289 { 0x000000000f00ffee, KEY_PROG1 }, /* Go */
290 { 0x000000001f00ffee, KEY_AUDIO },
291 { 0x000000002000ffee, KEY_VIDEO },
292 { 0x000000002100ffee, KEY_CAMERA },
293 { 0x000000002700ffee, KEY_DVD },
294 { 0x000000002300ffee, KEY_TV },
295 { 0x000000000500ffee, KEY_PREVIOUS },
296 { 0x000000000700ffee, KEY_REWIND },
297 { 0x000000000400ffee, KEY_STOP },
298 { 0x000000003c00ffee, KEY_PLAYPAUSE },
299 { 0x000000000800ffee, KEY_FASTFORWARD },
300 { 0x000000000600ffee, KEY_NEXT },
301 { 0x000000010000ffee, KEY_RIGHT },
302 { 0x000001000000ffee, KEY_LEFT },
303 { 0x000000003d00ffee, KEY_SELECT },
304 { 0x000100000000ffee, KEY_VOLUMEUP },
305 { 0x010000000000ffee, KEY_VOLUMEDOWN },
306 { 0x000000000100ffee, KEY_MUTE },
307 /* iMON Knob values */
308 { 0x000100ffffffffee, KEY_VOLUMEUP },
309 { 0x010000ffffffffee, KEY_VOLUMEDOWN },
310 { 0x000008ffffffffee, KEY_MUTE },
311};
312
313/* to prevent races between open() and disconnect(), probing, etc */
314static DEFINE_MUTEX(driver_lock);
315
316/* Module bookkeeping bits */
317MODULE_AUTHOR(MOD_AUTHOR);
318MODULE_DESCRIPTION(MOD_DESC);
319MODULE_VERSION(MOD_VERSION);
320MODULE_LICENSE("GPL");
321MODULE_DEVICE_TABLE(usb, imon_usb_id_table);
322
323static bool debug;
324module_param(debug, bool, S_IRUGO | S_IWUSR);
325MODULE_PARM_DESC(debug, "Debug messages: 0=no, 1=yes(default: no)");
326
327/* lcd, vfd, vga or none? should be auto-detected, but can be overridden... */
328static int display_type;
329module_param(display_type, int, S_IRUGO);
330MODULE_PARM_DESC(display_type, "Type of attached display. 0=autodetect, "
331 "1=vfd, 2=lcd, 3=vga, 4=none (default: autodetect)");
332
333/* IR protocol: native iMON, Windows MCE (RC-6), or iMON w/o PAD stabilize */
334static int ir_protocol;
335module_param(ir_protocol, int, S_IRUGO | S_IWUSR);
336MODULE_PARM_DESC(ir_protocol, "Which IR protocol to use. 0=auto-detect, "
337 "1=Windows Media Center Ed. (RC-6), 2=iMON native, "
338 "4=iMON w/o PAD stabilize (default: auto-detect)");
339
340/*
341 * In certain use cases, mouse mode isn't really helpful, and could actually
342 * cause confusion, so allow disabling it when the IR device is open.
343 */
344static bool nomouse;
345module_param(nomouse, bool, S_IRUGO | S_IWUSR);
346MODULE_PARM_DESC(nomouse, "Disable mouse input device mode when IR device is "
347 "open. 0=don't disable, 1=disable. (default: don't disable)");
348
349/* threshold at which a pad push registers as an arrow key in kbd mode */
350static int pad_thresh;
351module_param(pad_thresh, int, S_IRUGO | S_IWUSR);
352MODULE_PARM_DESC(pad_thresh, "Threshold at which a pad push registers as an "
353 "arrow key in kbd mode (default: 28)");
354
355
356static void free_imon_context(struct imon_context *ictx)
357{
358 struct device *dev = ictx->dev;
359
360 usb_free_urb(ictx->tx_urb);
361 usb_free_urb(ictx->rx_urb_intf0);
362 usb_free_urb(ictx->rx_urb_intf1);
363 kfree(ictx);
364
365 dev_dbg(dev, "%s: iMON context freed\n", __func__);
366}
367
368/**
369 * Called when the Display device (e.g. /dev/lcd0)
370 * is opened by the application.
371 */
372static int display_open(struct inode *inode, struct file *file)
373{
374 struct usb_interface *interface;
375 struct imon_context *ictx = NULL;
376 int subminor;
377 int retval = 0;
378
379 /* prevent races with disconnect */
380 mutex_lock(&driver_lock);
381
382 subminor = iminor(inode);
383 interface = usb_find_interface(&imon_driver, subminor);
384 if (!interface) {
385 err("%s: could not find interface for minor %d",
386 __func__, subminor);
387 retval = -ENODEV;
388 goto exit;
389 }
390 ictx = usb_get_intfdata(interface);
391
392 if (!ictx) {
393 err("%s: no context found for minor %d", __func__, subminor);
394 retval = -ENODEV;
395 goto exit;
396 }
397
398 mutex_lock(&ictx->lock);
399
400 if (!ictx->display_supported) {
401 err("%s: display not supported by device", __func__);
402 retval = -ENODEV;
403 } else if (ictx->display_isopen) {
404 err("%s: display port is already open", __func__);
405 retval = -EBUSY;
406 } else {
407 ictx->display_isopen = 1;
408 file->private_data = ictx;
409 dev_dbg(ictx->dev, "display port opened\n");
410 }
411
412 mutex_unlock(&ictx->lock);
413
414exit:
415 mutex_unlock(&driver_lock);
416 return retval;
417}
418
419/**
420 * Called when the display device (e.g. /dev/lcd0)
421 * is closed by the application.
422 */
423static int display_close(struct inode *inode, struct file *file)
424{
425 struct imon_context *ictx = NULL;
426 int retval = 0;
427
428 ictx = (struct imon_context *)file->private_data;
429
430 if (!ictx) {
431 err("%s: no context for device", __func__);
432 return -ENODEV;
433 }
434
435 mutex_lock(&ictx->lock);
436
437 if (!ictx->display_supported) {
438 err("%s: display not supported by device", __func__);
439 retval = -ENODEV;
440 } else if (!ictx->display_isopen) {
441 err("%s: display is not open", __func__);
442 retval = -EIO;
443 } else {
444 ictx->display_isopen = 0;
445 dev_dbg(ictx->dev, "display port closed\n");
446 if (!ictx->dev_present_intf0) {
447 /*
448 * Device disconnected before close and IR port is not
449 * open. If IR port is open, context will be deleted by
450 * ir_close.
451 */
452 mutex_unlock(&ictx->lock);
453 free_imon_context(ictx);
454 return retval;
455 }
456 }
457
458 mutex_unlock(&ictx->lock);
459 return retval;
460}
461
462/**
463 * Sends a packet to the device -- this function must be called
464 * with ictx->lock held.
465 */
466static int send_packet(struct imon_context *ictx)
467{
468 unsigned int pipe;
469 unsigned long timeout;
470 int interval = 0;
471 int retval = 0;
472 struct usb_ctrlrequest *control_req = NULL;
473
474 /* Check if we need to use control or interrupt urb */
475 if (!ictx->tx_control) {
476 pipe = usb_sndintpipe(ictx->usbdev_intf0,
477 ictx->tx_endpoint->bEndpointAddress);
478 interval = ictx->tx_endpoint->bInterval;
479
480 usb_fill_int_urb(ictx->tx_urb, ictx->usbdev_intf0, pipe,
481 ictx->usb_tx_buf,
482 sizeof(ictx->usb_tx_buf),
483 usb_tx_callback, ictx, interval);
484
485 ictx->tx_urb->actual_length = 0;
486 } else {
487 /* fill request into kmalloc'ed space: */
488 control_req = kmalloc(sizeof(struct usb_ctrlrequest),
489 GFP_KERNEL);
490 if (control_req == NULL)
491 return -ENOMEM;
492
493 /* setup packet is '21 09 0200 0001 0008' */
494 control_req->bRequestType = 0x21;
495 control_req->bRequest = 0x09;
496 control_req->wValue = cpu_to_le16(0x0200);
497 control_req->wIndex = cpu_to_le16(0x0001);
498 control_req->wLength = cpu_to_le16(0x0008);
499
500 /* control pipe is endpoint 0x00 */
501 pipe = usb_sndctrlpipe(ictx->usbdev_intf0, 0);
502
503 /* build the control urb */
504 usb_fill_control_urb(ictx->tx_urb, ictx->usbdev_intf0,
505 pipe, (unsigned char *)control_req,
506 ictx->usb_tx_buf,
507 sizeof(ictx->usb_tx_buf),
508 usb_tx_callback, ictx);
509 ictx->tx_urb->actual_length = 0;
510 }
511
512 init_completion(&ictx->tx.finished);
513 ictx->tx.busy = 1;
514 smp_rmb(); /* ensure later readers know we're busy */
515
516 retval = usb_submit_urb(ictx->tx_urb, GFP_KERNEL);
517 if (retval) {
518 ictx->tx.busy = 0;
519 smp_rmb(); /* ensure later readers know we're not busy */
520 err("%s: error submitting urb(%d)", __func__, retval);
521 } else {
522 /* Wait for transmission to complete (or abort) */
523 mutex_unlock(&ictx->lock);
524 retval = wait_for_completion_interruptible(
525 &ictx->tx.finished);
526 if (retval)
527 err("%s: task interrupted", __func__);
528 mutex_lock(&ictx->lock);
529
530 retval = ictx->tx.status;
531 if (retval)
532 err("%s: packet tx failed (%d)", __func__, retval);
533 }
534
535 kfree(control_req);
536
537 /*
538 * Induce a mandatory 5ms delay before returning, as otherwise,
539 * send_packet can get called so rapidly as to overwhelm the device,
540 * particularly on faster systems and/or those with quirky usb.
541 */
542 timeout = msecs_to_jiffies(5);
543 set_current_state(TASK_UNINTERRUPTIBLE);
544 schedule_timeout(timeout);
545
546 return retval;
547}
548
549/**
550 * Sends an associate packet to the iMON 2.4G.
551 *
552 * This might not be such a good idea, since it has an id collision with
553 * some versions of the "IR & VFD" combo. The only way to determine if it
554 * is an RF version is to look at the product description string. (Which
555 * we currently do not fetch).
556 */
557static int send_associate_24g(struct imon_context *ictx)
558{
559 int retval;
560 const unsigned char packet[8] = { 0x01, 0x00, 0x00, 0x00,
561 0x00, 0x00, 0x00, 0x20 };
562
563 if (!ictx) {
564 err("%s: no context for device", __func__);
565 return -ENODEV;
566 }
567
568 if (!ictx->dev_present_intf0) {
569 err("%s: no iMON device present", __func__);
570 return -ENODEV;
571 }
572
573 memcpy(ictx->usb_tx_buf, packet, sizeof(packet));
574 retval = send_packet(ictx);
575
576 return retval;
577}
578
579/**
580 * Sends packets to setup and show clock on iMON display
581 *
582 * Arguments: year - last 2 digits of year, month - 1..12,
583 * day - 1..31, dow - day of the week (0-Sun...6-Sat),
584 * hour - 0..23, minute - 0..59, second - 0..59
585 */
586static int send_set_imon_clock(struct imon_context *ictx,
587 unsigned int year, unsigned int month,
588 unsigned int day, unsigned int dow,
589 unsigned int hour, unsigned int minute,
590 unsigned int second)
591{
592 unsigned char clock_enable_pkt[IMON_CLOCK_ENABLE_PACKETS][8];
593 int retval = 0;
594 int i;
595
596 if (!ictx) {
597 err("%s: no context for device", __func__);
598 return -ENODEV;
599 }
600
601 switch (ictx->display_type) {
602 case IMON_DISPLAY_TYPE_LCD:
603 clock_enable_pkt[0][0] = 0x80;
604 clock_enable_pkt[0][1] = year;
605 clock_enable_pkt[0][2] = month-1;
606 clock_enable_pkt[0][3] = day;
607 clock_enable_pkt[0][4] = hour;
608 clock_enable_pkt[0][5] = minute;
609 clock_enable_pkt[0][6] = second;
610
611 clock_enable_pkt[1][0] = 0x80;
612 clock_enable_pkt[1][1] = 0;
613 clock_enable_pkt[1][2] = 0;
614 clock_enable_pkt[1][3] = 0;
615 clock_enable_pkt[1][4] = 0;
616 clock_enable_pkt[1][5] = 0;
617 clock_enable_pkt[1][6] = 0;
618
619 if (ictx->product == 0xffdc) {
620 clock_enable_pkt[0][7] = 0x50;
621 clock_enable_pkt[1][7] = 0x51;
622 } else {
623 clock_enable_pkt[0][7] = 0x88;
624 clock_enable_pkt[1][7] = 0x8a;
625 }
626
627 break;
628
629 case IMON_DISPLAY_TYPE_VFD:
630 clock_enable_pkt[0][0] = year;
631 clock_enable_pkt[0][1] = month-1;
632 clock_enable_pkt[0][2] = day;
633 clock_enable_pkt[0][3] = dow;
634 clock_enable_pkt[0][4] = hour;
635 clock_enable_pkt[0][5] = minute;
636 clock_enable_pkt[0][6] = second;
637 clock_enable_pkt[0][7] = 0x40;
638
639 clock_enable_pkt[1][0] = 0;
640 clock_enable_pkt[1][1] = 0;
641 clock_enable_pkt[1][2] = 1;
642 clock_enable_pkt[1][3] = 0;
643 clock_enable_pkt[1][4] = 0;
644 clock_enable_pkt[1][5] = 0;
645 clock_enable_pkt[1][6] = 0;
646 clock_enable_pkt[1][7] = 0x42;
647
648 break;
649
650 default:
651 return -ENODEV;
652 }
653
654 for (i = 0; i < IMON_CLOCK_ENABLE_PACKETS; i++) {
655 memcpy(ictx->usb_tx_buf, clock_enable_pkt[i], 8);
656 retval = send_packet(ictx);
657 if (retval) {
658 err("%s: send_packet failed for packet %d",
659 __func__, i);
660 break;
661 }
662 }
663
664 return retval;
665}
666
667/**
668 * These are the sysfs functions to handle the association on the iMON 2.4G LT.
669 */
670static ssize_t show_associate_remote(struct device *d,
671 struct device_attribute *attr,
672 char *buf)
673{
674 struct imon_context *ictx = dev_get_drvdata(d);
675
676 if (!ictx)
677 return -ENODEV;
678
679 mutex_lock(&ictx->lock);
680 if (ictx->rf_isassociating)
681 strcpy(buf, "associating\n");
682 else
683 strcpy(buf, "closed\n");
684
685 dev_info(d, "Visit http://www.lirc.org/html/imon-24g.html for "
686 "instructions on how to associate your iMON 2.4G DT/LT "
687 "remote\n");
688 mutex_unlock(&ictx->lock);
689 return strlen(buf);
690}
691
692static ssize_t store_associate_remote(struct device *d,
693 struct device_attribute *attr,
694 const char *buf, size_t count)
695{
696 struct imon_context *ictx;
697
698 ictx = dev_get_drvdata(d);
699
700 if (!ictx)
701 return -ENODEV;
702
703 mutex_lock(&ictx->lock);
704 ictx->rf_isassociating = 1;
705 send_associate_24g(ictx);
706 mutex_unlock(&ictx->lock);
707
708 return count;
709}
710
711/**
712 * sysfs functions to control internal imon clock
713 */
714static ssize_t show_imon_clock(struct device *d,
715 struct device_attribute *attr, char *buf)
716{
717 struct imon_context *ictx = dev_get_drvdata(d);
718 size_t len;
719
720 if (!ictx)
721 return -ENODEV;
722
723 mutex_lock(&ictx->lock);
724
725 if (!ictx->display_supported) {
726 len = snprintf(buf, PAGE_SIZE, "Not supported.");
727 } else {
728 len = snprintf(buf, PAGE_SIZE,
729 "To set the clock on your iMON display:\n"
730 "# date \"+%%y %%m %%d %%w %%H %%M %%S\" > imon_clock\n"
731 "%s", ictx->display_isopen ?
732 "\nNOTE: imon device must be closed\n" : "");
733 }
734
735 mutex_unlock(&ictx->lock);
736
737 return len;
738}
739
740static ssize_t store_imon_clock(struct device *d,
741 struct device_attribute *attr,
742 const char *buf, size_t count)
743{
744 struct imon_context *ictx = dev_get_drvdata(d);
745 ssize_t retval;
746 unsigned int year, month, day, dow, hour, minute, second;
747
748 if (!ictx)
749 return -ENODEV;
750
751 mutex_lock(&ictx->lock);
752
753 if (!ictx->display_supported) {
754 retval = -ENODEV;
755 goto exit;
756 } else if (ictx->display_isopen) {
757 retval = -EBUSY;
758 goto exit;
759 }
760
761 if (sscanf(buf, "%u %u %u %u %u %u %u", &year, &month, &day, &dow,
762 &hour, &minute, &second) != 7) {
763 retval = -EINVAL;
764 goto exit;
765 }
766
767 if ((month < 1 || month > 12) ||
768 (day < 1 || day > 31) || (dow > 6) ||
769 (hour > 23) || (minute > 59) || (second > 59)) {
770 retval = -EINVAL;
771 goto exit;
772 }
773
774 retval = send_set_imon_clock(ictx, year, month, day, dow,
775 hour, minute, second);
776 if (retval)
777 goto exit;
778
779 retval = count;
780exit:
781 mutex_unlock(&ictx->lock);
782
783 return retval;
784}
785
786
787static DEVICE_ATTR(imon_clock, S_IWUSR | S_IRUGO, show_imon_clock,
788 store_imon_clock);
789
790static DEVICE_ATTR(associate_remote, S_IWUSR | S_IRUGO, show_associate_remote,
791 store_associate_remote);
792
793static struct attribute *imon_display_sysfs_entries[] = {
794 &dev_attr_imon_clock.attr,
795 NULL
796};
797
798static struct attribute_group imon_display_attribute_group = {
799 .attrs = imon_display_sysfs_entries
800};
801
802static struct attribute *imon_rf_sysfs_entries[] = {
803 &dev_attr_associate_remote.attr,
804 NULL
805};
806
807static struct attribute_group imon_rf_attribute_group = {
808 .attrs = imon_rf_sysfs_entries
809};
810
811/**
812 * Writes data to the VFD. The iMON VFD is 2x16 characters
813 * and requires data in 5 consecutive USB interrupt packets,
814 * each packet but the last carrying 7 bytes.
815 *
816 * I don't know if the VFD board supports features such as
817 * scrolling, clearing rows, blanking, etc. so at
818 * the caller must provide a full screen of data. If fewer
819 * than 32 bytes are provided spaces will be appended to
820 * generate a full screen.
821 */
822static ssize_t vfd_write(struct file *file, const char *buf,
823 size_t n_bytes, loff_t *pos)
824{
825 int i;
826 int offset;
827 int seq;
828 int retval = 0;
829 struct imon_context *ictx;
830 const unsigned char vfd_packet6[] = {
831 0x01, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF };
832
833 ictx = (struct imon_context *)file->private_data;
834 if (!ictx) {
835 err("%s: no context for device", __func__);
836 return -ENODEV;
837 }
838
839 mutex_lock(&ictx->lock);
840
841 if (!ictx->dev_present_intf0) {
842 err("%s: no iMON device present", __func__);
843 retval = -ENODEV;
844 goto exit;
845 }
846
847 if (n_bytes <= 0 || n_bytes > 32) {
848 err("%s: invalid payload size", __func__);
849 retval = -EINVAL;
850 goto exit;
851 }
852
853 if (copy_from_user(ictx->tx.data_buf, buf, n_bytes)) {
854 retval = -EFAULT;
855 goto exit;
856 }
857
858 /* Pad with spaces */
859 for (i = n_bytes; i < 32; ++i)
860 ictx->tx.data_buf[i] = ' ';
861
862 for (i = 32; i < 35; ++i)
863 ictx->tx.data_buf[i] = 0xFF;
864
865 offset = 0;
866 seq = 0;
867
868 do {
869 memcpy(ictx->usb_tx_buf, ictx->tx.data_buf + offset, 7);
870 ictx->usb_tx_buf[7] = (unsigned char) seq;
871
872 retval = send_packet(ictx);
873 if (retval) {
874 err("%s: send packet failed for packet #%d",
875 __func__, seq/2);
876 goto exit;
877 } else {
878 seq += 2;
879 offset += 7;
880 }
881
882 } while (offset < 35);
883
884 /* Send packet #6 */
885 memcpy(ictx->usb_tx_buf, &vfd_packet6, sizeof(vfd_packet6));
886 ictx->usb_tx_buf[7] = (unsigned char) seq;
887 retval = send_packet(ictx);
888 if (retval)
889 err("%s: send packet failed for packet #%d",
890 __func__, seq / 2);
891
892exit:
893 mutex_unlock(&ictx->lock);
894
895 return (!retval) ? n_bytes : retval;
896}
897
898/**
899 * Writes data to the LCD. The iMON OEM LCD screen expects 8-byte
900 * packets. We accept data as 16 hexadecimal digits, followed by a
901 * newline (to make it easy to drive the device from a command-line
902 * -- even though the actual binary data is a bit complicated).
903 *
904 * The device itself is not a "traditional" text-mode display. It's
905 * actually a 16x96 pixel bitmap display. That means if you want to
906 * display text, you've got to have your own "font" and translate the
907 * text into bitmaps for display. This is really flexible (you can
908 * display whatever diacritics you need, and so on), but it's also
909 * a lot more complicated than most LCDs...
910 */
911static ssize_t lcd_write(struct file *file, const char *buf,
912 size_t n_bytes, loff_t *pos)
913{
914 int retval = 0;
915 struct imon_context *ictx;
916
917 ictx = (struct imon_context *)file->private_data;
918 if (!ictx) {
919 err("%s: no context for device", __func__);
920 return -ENODEV;
921 }
922
923 mutex_lock(&ictx->lock);
924
925 if (!ictx->display_supported) {
926 err("%s: no iMON display present", __func__);
927 retval = -ENODEV;
928 goto exit;
929 }
930
931 if (n_bytes != 8) {
932 err("%s: invalid payload size: %d (expecting 8)",
933 __func__, (int) n_bytes);
934 retval = -EINVAL;
935 goto exit;
936 }
937
938 if (copy_from_user(ictx->usb_tx_buf, buf, 8)) {
939 retval = -EFAULT;
940 goto exit;
941 }
942
943 retval = send_packet(ictx);
944 if (retval) {
945 err("%s: send packet failed!", __func__);
946 goto exit;
947 } else {
948 dev_dbg(ictx->dev, "%s: write %d bytes to LCD\n",
949 __func__, (int) n_bytes);
950 }
951exit:
952 mutex_unlock(&ictx->lock);
953 return (!retval) ? n_bytes : retval;
954}
955
956/**
957 * Callback function for USB core API: transmit data
958 */
959static void usb_tx_callback(struct urb *urb)
960{
961 struct imon_context *ictx;
962
963 if (!urb)
964 return;
965 ictx = (struct imon_context *)urb->context;
966 if (!ictx)
967 return;
968
969 ictx->tx.status = urb->status;
970
971 /* notify waiters that write has finished */
972 ictx->tx.busy = 0;
973 smp_rmb(); /* ensure later readers know we're not busy */
974 complete(&ictx->tx.finished);
975}
976
977/**
978 * mce/rc6 keypresses have no distinct release code, use timer
979 */
980static void imon_mce_timeout(unsigned long data)
981{
982 struct imon_context *ictx = (struct imon_context *)data;
983
984 input_report_key(ictx->idev, ictx->last_keycode, 0);
985 input_sync(ictx->idev);
986}
987
988/**
989 * report touchscreen input
990 */
991static void imon_touch_display_timeout(unsigned long data)
992{
993 struct imon_context *ictx = (struct imon_context *)data;
994
995 if (!ictx->display_type == IMON_DISPLAY_TYPE_VGA)
996 return;
997
998 input_report_abs(ictx->touch, ABS_X, ictx->touch_x);
999 input_report_abs(ictx->touch, ABS_Y, ictx->touch_y);
1000 input_report_key(ictx->touch, BTN_TOUCH, 0x00);
1001 input_sync(ictx->touch);
1002}
1003
1004/**
1005 * iMON IR receivers support two different signal sets -- those used by
1006 * the iMON remotes, and those used by the Windows MCE remotes (which is
1007 * really just RC-6), but only one or the other at a time, as the signals
1008 * are decoded onboard the receiver.
1009 */
1010static void imon_set_ir_protocol(struct imon_context *ictx)
1011{
1012 int retval;
1013 struct device *dev = ictx->dev;
1014 unsigned char ir_proto_packet[] = {
1015 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86 };
1016
1017 if (ir_protocol && !(ir_protocol & ictx->ir_proto_mask))
1018 dev_warn(dev, "Looks like you're trying to use an IR protocol "
1019 "this device does not support\n");
1020
1021 switch (ir_protocol) {
1022 case IMON_IR_PROTOCOL_AUTO:
1023 if (ictx->product == 0xffdc) {
1024 if (ictx->ir_proto_mask & IMON_IR_PROTO_MASK_MCE) {
1025 ir_proto_packet[0] = 0x01;
1026 ictx->ir_protocol = IMON_IR_PROTOCOL_MCE;
1027 ictx->pad_mouse = 0;
1028 init_timer(&ictx->itimer);
1029 ictx->itimer.data = (unsigned long)ictx;
1030 ictx->itimer.function = imon_mce_timeout;
1031 } else {
1032 ictx->ir_protocol = IMON_IR_PROTOCOL_IMON;
1033 ictx->pad_mouse = 1;
1034 }
1035 }
1036 break;
1037 case IMON_IR_PROTOCOL_MCE:
1038 dev_dbg(dev, "Configuring IR receiver for MCE protocol\n");
1039 ir_proto_packet[0] = 0x01;
1040 ictx->ir_protocol = IMON_IR_PROTOCOL_MCE;
1041 ictx->pad_mouse = 0;
1042 init_timer(&ictx->itimer);
1043 ictx->itimer.data = (unsigned long)ictx;
1044 ictx->itimer.function = imon_mce_timeout;
1045 break;
1046 case IMON_IR_PROTOCOL_IMON:
1047 dev_dbg(dev, "Configuring IR receiver for iMON protocol\n");
1048 /* ir_proto_packet[0] = 0x00; // already the default */
1049 ictx->ir_protocol = IMON_IR_PROTOCOL_IMON;
1050 ictx->pad_mouse = 1;
1051 break;
1052 case IMON_IR_PROTOCOL_IMON_NOPAD:
1053 dev_dbg(dev, "Configuring IR receiver for iMON protocol "
1054 "without PAD stabilize function enabled\n");
1055 /* ir_proto_packet[0] = 0x00; // already the default */
1056 ictx->ir_protocol = IMON_IR_PROTOCOL_IMON_NOPAD;
1057 ictx->pad_mouse = 0;
1058 break;
1059 default:
1060 dev_info(dev, "%s: unknown IR protocol specified, will "
1061 "just default to iMON protocol\n", __func__);
1062 ictx->ir_protocol = IMON_IR_PROTOCOL_IMON;
1063 ictx->pad_mouse = 1;
1064 break;
1065 }
1066
1067 memcpy(ictx->usb_tx_buf, &ir_proto_packet, sizeof(ir_proto_packet));
1068
1069 retval = send_packet(ictx);
1070 if (retval) {
1071 dev_info(dev, "%s: failed to set IR protocol, falling back "
1072 "to standard iMON protocol mode\n", __func__);
1073 ir_protocol = IMON_IR_PROTOCOL_IMON;
1074 ictx->ir_protocol = IMON_IR_PROTOCOL_IMON;
1075 }
1076}
1077
1078static inline int tv2int(const struct timeval *a, const struct timeval *b)
1079{
1080 int usecs = 0;
1081 int sec = 0;
1082
1083 if (b->tv_usec > a->tv_usec) {
1084 usecs = 1000000;
1085 sec--;
1086 }
1087
1088 usecs += a->tv_usec - b->tv_usec;
1089
1090 sec += a->tv_sec - b->tv_sec;
1091 sec *= 1000;
1092 usecs /= 1000;
1093 sec += usecs;
1094
1095 if (sec < 0)
1096 sec = 1000;
1097
1098 return sec;
1099}
1100
1101/**
1102 * The directional pad behaves a bit differently, depending on whether this is
1103 * one of the older ffdc devices or a newer device. Newer devices appear to
1104 * have a higher resolution matrix for more precise mouse movement, but it
1105 * makes things overly sensitive in keyboard mode, so we do some interesting
1106 * contortions to make it less touchy. Older devices run through the same
1107 * routine with shorter timeout and a smaller threshold.
1108 */
1109static int stabilize(int a, int b, u16 timeout, u16 threshold)
1110{
1111 struct timeval ct;
1112 static struct timeval prev_time = {0, 0};
1113 static struct timeval hit_time = {0, 0};
1114 static int x, y, prev_result, hits;
1115 int result = 0;
1116 int msec, msec_hit;
1117
1118 do_gettimeofday(&ct);
1119 msec = tv2int(&ct, &prev_time);
1120 msec_hit = tv2int(&ct, &hit_time);
1121
1122 if (msec > 100) {
1123 x = 0;
1124 y = 0;
1125 hits = 0;
1126 }
1127
1128 x += a;
1129 y += b;
1130
1131 prev_time = ct;
1132
1133 if (abs(x) > threshold || abs(y) > threshold) {
1134 if (abs(y) > abs(x))
1135 result = (y > 0) ? 0x7F : 0x80;
1136 else
1137 result = (x > 0) ? 0x7F00 : 0x8000;
1138
1139 x = 0;
1140 y = 0;
1141
1142 if (result == prev_result) {
1143 hits++;
1144
1145 if (hits > 3) {
1146 switch (result) {
1147 case 0x7F:
1148 y = 17 * threshold / 30;
1149 break;
1150 case 0x80:
1151 y -= 17 * threshold / 30;
1152 break;
1153 case 0x7F00:
1154 x = 17 * threshold / 30;
1155 break;
1156 case 0x8000:
1157 x -= 17 * threshold / 30;
1158 break;
1159 }
1160 }
1161
1162 if (hits == 2 && msec_hit < timeout) {
1163 result = 0;
1164 hits = 1;
1165 }
1166 } else {
1167 prev_result = result;
1168 hits = 1;
1169 hit_time = ct;
1170 }
1171 }
1172
1173 return result;
1174}
1175
1176static u32 imon_remote_key_lookup(struct imon_context *ictx, u32 hw_code)
1177{
1178 u32 scancode = be32_to_cpu(hw_code);
1179 u32 keycode;
1180 u32 release;
1181 bool is_release_code = false;
1182
1183 /* Look for the initial press of a button */
1184 keycode = ir_g_keycode_from_table(ictx->idev, scancode);
1185
1186 /* Look for the release of a button */
1187 if (keycode == KEY_RESERVED) {
1188 release = scancode & ~0x4000;
1189 keycode = ir_g_keycode_from_table(ictx->idev, release);
1190 if (keycode != KEY_RESERVED)
1191 is_release_code = true;
1192 }
1193
1194 ictx->release_code = is_release_code;
1195
1196 return keycode;
1197}
1198
1199static u32 imon_mce_key_lookup(struct imon_context *ictx, u32 hw_code)
1200{
1201 u32 scancode = be32_to_cpu(hw_code);
1202 u32 keycode;
1203
1204#define MCE_KEY_MASK 0x7000
1205#define MCE_TOGGLE_BIT 0x8000
1206
1207 /*
1208 * On some receivers, mce keys decode to 0x8000f04xx and 0x8000f84xx
1209 * (the toggle bit flipping between alternating key presses), while
1210 * on other receivers, we see 0x8000f74xx and 0x8000ff4xx. To keep
1211 * the table trim, we always or in the bits to look up 0x8000ff4xx,
1212 * but we can't or them into all codes, as some keys are decoded in
1213 * a different way w/o the same use of the toggle bit...
1214 */
1215 if ((scancode >> 24) & 0x80)
1216 scancode = scancode | MCE_KEY_MASK | MCE_TOGGLE_BIT;
1217
1218 keycode = ir_g_keycode_from_table(ictx->idev, scancode);
1219
1220 return keycode;
1221}
1222
1223static u32 imon_panel_key_lookup(u64 hw_code)
1224{
1225 int i;
1226 u64 code = be64_to_cpu(hw_code);
1227 u32 keycode;
1228
1229 for (i = 0; i < ARRAY_SIZE(imon_panel_key_table); i++)
1230 if (imon_panel_key_table[i].hw_code == (code | 0xffee))
1231 break;
1232
1233 keycode = imon_panel_key_table[i % IMON_KEY_RELEASE_OFFSET].keycode;
1234
1235 return keycode;
1236}
1237
1238static bool imon_mouse_event(struct imon_context *ictx,
1239 unsigned char *buf, int len)
1240{
1241 char rel_x = 0x00, rel_y = 0x00;
1242 u8 right_shift = 1;
1243 bool mouse_input = 1;
1244 int dir = 0;
1245
1246 /* newer iMON device PAD or mouse button */
1247 if (ictx->product != 0xffdc && (buf[0] & 0x01) && len == 5) {
1248 rel_x = buf[2];
1249 rel_y = buf[3];
1250 right_shift = 1;
1251 /* 0xffdc iMON PAD or mouse button input */
1252 } else if (ictx->product == 0xffdc && (buf[0] & 0x40) &&
1253 !((buf[1] & 0x01) || ((buf[1] >> 2) & 0x01))) {
1254 rel_x = (buf[1] & 0x08) | (buf[1] & 0x10) >> 2 |
1255 (buf[1] & 0x20) >> 4 | (buf[1] & 0x40) >> 6;
1256 if (buf[0] & 0x02)
1257 rel_x |= ~0x0f;
1258 rel_x = rel_x + rel_x / 2;
1259 rel_y = (buf[2] & 0x08) | (buf[2] & 0x10) >> 2 |
1260 (buf[2] & 0x20) >> 4 | (buf[2] & 0x40) >> 6;
1261 if (buf[0] & 0x01)
1262 rel_y |= ~0x0f;
1263 rel_y = rel_y + rel_y / 2;
1264 right_shift = 2;
1265 /* some ffdc devices decode mouse buttons differently... */
1266 } else if (ictx->product == 0xffdc && (buf[0] == 0x68)) {
1267 right_shift = 2;
1268 /* ch+/- buttons, which we use for an emulated scroll wheel */
1269 } else if (ictx->kc == KEY_CHANNELUP && (buf[2] & 0x40) != 0x40) {
1270 dir = 1;
1271 } else if (ictx->kc == KEY_CHANNELDOWN && (buf[2] & 0x40) != 0x40) {
1272 dir = -1;
1273 } else
1274 mouse_input = 0;
1275
1276 if (mouse_input) {
1277 dev_dbg(ictx->dev, "sending mouse data via input subsystem\n");
1278
1279 if (dir) {
1280 input_report_rel(ictx->idev, REL_WHEEL, dir);
1281 } else if (rel_x || rel_y) {
1282 input_report_rel(ictx->idev, REL_X, rel_x);
1283 input_report_rel(ictx->idev, REL_Y, rel_y);
1284 } else {
1285 input_report_key(ictx->idev, BTN_LEFT, buf[1] & 0x1);
1286 input_report_key(ictx->idev, BTN_RIGHT,
1287 buf[1] >> right_shift & 0x1);
1288 }
1289 input_sync(ictx->idev);
1290 ictx->last_keycode = ictx->kc;
1291 }
1292
1293 return mouse_input;
1294}
1295
1296static void imon_touch_event(struct imon_context *ictx, unsigned char *buf)
1297{
1298 mod_timer(&ictx->ttimer, jiffies + TOUCH_TIMEOUT);
1299 ictx->touch_x = (buf[0] << 4) | (buf[1] >> 4);
1300 ictx->touch_y = 0xfff - ((buf[2] << 4) | (buf[1] & 0xf));
1301 input_report_abs(ictx->touch, ABS_X, ictx->touch_x);
1302 input_report_abs(ictx->touch, ABS_Y, ictx->touch_y);
1303 input_report_key(ictx->touch, BTN_TOUCH, 0x01);
1304 input_sync(ictx->touch);
1305}
1306
1307static void imon_pad_to_keys(struct imon_context *ictx, unsigned char *buf)
1308{
1309 int dir = 0;
1310 char rel_x = 0x00, rel_y = 0x00;
1311 u16 timeout, threshold;
1312 u64 temp_key;
1313 u32 remote_key;
1314
1315 /*
1316 * The imon directional pad functions more like a touchpad. Bytes 3 & 4
1317 * contain a position coordinate (x,y), with each component ranging
1318 * from -14 to 14. We want to down-sample this to only 4 discrete values
1319 * for up/down/left/right arrow keys. Also, when you get too close to
1320 * diagonals, it has a tendancy to jump back and forth, so lets try to
1321 * ignore when they get too close.
1322 */
1323 if (ictx->product != 0xffdc) {
1324 /* first, pad to 8 bytes so it conforms with everything else */
1325 buf[5] = buf[6] = buf[7] = 0;
1326 timeout = 500; /* in msecs */
1327 /* (2*threshold) x (2*threshold) square */
1328 threshold = pad_thresh ? pad_thresh : 28;
1329 rel_x = buf[2];
1330 rel_y = buf[3];
1331
1332 if (ictx->ir_protocol == IMON_IR_PROTOCOL_IMON) {
1333 if ((buf[1] == 0) && ((rel_x != 0) || (rel_y != 0))) {
1334 dir = stabilize((int)rel_x, (int)rel_y,
1335 timeout, threshold);
1336 if (!dir) {
1337 ictx->kc = KEY_UNKNOWN;
1338 return;
1339 }
1340 buf[2] = dir & 0xFF;
1341 buf[3] = (dir >> 8) & 0xFF;
1342 memcpy(&temp_key, buf, sizeof(temp_key));
1343 remote_key = (u32) (le64_to_cpu(temp_key)
1344 & 0xffffffff);
1345 ictx->kc = imon_remote_key_lookup(ictx,
1346 remote_key);
1347 }
1348 } else {
1349 if (abs(rel_y) > abs(rel_x)) {
1350 buf[2] = (rel_y > 0) ? 0x7F : 0x80;
1351 buf[3] = 0;
1352 ictx->kc = (rel_y > 0) ? KEY_DOWN : KEY_UP;
1353 } else {
1354 buf[2] = 0;
1355 buf[3] = (rel_x > 0) ? 0x7F : 0x80;
1356 ictx->kc = (rel_x > 0) ? KEY_RIGHT : KEY_LEFT;
1357 }
1358 }
1359
1360 /*
1361 * Handle on-board decoded pad events for e.g. older VFD/iMON-Pad
1362 * device (15c2:ffdc). The remote generates various codes from
1363 * 0x68nnnnB7 to 0x6AnnnnB7, the left mouse button generates
1364 * 0x688301b7 and the right one 0x688481b7. All other keys generate
1365 * 0x2nnnnnnn. Position coordinate is encoded in buf[1] and buf[2] with
1366 * reversed endianess. Extract direction from buffer, rotate endianess,
1367 * adjust sign and feed the values into stabilize(). The resulting codes
1368 * will be 0x01008000, 0x01007F00, which match the newer devices.
1369 */
1370 } else {
1371 timeout = 10; /* in msecs */
1372 /* (2*threshold) x (2*threshold) square */
1373 threshold = pad_thresh ? pad_thresh : 15;
1374
1375 /* buf[1] is x */
1376 rel_x = (buf[1] & 0x08) | (buf[1] & 0x10) >> 2 |
1377 (buf[1] & 0x20) >> 4 | (buf[1] & 0x40) >> 6;
1378 if (buf[0] & 0x02)
1379 rel_x |= ~0x10+1;
1380 /* buf[2] is y */
1381 rel_y = (buf[2] & 0x08) | (buf[2] & 0x10) >> 2 |
1382 (buf[2] & 0x20) >> 4 | (buf[2] & 0x40) >> 6;
1383 if (buf[0] & 0x01)
1384 rel_y |= ~0x10+1;
1385
1386 buf[0] = 0x01;
1387 buf[1] = buf[4] = buf[5] = buf[6] = buf[7] = 0;
1388
1389 if (ictx->ir_protocol == IMON_IR_PROTOCOL_IMON) {
1390 dir = stabilize((int)rel_x, (int)rel_y,
1391 timeout, threshold);
1392 if (!dir) {
1393 ictx->kc = KEY_UNKNOWN;
1394 return;
1395 }
1396 buf[2] = dir & 0xFF;
1397 buf[3] = (dir >> 8) & 0xFF;
1398 memcpy(&temp_key, buf, sizeof(temp_key));
1399 remote_key = (u32) (le64_to_cpu(temp_key) & 0xffffffff);
1400 ictx->kc = imon_remote_key_lookup(ictx, remote_key);
1401 } else {
1402 if (abs(rel_y) > abs(rel_x)) {
1403 buf[2] = (rel_y > 0) ? 0x7F : 0x80;
1404 buf[3] = 0;
1405 ictx->kc = (rel_y > 0) ? KEY_DOWN : KEY_UP;
1406 } else {
1407 buf[2] = 0;
1408 buf[3] = (rel_x > 0) ? 0x7F : 0x80;
1409 ictx->kc = (rel_x > 0) ? KEY_RIGHT : KEY_LEFT;
1410 }
1411 }
1412 }
1413}
1414
1415static int imon_parse_press_type(struct imon_context *ictx,
1416 unsigned char *buf, u8 ktype)
1417{
1418 int press_type = 0;
1419
1420 /* key release of 0x02XXXXXX key */
1421 if (ictx->kc == KEY_RESERVED && buf[0] == 0x02 && buf[3] == 0x00)
1422 ictx->kc = ictx->last_keycode;
1423
1424 /* mouse button release on (some) 0xffdc devices */
1425 else if (ictx->kc == KEY_RESERVED && buf[0] == 0x68 && buf[1] == 0x82 &&
1426 buf[2] == 0x81 && buf[3] == 0xb7)
1427 ictx->kc = ictx->last_keycode;
1428
1429 /* mouse button release on (some other) 0xffdc devices */
1430 else if (ictx->kc == KEY_RESERVED && buf[0] == 0x01 && buf[1] == 0x00 &&
1431 buf[2] == 0x81 && buf[3] == 0xb7)
1432 ictx->kc = ictx->last_keycode;
1433
1434 /* mce-specific button handling */
1435 else if (ktype == IMON_KEY_MCE) {
1436 /* initial press */
1437 if (ictx->kc != ictx->last_keycode
1438 || buf[2] != ictx->mce_toggle_bit) {
1439 ictx->last_keycode = ictx->kc;
1440 ictx->mce_toggle_bit = buf[2];
1441 press_type = 1;
1442 mod_timer(&ictx->itimer,
1443 jiffies + msecs_to_jiffies(MCE_TIMEOUT_MS));
1444 /* repeat */
1445 } else {
1446 press_type = 2;
1447 mod_timer(&ictx->itimer,
1448 jiffies + msecs_to_jiffies(MCE_TIMEOUT_MS));
1449 }
1450
1451 /* incoherent or irrelevant data */
1452 } else if (ictx->kc == KEY_RESERVED)
1453 press_type = -EINVAL;
1454
1455 /* key release of 0xXXXXXXb7 key */
1456 else if (ictx->release_code)
1457 press_type = 0;
1458
1459 /* this is a button press */
1460 else
1461 press_type = 1;
1462
1463 return press_type;
1464}
1465
1466/**
1467 * Process the incoming packet
1468 */
1469static void imon_incoming_packet(struct imon_context *ictx,
1470 struct urb *urb, int intf)
1471{
1472 int len = urb->actual_length;
1473 unsigned char *buf = urb->transfer_buffer;
1474 struct device *dev = ictx->dev;
1475 u32 kc;
1476 bool norelease = 0;
1477 int i;
1478 u64 temp_key;
1479 u64 panel_key = 0;
1480 u32 remote_key = 0;
1481 struct input_dev *idev = NULL;
1482 int press_type = 0;
1483 int msec;
1484 struct timeval t;
1485 static struct timeval prev_time = { 0, 0 };
1486 u8 ktype = IMON_KEY_IMON;
1487
1488 idev = ictx->idev;
1489
1490 /* filter out junk data on the older 0xffdc imon devices */
1491 if ((buf[0] == 0xff) && (buf[7] == 0xff))
1492 return;
1493
1494 /* Figure out what key was pressed */
1495 memcpy(&temp_key, buf, sizeof(temp_key));
1496 if (len == 8 && buf[7] == 0xee) {
1497 ktype = IMON_KEY_PANEL;
1498 panel_key = le64_to_cpu(temp_key);
1499 kc = imon_panel_key_lookup(panel_key);
1500 } else {
1501 remote_key = (u32) (le64_to_cpu(temp_key) & 0xffffffff);
1502 if (ictx->ir_protocol == IMON_IR_PROTOCOL_MCE) {
1503 if (buf[0] == 0x80)
1504 ktype = IMON_KEY_MCE;
1505 kc = imon_mce_key_lookup(ictx, remote_key);
1506 } else
1507 kc = imon_remote_key_lookup(ictx, remote_key);
1508 }
1509
1510 /* keyboard/mouse mode toggle button */
1511 if (kc == KEY_KEYBOARD && !ictx->release_code) {
1512 ictx->last_keycode = kc;
1513 if (!nomouse) {
1514 ictx->pad_mouse = ~(ictx->pad_mouse) & 0x1;
1515 dev_dbg(dev, "toggling to %s mode\n",
1516 ictx->pad_mouse ? "mouse" : "keyboard");
1517 return;
1518 } else {
1519 ictx->pad_mouse = 0;
1520 dev_dbg(dev, "mouse mode disabled, passing key value\n");
1521 }
1522 }
1523
1524 ictx->kc = kc;
1525
1526 /* send touchscreen events through input subsystem if touchpad data */
1527 if (ictx->display_type == IMON_DISPLAY_TYPE_VGA && len == 8 &&
1528 buf[7] == 0x86) {
1529 imon_touch_event(ictx, buf);
1530
1531 /* look for mouse events with pad in mouse mode */
1532 } else if (ictx->pad_mouse) {
1533 if (imon_mouse_event(ictx, buf, len))
1534 return;
1535 }
1536
1537 /* Now for some special handling to convert pad input to arrow keys */
1538 if (((len == 5) && (buf[0] == 0x01) && (buf[4] == 0x00)) ||
1539 ((len == 8) && (buf[0] & 0x40) &&
1540 !(buf[1] & 0x1 || buf[1] >> 2 & 0x1))) {
1541 len = 8;
1542 imon_pad_to_keys(ictx, buf);
1543 norelease = 1;
1544 }
1545
1546 if (debug) {
1547 printk(KERN_INFO "intf%d decoded packet: ", intf);
1548 for (i = 0; i < len; ++i)
1549 printk("%02x ", buf[i]);
1550 printk("\n");
1551 }
1552
1553 press_type = imon_parse_press_type(ictx, buf, ktype);
1554 if (press_type < 0)
1555 goto not_input_data;
1556
1557 if (ictx->kc == KEY_UNKNOWN)
1558 goto unknown_key;
1559
1560 /* KEY_MUTE repeats from MCE and knob need to be suppressed */
1561 if ((ictx->kc == KEY_MUTE && ictx->kc == ictx->last_keycode)
1562 && (buf[7] == 0xee || ktype == IMON_KEY_MCE)) {
1563 do_gettimeofday(&t);
1564 msec = tv2int(&t, &prev_time);
1565 prev_time = t;
1566 if (msec < 200)
1567 return;
1568 }
1569
1570 input_report_key(idev, ictx->kc, press_type);
1571 input_sync(idev);
1572
1573 /* panel keys and some remote keys don't generate a release */
1574 if (panel_key || norelease) {
1575 input_report_key(idev, ictx->kc, 0);
1576 input_sync(idev);
1577 }
1578
1579 ictx->last_keycode = ictx->kc;
1580
1581 return;
1582
1583unknown_key:
1584 dev_info(dev, "%s: unknown keypress, code 0x%llx\n", __func__,
1585 (panel_key ? be64_to_cpu(panel_key) :
1586 be32_to_cpu(remote_key)));
1587 return;
1588
1589not_input_data:
1590 if (len != 8) {
1591 dev_warn(dev, "imon %s: invalid incoming packet "
1592 "size (len = %d, intf%d)\n", __func__, len, intf);
1593 return;
1594 }
1595
1596 /* iMON 2.4G associate frame */
1597 if (buf[0] == 0x00 &&
1598 buf[2] == 0xFF && /* REFID */
1599 buf[3] == 0xFF &&
1600 buf[4] == 0xFF &&
1601 buf[5] == 0xFF && /* iMON 2.4G */
1602 ((buf[6] == 0x4E && buf[7] == 0xDF) || /* LT */
1603 (buf[6] == 0x5E && buf[7] == 0xDF))) { /* DT */
1604 dev_warn(dev, "%s: remote associated refid=%02X\n",
1605 __func__, buf[1]);
1606 ictx->rf_isassociating = 0;
1607 }
1608}
1609
1610/**
1611 * Callback function for USB core API: receive data
1612 */
1613static void usb_rx_callback_intf0(struct urb *urb)
1614{
1615 struct imon_context *ictx;
1616 int intfnum = 0;
1617
1618 if (!urb)
1619 return;
1620
1621 ictx = (struct imon_context *)urb->context;
1622 if (!ictx)
1623 return;
1624
1625 switch (urb->status) {
1626 case -ENOENT: /* usbcore unlink successful! */
1627 return;
1628
1629 case -ESHUTDOWN: /* transport endpoint was shut down */
1630 break;
1631
1632 case 0:
1633 imon_incoming_packet(ictx, urb, intfnum);
1634 break;
1635
1636 default:
1637 dev_warn(ictx->dev, "imon %s: status(%d): ignored\n",
1638 __func__, urb->status);
1639 break;
1640 }
1641
1642 usb_submit_urb(ictx->rx_urb_intf0, GFP_ATOMIC);
1643}
1644
1645static void usb_rx_callback_intf1(struct urb *urb)
1646{
1647 struct imon_context *ictx;
1648 int intfnum = 1;
1649
1650 if (!urb)
1651 return;
1652
1653 ictx = (struct imon_context *)urb->context;
1654 if (!ictx)
1655 return;
1656
1657 switch (urb->status) {
1658 case -ENOENT: /* usbcore unlink successful! */
1659 return;
1660
1661 case -ESHUTDOWN: /* transport endpoint was shut down */
1662 break;
1663
1664 case 0:
1665 imon_incoming_packet(ictx, urb, intfnum);
1666 break;
1667
1668 default:
1669 dev_warn(ictx->dev, "imon %s: status(%d): ignored\n",
1670 __func__, urb->status);
1671 break;
1672 }
1673
1674 usb_submit_urb(ictx->rx_urb_intf1, GFP_ATOMIC);
1675}
1676
1677static struct input_dev *imon_init_idev(struct imon_context *ictx)
1678{
1679 struct input_dev *idev;
1680 struct ir_dev_props *props;
1681 struct ir_input_dev *ir;
1682 int ret, i;
1683 char *ir_codes = NULL;
1684
1685 if (ir_protocol == IMON_IR_PROTOCOL_MCE)
1686 ir_codes = RC_MAP_IMON_MCE;
1687 else
1688 ir_codes = RC_MAP_IMON_PAD;
1689
1690 idev = input_allocate_device();
1691 if (!idev) {
1692 dev_err(ictx->dev, "remote input dev allocation failed\n");
1693 goto idev_alloc_failed;
1694 }
1695
1696 props = kzalloc(sizeof(struct ir_dev_props), GFP_KERNEL);
1697 if (!props) {
1698 dev_err(ictx->dev, "remote ir dev props allocation failed\n");
1699 goto props_alloc_failed;
1700 }
1701
1702 ir = kzalloc(sizeof(struct ir_input_dev), GFP_KERNEL);
1703 if (!props) {
1704 dev_err(ictx->dev, "remote ir input dev allocation failed\n");
1705 goto ir_dev_alloc_failed;
1706 }
1707
1708 snprintf(ictx->name_idev, sizeof(ictx->name_idev),
1709 "iMON Remote (%04x:%04x)", ictx->vendor, ictx->product);
1710 idev->name = ictx->name_idev;
1711
1712 usb_make_path(ictx->usbdev_intf0, ictx->phys_idev,
1713 sizeof(ictx->phys_idev));
1714 strlcat(ictx->phys_idev, "/input0", sizeof(ictx->phys_idev));
1715 idev->phys = ictx->phys_idev;
1716
1717 idev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL);
1718
1719 idev->keybit[BIT_WORD(BTN_MOUSE)] =
1720 BIT_MASK(BTN_LEFT) | BIT_MASK(BTN_RIGHT);
1721 idev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y) |
1722 BIT_MASK(REL_WHEEL);
1723
1724 /* panel and/or knob code support */
1725 for (i = 0; i < ARRAY_SIZE(imon_panel_key_table); i++) {
1726 u32 kc = imon_panel_key_table[i].keycode;
1727 __set_bit(kc, idev->keybit);
1728 }
1729
1730 props->driver_type = RC_DRIVER_SCANCODE;
1731 props->allowed_protos = IR_TYPE_UNKNOWN;
1732
1733 ictx->ir = ir;
1734 memcpy(&ir->dev, ictx->dev, sizeof(struct device));
1735
1736 usb_to_input_id(ictx->usbdev_intf0, &idev->id);
1737 idev->dev.parent = ictx->dev;
1738
1739 input_set_drvdata(idev, ir);
1740
1741 ret = ir_input_register(idev, ir_codes, props, MOD_NAME);
1742 if (ret < 0) {
1743 dev_err(ictx->dev, "remote input dev register failed\n");
1744 goto idev_register_failed;
1745 }
1746
1747 return idev;
1748
1749idev_register_failed:
1750 kfree(ir);
1751ir_dev_alloc_failed:
1752 kfree(props);
1753props_alloc_failed:
1754 input_free_device(idev);
1755idev_alloc_failed:
1756
1757 return NULL;
1758}
1759
1760static struct input_dev *imon_init_touch(struct imon_context *ictx)
1761{
1762 struct input_dev *touch;
1763 int ret;
1764
1765 touch = input_allocate_device();
1766 if (!touch) {
1767 dev_err(ictx->dev, "touchscreen input dev allocation failed\n");
1768 goto touch_alloc_failed;
1769 }
1770
1771 snprintf(ictx->name_touch, sizeof(ictx->name_touch),
1772 "iMON USB Touchscreen (%04x:%04x)",
1773 ictx->vendor, ictx->product);
1774 touch->name = ictx->name_touch;
1775
1776 usb_make_path(ictx->usbdev_intf1, ictx->phys_touch,
1777 sizeof(ictx->phys_touch));
1778 strlcat(ictx->phys_touch, "/input1", sizeof(ictx->phys_touch));
1779 touch->phys = ictx->phys_touch;
1780
1781 touch->evbit[0] =
1782 BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
1783 touch->keybit[BIT_WORD(BTN_TOUCH)] =
1784 BIT_MASK(BTN_TOUCH);
1785 input_set_abs_params(touch, ABS_X,
1786 0x00, 0xfff, 0, 0);
1787 input_set_abs_params(touch, ABS_Y,
1788 0x00, 0xfff, 0, 0);
1789
1790 input_set_drvdata(touch, ictx);
1791
1792 usb_to_input_id(ictx->usbdev_intf1, &touch->id);
1793 touch->dev.parent = ictx->dev;
1794 ret = input_register_device(touch);
1795 if (ret < 0) {
1796 dev_info(ictx->dev, "touchscreen input dev register failed\n");
1797 goto touch_register_failed;
1798 }
1799
1800 return touch;
1801
1802touch_register_failed:
1803 input_free_device(ictx->touch);
1804 mutex_unlock(&ictx->lock);
1805
1806touch_alloc_failed:
1807 return NULL;
1808}
1809
1810static bool imon_find_endpoints(struct imon_context *ictx,
1811 struct usb_host_interface *iface_desc)
1812{
1813 struct usb_endpoint_descriptor *ep;
1814 struct usb_endpoint_descriptor *rx_endpoint = NULL;
1815 struct usb_endpoint_descriptor *tx_endpoint = NULL;
1816 int ifnum = iface_desc->desc.bInterfaceNumber;
1817 int num_endpts = iface_desc->desc.bNumEndpoints;
1818 int i, ep_dir, ep_type;
1819 bool ir_ep_found = 0;
1820 bool display_ep_found = 0;
1821 bool tx_control = 0;
1822
1823 /*
1824 * Scan the endpoint list and set:
1825 * first input endpoint = IR endpoint
1826 * first output endpoint = display endpoint
1827 */
1828 for (i = 0; i < num_endpts && !(ir_ep_found && display_ep_found); ++i) {
1829 ep = &iface_desc->endpoint[i].desc;
1830 ep_dir = ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK;
1831 ep_type = ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK;
1832
1833 if (!ir_ep_found && ep_dir == USB_DIR_IN &&
1834 ep_type == USB_ENDPOINT_XFER_INT) {
1835
1836 rx_endpoint = ep;
1837 ir_ep_found = 1;
1838 dev_dbg(ictx->dev, "%s: found IR endpoint\n", __func__);
1839
1840 } else if (!display_ep_found && ep_dir == USB_DIR_OUT &&
1841 ep_type == USB_ENDPOINT_XFER_INT) {
1842 tx_endpoint = ep;
1843 display_ep_found = 1;
1844 dev_dbg(ictx->dev, "%s: found display endpoint\n", __func__);
1845 }
1846 }
1847
1848 if (ifnum == 0) {
1849 ictx->rx_endpoint_intf0 = rx_endpoint;
1850 /*
1851 * tx is used to send characters to lcd/vfd, associate RF
1852 * remotes, set IR protocol, and maybe more...
1853 */
1854 ictx->tx_endpoint = tx_endpoint;
1855 } else {
1856 ictx->rx_endpoint_intf1 = rx_endpoint;
1857 }
1858
1859 /*
1860 * If we didn't find a display endpoint, this is probably one of the
1861 * newer iMON devices that use control urb instead of interrupt
1862 */
1863 if (!display_ep_found) {
1864 tx_control = 1;
1865 display_ep_found = 1;
1866 dev_dbg(ictx->dev, "%s: device uses control endpoint, not "
1867 "interface OUT endpoint\n", __func__);
1868 }
1869
1870 /*
1871 * Some iMON receivers have no display. Unfortunately, it seems
1872 * that SoundGraph recycles device IDs between devices both with
1873 * and without... :\
1874 */
1875 if (ictx->display_type == IMON_DISPLAY_TYPE_NONE) {
1876 display_ep_found = 0;
1877 dev_dbg(ictx->dev, "%s: device has no display\n", __func__);
1878 }
1879
1880 /*
1881 * iMON Touch devices have a VGA touchscreen, but no "display", as
1882 * that refers to e.g. /dev/lcd0 (a character device LCD or VFD).
1883 */
1884 if (ictx->display_type == IMON_DISPLAY_TYPE_VGA) {
1885 display_ep_found = 0;
1886 dev_dbg(ictx->dev, "%s: iMON Touch device found\n", __func__);
1887 }
1888
1889 /* Input endpoint is mandatory */
1890 if (!ir_ep_found)
1891 err("%s: no valid input (IR) endpoint found.", __func__);
1892
1893 ictx->tx_control = tx_control;
1894
1895 if (display_ep_found)
1896 ictx->display_supported = true;
1897
1898 return ir_ep_found;
1899
1900}
1901
1902static struct imon_context *imon_init_intf0(struct usb_interface *intf)
1903{
1904 struct imon_context *ictx;
1905 struct urb *rx_urb;
1906 struct urb *tx_urb;
1907 struct device *dev = &intf->dev;
1908 struct usb_host_interface *iface_desc;
1909 int ret;
1910
1911 ictx = kzalloc(sizeof(struct imon_context), GFP_KERNEL);
1912 if (!ictx) {
1913 dev_err(dev, "%s: kzalloc failed for context", __func__);
1914 goto exit;
1915 }
1916 rx_urb = usb_alloc_urb(0, GFP_KERNEL);
1917 if (!rx_urb) {
1918 dev_err(dev, "%s: usb_alloc_urb failed for IR urb", __func__);
1919 goto rx_urb_alloc_failed;
1920 }
1921 tx_urb = usb_alloc_urb(0, GFP_KERNEL);
1922 if (!tx_urb) {
1923 dev_err(dev, "%s: usb_alloc_urb failed for display urb",
1924 __func__);
1925 goto tx_urb_alloc_failed;
1926 }
1927
1928 mutex_init(&ictx->lock);
1929
1930 mutex_lock(&ictx->lock);
1931
1932 ictx->dev = dev;
1933 ictx->usbdev_intf0 = usb_get_dev(interface_to_usbdev(intf));
1934 ictx->dev_present_intf0 = 1;
1935 ictx->rx_urb_intf0 = rx_urb;
1936 ictx->tx_urb = tx_urb;
1937
1938 ictx->vendor = le16_to_cpu(ictx->usbdev_intf0->descriptor.idVendor);
1939 ictx->product = le16_to_cpu(ictx->usbdev_intf0->descriptor.idProduct);
1940
1941 iface_desc = intf->cur_altsetting;
1942 if (!imon_find_endpoints(ictx, iface_desc))
1943 goto find_endpoint_failed;
1944
1945 ictx->idev = imon_init_idev(ictx);
1946 if (!ictx->idev) {
1947 dev_err(dev, "%s: input device setup failed\n", __func__);
1948 goto idev_setup_failed;
1949 }
1950
1951 usb_fill_int_urb(ictx->rx_urb_intf0, ictx->usbdev_intf0,
1952 usb_rcvintpipe(ictx->usbdev_intf0,
1953 ictx->rx_endpoint_intf0->bEndpointAddress),
1954 ictx->usb_rx_buf, sizeof(ictx->usb_rx_buf),
1955 usb_rx_callback_intf0, ictx,
1956 ictx->rx_endpoint_intf0->bInterval);
1957
1958 ret = usb_submit_urb(ictx->rx_urb_intf0, GFP_KERNEL);
1959 if (ret) {
1960 err("%s: usb_submit_urb failed for intf0 (%d)",
1961 __func__, ret);
1962 goto urb_submit_failed;
1963 }
1964
1965 return ictx;
1966
1967urb_submit_failed:
1968 input_unregister_device(ictx->idev);
1969 input_free_device(ictx->idev);
1970idev_setup_failed:
1971find_endpoint_failed:
1972 mutex_unlock(&ictx->lock);
1973 usb_free_urb(tx_urb);
1974tx_urb_alloc_failed:
1975 usb_free_urb(rx_urb);
1976rx_urb_alloc_failed:
1977 kfree(ictx);
1978exit:
1979 dev_err(dev, "unable to initialize intf0, err %d\n", ret);
1980
1981 return NULL;
1982}
1983
1984static struct imon_context *imon_init_intf1(struct usb_interface *intf,
1985 struct imon_context *ictx)
1986{
1987 struct urb *rx_urb;
1988 struct usb_host_interface *iface_desc;
1989 int ret;
1990
1991 rx_urb = usb_alloc_urb(0, GFP_KERNEL);
1992 if (!rx_urb) {
1993 err("%s: usb_alloc_urb failed for IR urb", __func__);
1994 ret = -ENOMEM;
1995 goto rx_urb_alloc_failed;
1996 }
1997
1998 mutex_lock(&ictx->lock);
1999
2000 if (ictx->display_type == IMON_DISPLAY_TYPE_VGA) {
2001 init_timer(&ictx->ttimer);
2002 ictx->ttimer.data = (unsigned long)ictx;
2003 ictx->ttimer.function = imon_touch_display_timeout;
2004 }
2005
2006 ictx->usbdev_intf1 = usb_get_dev(interface_to_usbdev(intf));
2007 ictx->dev_present_intf1 = 1;
2008 ictx->rx_urb_intf1 = rx_urb;
2009
2010 iface_desc = intf->cur_altsetting;
2011 if (!imon_find_endpoints(ictx, iface_desc))
2012 goto find_endpoint_failed;
2013
2014 if (ictx->display_type == IMON_DISPLAY_TYPE_VGA) {
2015 ictx->touch = imon_init_touch(ictx);
2016 if (!ictx->touch)
2017 goto touch_setup_failed;
2018 } else
2019 ictx->touch = NULL;
2020
2021 usb_fill_int_urb(ictx->rx_urb_intf1, ictx->usbdev_intf1,
2022 usb_rcvintpipe(ictx->usbdev_intf1,
2023 ictx->rx_endpoint_intf1->bEndpointAddress),
2024 ictx->usb_rx_buf, sizeof(ictx->usb_rx_buf),
2025 usb_rx_callback_intf1, ictx,
2026 ictx->rx_endpoint_intf1->bInterval);
2027
2028 ret = usb_submit_urb(ictx->rx_urb_intf1, GFP_KERNEL);
2029
2030 if (ret) {
2031 err("%s: usb_submit_urb failed for intf1 (%d)",
2032 __func__, ret);
2033 goto urb_submit_failed;
2034 }
2035
2036 return ictx;
2037
2038urb_submit_failed:
2039 if (ictx->touch) {
2040 input_unregister_device(ictx->touch);
2041 input_free_device(ictx->touch);
2042 }
2043touch_setup_failed:
2044find_endpoint_failed:
2045 mutex_unlock(&ictx->lock);
2046 usb_free_urb(rx_urb);
2047rx_urb_alloc_failed:
2048 dev_err(ictx->dev, "unable to initialize intf0, err %d\n", ret);
2049
2050 return NULL;
2051}
2052
2053/*
2054 * The 0x15c2:0xffdc device ID was used for umpteen different imon
2055 * devices, and all of them constantly spew interrupts, even when there
2056 * is no actual data to report. However, byte 6 of this buffer looks like
2057 * its unique across device variants, so we're trying to key off that to
2058 * figure out which display type (if any) and what IR protocol the device
2059 * actually supports.
2060 */
2061static void imon_get_ffdc_type(struct imon_context *ictx)
2062{
2063 u8 ffdc_cfg_byte = ictx->usb_rx_buf[6];
2064 u8 detected_display_type = IMON_DISPLAY_TYPE_NONE;
2065 u8 ir_proto_mask = IMON_IR_PROTO_MASK_IMON;
2066
2067 switch (ffdc_cfg_byte) {
2068 /* iMON Knob, no display, iMON IR + vol knob */
2069 case 0x21:
2070 dev_info(ictx->dev, "0xffdc iMON Knob, iMON IR");
2071 ictx->display_supported = false;
2072 break;
2073 /* iMON VFD, no IR (does have vol knob tho) */
2074 case 0x35:
2075 dev_info(ictx->dev, "0xffdc iMON VFD + knob, no IR");
2076 detected_display_type = IMON_DISPLAY_TYPE_VFD;
2077 ir_proto_mask = IMON_IR_PROTO_MASK_NONE;
2078 break;
2079 /* iMON VFD, iMON IR */
2080 case 0x24:
2081 case 0x85:
2082 dev_info(ictx->dev, "0xffdc iMON VFD, iMON IR");
2083 detected_display_type = IMON_DISPLAY_TYPE_VFD;
2084 break;
2085 /* iMON LCD, MCE IR */
2086 case 0x9f:
2087 dev_info(ictx->dev, "0xffdc iMON LCD, MCE IR");
2088 detected_display_type = IMON_DISPLAY_TYPE_LCD;
2089 ir_proto_mask = IMON_IR_PROTO_MASK_MCE;
2090 break;
2091 default:
2092 dev_info(ictx->dev, "Unknown 0xffdc device, "
2093 "defaulting to VFD and iMON IR");
2094 detected_display_type = IMON_DISPLAY_TYPE_VFD;
2095 break;
2096 }
2097
2098 printk(" (id 0x%02x)\n", ffdc_cfg_byte);
2099
2100 ictx->display_type = detected_display_type;
2101 ictx->ir_proto_mask = ir_proto_mask;
2102}
2103
2104static void imon_set_display_type(struct imon_context *ictx,
2105 struct usb_interface *intf)
2106{
2107 u8 configured_display_type = IMON_DISPLAY_TYPE_VFD;
2108
2109 /*
2110 * Try to auto-detect the type of display if the user hasn't set
2111 * it by hand via the display_type modparam. Default is VFD.
2112 */
2113
2114 if (display_type == IMON_DISPLAY_TYPE_AUTO) {
2115 switch (ictx->product) {
2116 case 0xffdc:
2117 /* set in imon_get_ffdc_type() */
2118 configured_display_type = ictx->display_type;
2119 break;
2120 case 0x0034:
2121 case 0x0035:
2122 configured_display_type = IMON_DISPLAY_TYPE_VGA;
2123 break;
2124 case 0x0038:
2125 case 0x0039:
2126 case 0x0045:
2127 configured_display_type = IMON_DISPLAY_TYPE_LCD;
2128 break;
2129 case 0x003c:
2130 case 0x0041:
2131 case 0x0042:
2132 case 0x0043:
2133 configured_display_type = IMON_DISPLAY_TYPE_NONE;
2134 ictx->display_supported = false;
2135 break;
2136 case 0x0036:
2137 case 0x0044:
2138 default:
2139 configured_display_type = IMON_DISPLAY_TYPE_VFD;
2140 break;
2141 }
2142 } else {
2143 configured_display_type = display_type;
2144 if (display_type == IMON_DISPLAY_TYPE_NONE)
2145 ictx->display_supported = false;
2146 else
2147 ictx->display_supported = true;
2148 dev_info(ictx->dev, "%s: overriding display type to %d via "
2149 "modparam\n", __func__, display_type);
2150 }
2151
2152 ictx->display_type = configured_display_type;
2153}
2154
2155static void imon_init_display(struct imon_context *ictx,
2156 struct usb_interface *intf)
2157{
2158 int ret;
2159
2160 dev_dbg(ictx->dev, "Registering iMON display with sysfs\n");
2161
2162 /* set up sysfs entry for built-in clock */
2163 ret = sysfs_create_group(&intf->dev.kobj,
2164 &imon_display_attribute_group);
2165 if (ret)
2166 dev_err(ictx->dev, "Could not create display sysfs "
2167 "entries(%d)", ret);
2168
2169 if (ictx->display_type == IMON_DISPLAY_TYPE_LCD)
2170 ret = usb_register_dev(intf, &imon_lcd_class);
2171 else
2172 ret = usb_register_dev(intf, &imon_vfd_class);
2173 if (ret)
2174 /* Not a fatal error, so ignore */
2175 dev_info(ictx->dev, "could not get a minor number for "
2176 "display\n");
2177
2178}
2179
2180/**
2181 * Callback function for USB core API: Probe
2182 */
2183static int __devinit imon_probe(struct usb_interface *interface,
2184 const struct usb_device_id *id)
2185{
2186 struct usb_device *usbdev = NULL;
2187 struct usb_host_interface *iface_desc = NULL;
2188 struct usb_interface *first_if;
2189 struct device *dev = &interface->dev;
2190 int ifnum, code_length, sysfs_err;
2191 int ret = 0;
2192 struct imon_context *ictx = NULL;
2193 struct imon_context *first_if_ctx = NULL;
2194 u16 vendor, product;
2195 const unsigned char fp_packet[] = { 0x40, 0x00, 0x00, 0x00,
2196 0x00, 0x00, 0x00, 0x88 };
2197
2198 code_length = BUF_CHUNK_SIZE * 8;
2199
2200 usbdev = usb_get_dev(interface_to_usbdev(interface));
2201 iface_desc = interface->cur_altsetting;
2202 ifnum = iface_desc->desc.bInterfaceNumber;
2203 vendor = le16_to_cpu(usbdev->descriptor.idVendor);
2204 product = le16_to_cpu(usbdev->descriptor.idProduct);
2205
2206 dev_dbg(dev, "%s: found iMON device (%04x:%04x, intf%d)\n",
2207 __func__, vendor, product, ifnum);
2208
2209 /* prevent races probing devices w/multiple interfaces */
2210 mutex_lock(&driver_lock);
2211
2212 first_if = usb_ifnum_to_if(usbdev, 0);
2213 first_if_ctx = (struct imon_context *)usb_get_intfdata(first_if);
2214
2215 if (ifnum == 0) {
2216 ictx = imon_init_intf0(interface);
2217 if (!ictx) {
2218 err("%s: failed to initialize context!\n", __func__);
2219 ret = -ENODEV;
2220 goto fail;
2221 }
2222
2223 if (product == 0xffdc) {
2224 /* RF products *also* use 0xffdc... sigh... */
2225 sysfs_err = sysfs_create_group(&interface->dev.kobj,
2226 &imon_rf_attribute_group);
2227 if (sysfs_err)
2228 err("%s: Could not create RF sysfs entries(%d)",
2229 __func__, sysfs_err);
2230 }
2231
2232 } else {
2233 /* this is the secondary interface on the device */
2234 ictx = imon_init_intf1(interface, first_if_ctx);
2235 if (!ictx) {
2236 err("%s: failed to attach to context!\n", __func__);
2237 ret = -ENODEV;
2238 goto fail;
2239 }
2240
2241 }
2242
2243 usb_set_intfdata(interface, ictx);
2244
2245 if (ifnum == 0) {
2246 /* Enable front-panel buttons and/or knobs */
2247 memcpy(ictx->usb_tx_buf, &fp_packet, sizeof(fp_packet));
2248 ret = send_packet(ictx);
2249 /* Not fatal, but warn about it */
2250 if (ret)
2251 dev_info(dev, "failed to enable panel buttons "
2252 "and/or knobs\n");
2253
2254 if (product == 0xffdc)
2255 imon_get_ffdc_type(ictx);
2256 else
2257 ictx->ir_proto_mask = IMON_IR_PROTO_MASK_MCE |
2258 IMON_IR_PROTO_MASK_IMON;
2259
2260 imon_set_display_type(ictx, interface);
2261
2262 if (ictx->display_supported)
2263 imon_init_display(ictx, interface);
2264 }
2265
2266 /* set IR protocol/remote type */
2267 imon_set_ir_protocol(ictx);
2268
2269 dev_info(dev, "iMON device (%04x:%04x, intf%d) on "
2270 "usb<%d:%d> initialized\n", vendor, product, ifnum,
2271 usbdev->bus->busnum, usbdev->devnum);
2272
2273 mutex_unlock(&ictx->lock);
2274 mutex_unlock(&driver_lock);
2275
2276 return 0;
2277
2278fail:
2279 mutex_unlock(&driver_lock);
2280 dev_err(dev, "unable to register, err %d\n", ret);
2281
2282 return ret;
2283}
2284
2285/**
2286 * Callback function for USB core API: disconnect
2287 */
2288static void __devexit imon_disconnect(struct usb_interface *interface)
2289{
2290 struct imon_context *ictx;
2291 struct device *dev;
2292 int ifnum;
2293
2294 /* prevent races with multi-interface device probing and display_open */
2295 mutex_lock(&driver_lock);
2296
2297 ictx = usb_get_intfdata(interface);
2298 dev = ictx->dev;
2299 ifnum = interface->cur_altsetting->desc.bInterfaceNumber;
2300
2301 mutex_lock(&ictx->lock);
2302
2303 /*
2304 * sysfs_remove_group is safe to call even if sysfs_create_group
2305 * hasn't been called
2306 */
2307 sysfs_remove_group(&interface->dev.kobj,
2308 &imon_display_attribute_group);
2309 sysfs_remove_group(&interface->dev.kobj,
2310 &imon_rf_attribute_group);
2311
2312 usb_set_intfdata(interface, NULL);
2313
2314 /* Abort ongoing write */
2315 if (ictx->tx.busy) {
2316 usb_kill_urb(ictx->tx_urb);
2317 complete_all(&ictx->tx.finished);
2318 }
2319
2320 if (ifnum == 0) {
2321 ictx->dev_present_intf0 = 0;
2322 usb_kill_urb(ictx->rx_urb_intf0);
2323 input_unregister_device(ictx->idev);
2324 if (ictx->display_supported) {
2325 if (ictx->display_type == IMON_DISPLAY_TYPE_LCD)
2326 usb_deregister_dev(interface, &imon_lcd_class);
2327 else
2328 usb_deregister_dev(interface, &imon_vfd_class);
2329 }
2330 } else {
2331 ictx->dev_present_intf1 = 0;
2332 usb_kill_urb(ictx->rx_urb_intf1);
2333 if (ictx->display_type == IMON_DISPLAY_TYPE_VGA)
2334 input_unregister_device(ictx->touch);
2335 }
2336
2337 if (!ictx->dev_present_intf0 && !ictx->dev_present_intf1) {
2338 if (ictx->display_type == IMON_DISPLAY_TYPE_VGA)
2339 del_timer_sync(&ictx->ttimer);
2340 mutex_unlock(&ictx->lock);
2341 if (!ictx->display_isopen)
2342 free_imon_context(ictx);
2343 } else {
2344 if (ictx->ir_protocol == IMON_IR_PROTOCOL_MCE)
2345 del_timer_sync(&ictx->itimer);
2346 mutex_unlock(&ictx->lock);
2347 }
2348
2349 mutex_unlock(&driver_lock);
2350
2351 dev_dbg(dev, "%s: iMON device (intf%d) disconnected\n",
2352 __func__, ifnum);
2353}
2354
2355static int imon_suspend(struct usb_interface *intf, pm_message_t message)
2356{
2357 struct imon_context *ictx = usb_get_intfdata(intf);
2358 int ifnum = intf->cur_altsetting->desc.bInterfaceNumber;
2359
2360 if (ifnum == 0)
2361 usb_kill_urb(ictx->rx_urb_intf0);
2362 else
2363 usb_kill_urb(ictx->rx_urb_intf1);
2364
2365 return 0;
2366}
2367
2368static int imon_resume(struct usb_interface *intf)
2369{
2370 int rc = 0;
2371 struct imon_context *ictx = usb_get_intfdata(intf);
2372 int ifnum = intf->cur_altsetting->desc.bInterfaceNumber;
2373
2374 if (ifnum == 0) {
2375 usb_fill_int_urb(ictx->rx_urb_intf0, ictx->usbdev_intf0,
2376 usb_rcvintpipe(ictx->usbdev_intf0,
2377 ictx->rx_endpoint_intf0->bEndpointAddress),
2378 ictx->usb_rx_buf, sizeof(ictx->usb_rx_buf),
2379 usb_rx_callback_intf0, ictx,
2380 ictx->rx_endpoint_intf0->bInterval);
2381
2382 rc = usb_submit_urb(ictx->rx_urb_intf0, GFP_ATOMIC);
2383
2384 } else {
2385 usb_fill_int_urb(ictx->rx_urb_intf1, ictx->usbdev_intf1,
2386 usb_rcvintpipe(ictx->usbdev_intf1,
2387 ictx->rx_endpoint_intf1->bEndpointAddress),
2388 ictx->usb_rx_buf, sizeof(ictx->usb_rx_buf),
2389 usb_rx_callback_intf1, ictx,
2390 ictx->rx_endpoint_intf1->bInterval);
2391
2392 rc = usb_submit_urb(ictx->rx_urb_intf1, GFP_ATOMIC);
2393 }
2394
2395 return rc;
2396}
2397
2398static int __init imon_init(void)
2399{
2400 int rc;
2401
2402 rc = usb_register(&imon_driver);
2403 if (rc) {
2404 err("%s: usb register failed(%d)", __func__, rc);
2405 rc = -ENODEV;
2406 }
2407
2408 return rc;
2409}
2410
2411static void __exit imon_exit(void)
2412{
2413 usb_deregister(&imon_driver);
2414}
2415
2416module_init(imon_init);
2417module_exit(imon_exit);