Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
lirc_imon.c
Go to the documentation of this file.
1 /*
2  * lirc_imon.c: LIRC/VFD/LCD driver for SoundGraph iMON IR/VFD/LCD
3  * including the iMON PAD model
4  *
5  * Copyright(C) 2004 Venky Raju([email protected])
6  * Copyright(C) 2009 Jarod Wilson <[email protected]>
7  *
8  * lirc_imon is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21  */
22 
23 #include <linux/errno.h>
24 #include <linux/init.h>
25 #include <linux/kernel.h>
26 #include <linux/module.h>
27 #include <linux/slab.h>
28 #include <linux/uaccess.h>
29 #include <linux/usb.h>
30 
31 #include <media/lirc.h>
32 #include <media/lirc_dev.h>
33 
34 
35 #define MOD_AUTHOR "Venky Raju <[email protected]>"
36 #define MOD_DESC "Driver for SoundGraph iMON MultiMedia IR/Display"
37 #define MOD_NAME "lirc_imon"
38 #define MOD_VERSION "0.8"
39 
40 #define DISPLAY_MINOR_BASE 144
41 #define DEVICE_NAME "lcd%d"
42 
43 #define BUF_CHUNK_SIZE 4
44 #define BUF_SIZE 128
45 
46 #define BIT_DURATION 250 /* each bit received is 250us */
47 
48 /*** P R O T O T Y P E S ***/
49 
50 /* USB Callback prototypes */
51 static int imon_probe(struct usb_interface *interface,
52  const struct usb_device_id *id);
53 static void imon_disconnect(struct usb_interface *interface);
54 static void usb_rx_callback(struct urb *urb);
55 static void usb_tx_callback(struct urb *urb);
56 
57 /* suspend/resume support */
58 static int imon_resume(struct usb_interface *intf);
59 static int imon_suspend(struct usb_interface *intf, pm_message_t message);
60 
61 /* Display file_operations function prototypes */
62 static int display_open(struct inode *inode, struct file *file);
63 static int display_close(struct inode *inode, struct file *file);
64 
65 /* VFD write operation */
66 static ssize_t vfd_write(struct file *file, const char __user *buf,
67  size_t n_bytes, loff_t *pos);
68 
69 /* LIRC driver function prototypes */
70 static int ir_open(void *data);
71 static void ir_close(void *data);
72 
73 /*** G L O B A L S ***/
74 #define IMON_DATA_BUF_SZ 35
75 
76 struct imon_context {
77  struct usb_device *usbdev;
78  /* Newer devices have two interfaces */
79  int display; /* not all controllers do */
80  int display_isopen; /* display port has been opened */
81  int ir_isopen; /* IR port open */
82  int dev_present; /* USB device presence */
83  struct mutex ctx_lock; /* to lock this object */
84  wait_queue_head_t remove_ok; /* For unexpected USB disconnects */
85 
86  int vfd_proto_6p; /* some VFD require a 6th packet */
87 
91  struct urb *rx_urb;
92  struct urb *tx_urb;
93  unsigned char usb_rx_buf[8];
94  unsigned char usb_tx_buf[8];
95 
96  struct rx_data {
97  int count; /* length of 0 or 1 sequence */
98  int prev_bit; /* logic level of sequence */
99  int initial_space; /* initial space flag */
100  } rx;
101 
102  struct tx_t {
103  unsigned char data_buf[IMON_DATA_BUF_SZ]; /* user data buffer */
104  struct completion finished; /* wait for write to finish */
105  atomic_t busy; /* write in progress */
106  int status; /* status of tx completion */
107  } tx;
108 };
109 
110 static const struct file_operations display_fops = {
111  .owner = THIS_MODULE,
112  .open = &display_open,
113  .write = &vfd_write,
114  .release = &display_close,
115  .llseek = noop_llseek,
116 };
117 
118 /*
119  * USB Device ID for iMON USB Control Boards
120  *
121  * The Windows drivers contain 6 different inf files, more or less one for
122  * each new device until the 0x0034-0x0046 devices, which all use the same
123  * driver. Some of the devices in the 34-46 range haven't been definitively
124  * identified yet. Early devices have either a TriGem Computer, Inc. or a
125  * Samsung vendor ID (0x0aa8 and 0x04e8 respectively), while all later
126  * devices use the SoundGraph vendor ID (0x15c2).
127  */
128 static struct usb_device_id imon_usb_id_table[] = {
129  /* TriGem iMON (IR only) -- TG_iMON.inf */
130  { USB_DEVICE(0x0aa8, 0x8001) },
131 
132  /* SoundGraph iMON (IR only) -- sg_imon.inf */
133  { USB_DEVICE(0x04e8, 0xff30) },
134 
135  /* SoundGraph iMON VFD (IR & VFD) -- iMON_VFD.inf */
136  { USB_DEVICE(0x0aa8, 0xffda) },
137 
138  /* SoundGraph iMON SS (IR & VFD) -- iMON_SS.inf */
139  { USB_DEVICE(0x15c2, 0xffda) },
140 
141  {}
142 };
143 
144 /* Some iMON VFD models requires a 6th packet for VFD writes */
145 static struct usb_device_id vfd_proto_6p_list[] = {
146  { USB_DEVICE(0x15c2, 0xffda) },
147  {}
148 };
149 
150 /* Some iMON devices have no lcd/vfd, don't set one up */
151 static struct usb_device_id ir_only_list[] = {
152  { USB_DEVICE(0x0aa8, 0x8001) },
153  { USB_DEVICE(0x04e8, 0xff30) },
154  {}
155 };
156 
157 /* USB Device data */
158 static struct usb_driver imon_driver = {
159  .name = MOD_NAME,
160  .probe = imon_probe,
161  .disconnect = imon_disconnect,
162  .suspend = imon_suspend,
163  .resume = imon_resume,
164  .id_table = imon_usb_id_table,
165 };
166 
167 static struct usb_class_driver imon_class = {
168  .name = DEVICE_NAME,
169  .fops = &display_fops,
170  .minor_base = DISPLAY_MINOR_BASE,
171 };
172 
173 /* to prevent races between open() and disconnect(), probing, etc */
174 static DEFINE_MUTEX(driver_lock);
175 
176 static int debug;
177 
178 /*** M O D U L E C O D E ***/
179 
183 MODULE_LICENSE("GPL");
184 MODULE_DEVICE_TABLE(usb, imon_usb_id_table);
186 MODULE_PARM_DESC(debug, "Debug messages: 0=no, 1=yes(default: no)");
187 
188 static void free_imon_context(struct imon_context *context)
189 {
190  struct device *dev = context->driver->dev;
191  usb_free_urb(context->tx_urb);
192  usb_free_urb(context->rx_urb);
193  lirc_buffer_free(context->driver->rbuf);
194  kfree(context->driver->rbuf);
195  kfree(context->driver);
196  kfree(context);
197 
198  dev_dbg(dev, "%s: iMON context freed\n", __func__);
199 }
200 
201 static void deregister_from_lirc(struct imon_context *context)
202 {
203  int retval;
204  int minor = context->driver->minor;
205 
206  retval = lirc_unregister_driver(minor);
207  if (retval)
208  printk(KERN_ERR KBUILD_MODNAME
209  ": %s: unable to deregister from lirc(%d)",
210  __func__, retval);
211  else
212  printk(KERN_INFO MOD_NAME ": Deregistered iMON driver "
213  "(minor:%d)\n", minor);
214 
215 }
216 
221 static int display_open(struct inode *inode, struct file *file)
222 {
223  struct usb_interface *interface;
224  struct imon_context *context = NULL;
225  int subminor;
226  int retval = 0;
227 
228  /* prevent races with disconnect */
229  mutex_lock(&driver_lock);
230 
231  subminor = iminor(inode);
232  interface = usb_find_interface(&imon_driver, subminor);
233  if (!interface) {
234  printk(KERN_ERR KBUILD_MODNAME
235  ": %s: could not find interface for minor %d\n",
236  __func__, subminor);
237  retval = -ENODEV;
238  goto exit;
239  }
240  context = usb_get_intfdata(interface);
241 
242  if (!context) {
243  dev_err(&interface->dev,
244  "%s: no context found for minor %d\n",
245  __func__, subminor);
246  retval = -ENODEV;
247  goto exit;
248  }
249 
250  mutex_lock(&context->ctx_lock);
251 
252  if (!context->display) {
253  dev_err(&interface->dev,
254  "%s: display not supported by device\n", __func__);
255  retval = -ENODEV;
256  } else if (context->display_isopen) {
257  dev_err(&interface->dev,
258  "%s: display port is already open\n", __func__);
259  retval = -EBUSY;
260  } else {
261  context->display_isopen = 1;
262  file->private_data = context;
263  dev_info(context->driver->dev, "display port opened\n");
264  }
265 
266  mutex_unlock(&context->ctx_lock);
267 
268 exit:
269  mutex_unlock(&driver_lock);
270  return retval;
271 }
272 
277 static int display_close(struct inode *inode, struct file *file)
278 {
279  struct imon_context *context = NULL;
280  int retval = 0;
281 
282  context = file->private_data;
283 
284  if (!context) {
285  printk(KERN_ERR KBUILD_MODNAME
286  "%s: no context for device\n", __func__);
287  return -ENODEV;
288  }
289 
290  mutex_lock(&context->ctx_lock);
291 
292  if (!context->display) {
293  dev_err(&context->usbdev->dev,
294  "%s: display not supported by device\n", __func__);
295  retval = -ENODEV;
296  } else if (!context->display_isopen) {
297  dev_err(&context->usbdev->dev,
298  "%s: display is not open\n", __func__);
299  retval = -EIO;
300  } else {
301  context->display_isopen = 0;
302  dev_info(context->driver->dev, "display port closed\n");
303  if (!context->dev_present && !context->ir_isopen) {
304  /*
305  * Device disconnected before close and IR port is not
306  * open. If IR port is open, context will be deleted by
307  * ir_close.
308  */
309  mutex_unlock(&context->ctx_lock);
310  free_imon_context(context);
311  return retval;
312  }
313  }
314 
315  mutex_unlock(&context->ctx_lock);
316  return retval;
317 }
318 
323 static int send_packet(struct imon_context *context)
324 {
325  unsigned int pipe;
326  int interval = 0;
327  int retval = 0;
328 
329  /* Check if we need to use control or interrupt urb */
330  pipe = usb_sndintpipe(context->usbdev,
331  context->tx_endpoint->bEndpointAddress);
332  interval = context->tx_endpoint->bInterval;
333 
334  usb_fill_int_urb(context->tx_urb, context->usbdev, pipe,
335  context->usb_tx_buf,
336  sizeof(context->usb_tx_buf),
337  usb_tx_callback, context, interval);
338 
339  context->tx_urb->actual_length = 0;
340 
341  init_completion(&context->tx.finished);
342  atomic_set(&(context->tx.busy), 1);
343 
344  retval = usb_submit_urb(context->tx_urb, GFP_KERNEL);
345  if (retval) {
346  atomic_set(&(context->tx.busy), 0);
347  dev_err(&context->usbdev->dev,
348  "%s: error submitting urb(%d)\n", __func__, retval);
349  } else {
350  /* Wait for transmission to complete (or abort) */
351  mutex_unlock(&context->ctx_lock);
353  &context->tx.finished);
354  if (retval)
355  dev_err(&context->usbdev->dev,
356  "%s: task interrupted\n", __func__);
357  mutex_lock(&context->ctx_lock);
358 
359  retval = context->tx.status;
360  if (retval)
361  dev_err(&context->usbdev->dev,
362  "%s: packet tx failed (%d)\n",
363  __func__, retval);
364  }
365 
366  return retval;
367 }
368 
380 static ssize_t vfd_write(struct file *file, const char __user *buf,
381  size_t n_bytes, loff_t *pos)
382 {
383  int i;
384  int offset;
385  int seq;
386  int retval = 0;
387  struct imon_context *context;
388  const unsigned char vfd_packet6[] = {
389  0x01, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF };
390  int *data_buf = NULL;
391 
392  context = file->private_data;
393  if (!context) {
394  printk(KERN_ERR KBUILD_MODNAME
395  "%s: no context for device\n", __func__);
396  return -ENODEV;
397  }
398 
399  mutex_lock(&context->ctx_lock);
400 
401  if (!context->dev_present) {
402  dev_err(&context->usbdev->dev,
403  "%s: no iMON device present\n", __func__);
404  retval = -ENODEV;
405  goto exit;
406  }
407 
408  if (n_bytes <= 0 || n_bytes > IMON_DATA_BUF_SZ - 3) {
409  dev_err(&context->usbdev->dev,
410  "%s: invalid payload size\n", __func__);
411  retval = -EINVAL;
412  goto exit;
413  }
414 
415  data_buf = memdup_user(buf, n_bytes);
416  if (IS_ERR(data_buf)) {
417  retval = PTR_ERR(data_buf);
418  goto exit;
419  }
420 
421  memcpy(context->tx.data_buf, data_buf, n_bytes);
422 
423  /* Pad with spaces */
424  for (i = n_bytes; i < IMON_DATA_BUF_SZ - 3; ++i)
425  context->tx.data_buf[i] = ' ';
426 
427  for (i = IMON_DATA_BUF_SZ - 3; i < IMON_DATA_BUF_SZ; ++i)
428  context->tx.data_buf[i] = 0xFF;
429 
430  offset = 0;
431  seq = 0;
432 
433  do {
434  memcpy(context->usb_tx_buf, context->tx.data_buf + offset, 7);
435  context->usb_tx_buf[7] = (unsigned char) seq;
436 
437  retval = send_packet(context);
438  if (retval) {
439  dev_err(&context->usbdev->dev,
440  "%s: send packet failed for packet #%d\n",
441  __func__, seq/2);
442  goto exit;
443  } else {
444  seq += 2;
445  offset += 7;
446  }
447 
448  } while (offset < IMON_DATA_BUF_SZ);
449 
450  if (context->vfd_proto_6p) {
451  /* Send packet #6 */
452  memcpy(context->usb_tx_buf, &vfd_packet6, sizeof(vfd_packet6));
453  context->usb_tx_buf[7] = (unsigned char) seq;
454  retval = send_packet(context);
455  if (retval)
456  dev_err(&context->usbdev->dev,
457  "%s: send packet failed for packet #%d\n",
458  __func__, seq/2);
459  }
460 
461 exit:
462  mutex_unlock(&context->ctx_lock);
463  kfree(data_buf);
464 
465  return (!retval) ? n_bytes : retval;
466 }
467 
471 static void usb_tx_callback(struct urb *urb)
472 {
473  struct imon_context *context;
474 
475  if (!urb)
476  return;
477  context = (struct imon_context *)urb->context;
478  if (!context)
479  return;
480 
481  context->tx.status = urb->status;
482 
483  /* notify waiters that write has finished */
484  atomic_set(&context->tx.busy, 0);
485  complete(&context->tx.finished);
486 
487  return;
488 }
489 
493 static int ir_open(void *data)
494 {
495  int retval = 0;
496  struct imon_context *context;
497 
498  /* prevent races with disconnect */
499  mutex_lock(&driver_lock);
500 
501  context = (struct imon_context *)data;
502 
503  /* initial IR protocol decode variables */
504  context->rx.count = 0;
505  context->rx.initial_space = 1;
506  context->rx.prev_bit = 0;
507 
508  context->ir_isopen = 1;
509  dev_info(context->driver->dev, "IR port opened\n");
510 
511  mutex_unlock(&driver_lock);
512  return retval;
513 }
514 
518 static void ir_close(void *data)
519 {
520  struct imon_context *context;
521 
522  context = (struct imon_context *)data;
523  if (!context) {
524  printk(KERN_ERR KBUILD_MODNAME
525  "%s: no context for device\n", __func__);
526  return;
527  }
528 
529  mutex_lock(&context->ctx_lock);
530 
531  context->ir_isopen = 0;
532  dev_info(context->driver->dev, "IR port closed\n");
533 
534  if (!context->dev_present) {
535  /*
536  * Device disconnected while IR port was still open. Driver
537  * was not deregistered at disconnect time, so do it now.
538  */
539  deregister_from_lirc(context);
540 
541  if (!context->display_isopen) {
542  mutex_unlock(&context->ctx_lock);
543  free_imon_context(context);
544  return;
545  }
546  /*
547  * If display port is open, context will be deleted by
548  * display_close
549  */
550  }
551 
552  mutex_unlock(&context->ctx_lock);
553  return;
554 }
555 
560 static void submit_data(struct imon_context *context)
561 {
562  unsigned char buf[4];
563  int value = context->rx.count;
564  int i;
565 
566  dev_dbg(context->driver->dev, "submitting data to LIRC\n");
567 
568  value *= BIT_DURATION;
569  value &= PULSE_MASK;
570  if (context->rx.prev_bit)
571  value |= PULSE_BIT;
572 
573  for (i = 0; i < 4; ++i)
574  buf[i] = value>>(i*8);
575 
576  lirc_buffer_write(context->driver->rbuf, buf);
577  wake_up(&context->driver->rbuf->wait_poll);
578  return;
579 }
580 
581 static inline int tv2int(const struct timeval *a, const struct timeval *b)
582 {
583  int usecs = 0;
584  int sec = 0;
585 
586  if (b->tv_usec > a->tv_usec) {
587  usecs = 1000000;
588  sec--;
589  }
590 
591  usecs += a->tv_usec - b->tv_usec;
592 
593  sec += a->tv_sec - b->tv_sec;
594  sec *= 1000;
595  usecs /= 1000;
596  sec += usecs;
597 
598  if (sec < 0)
599  sec = 1000;
600 
601  return sec;
602 }
603 
607 static void imon_incoming_packet(struct imon_context *context,
608  struct urb *urb, int intf)
609 {
610  int len = urb->actual_length;
611  unsigned char *buf = urb->transfer_buffer;
612  struct device *dev = context->driver->dev;
613  int octet, bit;
614  unsigned char mask;
615  int i;
616 
617  /*
618  * just bail out if no listening IR client
619  */
620  if (!context->ir_isopen)
621  return;
622 
623  if (len != 8) {
624  dev_warn(dev, "imon %s: invalid incoming packet "
625  "size (len = %d, intf%d)\n", __func__, len, intf);
626  return;
627  }
628 
629  if (debug) {
630  printk(KERN_INFO "raw packet: ");
631  for (i = 0; i < len; ++i)
632  printk("%02x ", buf[i]);
633  printk("\n");
634  }
635 
636  /*
637  * Translate received data to pulse and space lengths.
638  * Received data is active low, i.e. pulses are 0 and
639  * spaces are 1.
640  *
641  * My original algorithm was essentially similar to
642  * Changwoo Ryu's with the exception that he switched
643  * the incoming bits to active high and also fed an
644  * initial space to LIRC at the start of a new sequence
645  * if the previous bit was a pulse.
646  *
647  * I've decided to adopt his algorithm.
648  */
649 
650  if (buf[7] == 1 && context->rx.initial_space) {
651  /* LIRC requires a leading space */
652  context->rx.prev_bit = 0;
653  context->rx.count = 4;
654  submit_data(context);
655  context->rx.count = 0;
656  }
657 
658  for (octet = 0; octet < 5; ++octet) {
659  mask = 0x80;
660  for (bit = 0; bit < 8; ++bit) {
661  int curr_bit = !(buf[octet] & mask);
662  if (curr_bit != context->rx.prev_bit) {
663  if (context->rx.count) {
664  submit_data(context);
665  context->rx.count = 0;
666  }
667  context->rx.prev_bit = curr_bit;
668  }
669  ++context->rx.count;
670  mask >>= 1;
671  }
672  }
673 
674  if (buf[7] == 10) {
675  if (context->rx.count) {
676  submit_data(context);
677  context->rx.count = 0;
678  }
679  context->rx.initial_space = context->rx.prev_bit;
680  }
681 }
682 
686 static void usb_rx_callback(struct urb *urb)
687 {
688  struct imon_context *context;
689  int intfnum = 0;
690 
691  if (!urb)
692  return;
693 
694  context = (struct imon_context *)urb->context;
695  if (!context)
696  return;
697 
698  switch (urb->status) {
699  case -ENOENT: /* usbcore unlink successful! */
700  return;
701 
702  case 0:
703  imon_incoming_packet(context, urb, intfnum);
704  break;
705 
706  default:
707  dev_warn(context->driver->dev, "imon %s: status(%d): ignored\n",
708  __func__, urb->status);
709  break;
710  }
711 
712  usb_submit_urb(context->rx_urb, GFP_ATOMIC);
713 
714  return;
715 }
716 
720 static int imon_probe(struct usb_interface *interface,
721  const struct usb_device_id *id)
722 {
723  struct usb_device *usbdev = NULL;
724  struct usb_host_interface *iface_desc = NULL;
725  struct usb_endpoint_descriptor *rx_endpoint = NULL;
726  struct usb_endpoint_descriptor *tx_endpoint = NULL;
727  struct urb *rx_urb = NULL;
728  struct urb *tx_urb = NULL;
729  struct lirc_driver *driver = NULL;
730  struct lirc_buffer *rbuf = NULL;
731  struct device *dev = &interface->dev;
732  int ifnum;
733  int lirc_minor = 0;
734  int num_endpts;
735  int retval = 0;
736  int display_ep_found = 0;
737  int ir_ep_found = 0;
738  int alloc_status = 0;
739  int vfd_proto_6p = 0;
740  struct imon_context *context = NULL;
741  int i;
742  u16 vendor, product;
743 
744  /* prevent races probing devices w/multiple interfaces */
745  mutex_lock(&driver_lock);
746 
747  context = kzalloc(sizeof(struct imon_context), GFP_KERNEL);
748  if (!context) {
749  dev_err(dev, "%s: kzalloc failed for context\n", __func__);
750  alloc_status = 1;
751  goto alloc_status_switch;
752  }
753 
754  /*
755  * Try to auto-detect the type of display if the user hasn't set
756  * it by hand via the display_type modparam. Default is VFD.
757  */
758  if (usb_match_id(interface, ir_only_list))
759  context->display = 0;
760  else
761  context->display = 1;
762 
763  usbdev = usb_get_dev(interface_to_usbdev(interface));
764  iface_desc = interface->cur_altsetting;
765  num_endpts = iface_desc->desc.bNumEndpoints;
766  ifnum = iface_desc->desc.bInterfaceNumber;
767  vendor = le16_to_cpu(usbdev->descriptor.idVendor);
768  product = le16_to_cpu(usbdev->descriptor.idProduct);
769 
770  dev_dbg(dev, "%s: found iMON device (%04x:%04x, intf%d)\n",
771  __func__, vendor, product, ifnum);
772 
773  /*
774  * Scan the endpoint list and set:
775  * first input endpoint = IR endpoint
776  * first output endpoint = display endpoint
777  */
778  for (i = 0; i < num_endpts && !(ir_ep_found && display_ep_found); ++i) {
779  struct usb_endpoint_descriptor *ep;
780  int ep_dir;
781  int ep_type;
782  ep = &iface_desc->endpoint[i].desc;
785 
786  if (!ir_ep_found &&
787  ep_dir == USB_DIR_IN &&
788  ep_type == USB_ENDPOINT_XFER_INT) {
789 
790  rx_endpoint = ep;
791  ir_ep_found = 1;
792  dev_dbg(dev, "%s: found IR endpoint\n", __func__);
793 
794  } else if (!display_ep_found && ep_dir == USB_DIR_OUT &&
795  ep_type == USB_ENDPOINT_XFER_INT) {
796  tx_endpoint = ep;
797  display_ep_found = 1;
798  dev_dbg(dev, "%s: found display endpoint\n", __func__);
799  }
800  }
801 
802  /*
803  * Some iMON receivers have no display. Unfortunately, it seems
804  * that SoundGraph recycles device IDs between devices both with
805  * and without... :\
806  */
807  if (context->display == 0) {
808  display_ep_found = 0;
809  dev_dbg(dev, "%s: device has no display\n", __func__);
810  }
811 
812  /* Input endpoint is mandatory */
813  if (!ir_ep_found) {
814  dev_err(dev, "%s: no valid input (IR) endpoint found.\n", __func__);
815  retval = -ENODEV;
816  alloc_status = 2;
817  goto alloc_status_switch;
818  }
819 
820  /* Determine if display requires 6 packets */
821  if (display_ep_found) {
822  if (usb_match_id(interface, vfd_proto_6p_list))
823  vfd_proto_6p = 1;
824 
825  dev_dbg(dev, "%s: vfd_proto_6p: %d\n",
826  __func__, vfd_proto_6p);
827  }
828 
829  driver = kzalloc(sizeof(struct lirc_driver), GFP_KERNEL);
830  if (!driver) {
831  dev_err(dev, "%s: kzalloc failed for lirc_driver\n", __func__);
832  alloc_status = 2;
833  goto alloc_status_switch;
834  }
835  rbuf = kmalloc(sizeof(struct lirc_buffer), GFP_KERNEL);
836  if (!rbuf) {
837  dev_err(dev, "%s: kmalloc failed for lirc_buffer\n", __func__);
838  alloc_status = 3;
839  goto alloc_status_switch;
840  }
841  if (lirc_buffer_init(rbuf, BUF_CHUNK_SIZE, BUF_SIZE)) {
842  dev_err(dev, "%s: lirc_buffer_init failed\n", __func__);
843  alloc_status = 4;
844  goto alloc_status_switch;
845  }
846  rx_urb = usb_alloc_urb(0, GFP_KERNEL);
847  if (!rx_urb) {
848  dev_err(dev, "%s: usb_alloc_urb failed for IR urb\n", __func__);
849  alloc_status = 5;
850  goto alloc_status_switch;
851  }
852  tx_urb = usb_alloc_urb(0, GFP_KERNEL);
853  if (!tx_urb) {
854  dev_err(dev, "%s: usb_alloc_urb failed for display urb\n",
855  __func__);
856  alloc_status = 6;
857  goto alloc_status_switch;
858  }
859 
860  mutex_init(&context->ctx_lock);
861  context->vfd_proto_6p = vfd_proto_6p;
862 
863  strcpy(driver->name, MOD_NAME);
864  driver->minor = -1;
865  driver->code_length = BUF_CHUNK_SIZE * 8;
866  driver->sample_rate = 0;
867  driver->features = LIRC_CAN_REC_MODE2;
868  driver->data = context;
869  driver->rbuf = rbuf;
870  driver->set_use_inc = ir_open;
871  driver->set_use_dec = ir_close;
872  driver->dev = &interface->dev;
873  driver->owner = THIS_MODULE;
874 
875  mutex_lock(&context->ctx_lock);
876 
877  context->driver = driver;
878  /* start out in keyboard mode */
879 
880  lirc_minor = lirc_register_driver(driver);
881  if (lirc_minor < 0) {
882  dev_err(dev, "%s: lirc_register_driver failed\n", __func__);
883  alloc_status = 7;
884  goto unlock;
885  } else
886  dev_info(dev, "Registered iMON driver "
887  "(lirc minor: %d)\n", lirc_minor);
888 
889  /* Needed while unregistering! */
890  driver->minor = lirc_minor;
891 
892  context->usbdev = usbdev;
893  context->dev_present = 1;
894  context->rx_endpoint = rx_endpoint;
895  context->rx_urb = rx_urb;
896 
897  /*
898  * tx is used to send characters to lcd/vfd, associate RF
899  * remotes, set IR protocol, and maybe more...
900  */
901  context->tx_endpoint = tx_endpoint;
902  context->tx_urb = tx_urb;
903 
904  if (display_ep_found)
905  context->display = 1;
906 
907  usb_fill_int_urb(context->rx_urb, context->usbdev,
908  usb_rcvintpipe(context->usbdev,
909  context->rx_endpoint->bEndpointAddress),
910  context->usb_rx_buf, sizeof(context->usb_rx_buf),
911  usb_rx_callback, context,
912  context->rx_endpoint->bInterval);
913 
914  retval = usb_submit_urb(context->rx_urb, GFP_KERNEL);
915 
916  if (retval) {
917  dev_err(dev, "%s: usb_submit_urb failed for intf0 (%d)\n",
918  __func__, retval);
919  mutex_unlock(&context->ctx_lock);
920  goto exit;
921  }
922 
923  usb_set_intfdata(interface, context);
924 
925  if (context->display && ifnum == 0) {
926  dev_dbg(dev, "%s: Registering iMON display with sysfs\n",
927  __func__);
928 
929  if (usb_register_dev(interface, &imon_class)) {
930  /* Not a fatal error, so ignore */
931  dev_info(dev, "%s: could not get a minor number for "
932  "display\n", __func__);
933  }
934  }
935 
936  dev_info(dev, "iMON device (%04x:%04x, intf%d) on "
937  "usb<%d:%d> initialized\n", vendor, product, ifnum,
938  usbdev->bus->busnum, usbdev->devnum);
939 
940 unlock:
941  mutex_unlock(&context->ctx_lock);
942 alloc_status_switch:
943 
944  switch (alloc_status) {
945  case 7:
946  usb_free_urb(tx_urb);
947  case 6:
948  usb_free_urb(rx_urb);
949  case 5:
950  if (rbuf)
951  lirc_buffer_free(rbuf);
952  case 4:
953  kfree(rbuf);
954  case 3:
955  kfree(driver);
956  case 2:
957  kfree(context);
958  context = NULL;
959  case 1:
960  if (retval != -ENODEV)
961  retval = -ENOMEM;
962  break;
963  case 0:
964  retval = 0;
965  }
966 
967 exit:
968  mutex_unlock(&driver_lock);
969 
970  return retval;
971 }
972 
976 static void imon_disconnect(struct usb_interface *interface)
977 {
978  struct imon_context *context;
979  int ifnum;
980 
981  /* prevent races with ir_open()/display_open() */
982  mutex_lock(&driver_lock);
983 
984  context = usb_get_intfdata(interface);
985  ifnum = interface->cur_altsetting->desc.bInterfaceNumber;
986 
987  mutex_lock(&context->ctx_lock);
988 
989  usb_set_intfdata(interface, NULL);
990 
991  /* Abort ongoing write */
992  if (atomic_read(&context->tx.busy)) {
993  usb_kill_urb(context->tx_urb);
994  complete_all(&context->tx.finished);
995  }
996 
997  context->dev_present = 0;
998  usb_kill_urb(context->rx_urb);
999  if (context->display)
1000  usb_deregister_dev(interface, &imon_class);
1001 
1002  if (!context->ir_isopen && !context->dev_present) {
1003  deregister_from_lirc(context);
1004  mutex_unlock(&context->ctx_lock);
1005  if (!context->display_isopen)
1006  free_imon_context(context);
1007  } else
1008  mutex_unlock(&context->ctx_lock);
1009 
1010  mutex_unlock(&driver_lock);
1011 
1012  printk(KERN_INFO "%s: iMON device (intf%d) disconnected\n",
1013  __func__, ifnum);
1014 }
1015 
1016 static int imon_suspend(struct usb_interface *intf, pm_message_t message)
1017 {
1018  struct imon_context *context = usb_get_intfdata(intf);
1019 
1020  usb_kill_urb(context->rx_urb);
1021 
1022  return 0;
1023 }
1024 
1025 static int imon_resume(struct usb_interface *intf)
1026 {
1027  int rc = 0;
1028  struct imon_context *context = usb_get_intfdata(intf);
1029 
1030  usb_fill_int_urb(context->rx_urb, context->usbdev,
1031  usb_rcvintpipe(context->usbdev,
1032  context->rx_endpoint->bEndpointAddress),
1033  context->usb_rx_buf, sizeof(context->usb_rx_buf),
1034  usb_rx_callback, context,
1035  context->rx_endpoint->bInterval);
1036 
1037  rc = usb_submit_urb(context->rx_urb, GFP_ATOMIC);
1038 
1039  return rc;
1040 }
1041 
1042 module_usb_driver(imon_driver);