Version:  2.0.40 2.2.26 2.4.37 3.12 3.13 3.14 3.15 3.16 3.17 3.18 3.19 4.0 4.1 4.2 4.3 4.4 4.5 4.6 4.7 4.8 4.9

Linux/drivers/staging/media/lirc/lirc_imon.c

  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(dev@venky.ws)
  6  *   Copyright(C) 2009  Jarod Wilson <jarod@wilsonet.com>
  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 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 24 
 25 #include <linux/errno.h>
 26 #include <linux/kernel.h>
 27 #include <linux/module.h>
 28 #include <linux/slab.h>
 29 #include <linux/uaccess.h>
 30 #include <linux/usb.h>
 31 
 32 #include <media/lirc.h>
 33 #include <media/lirc_dev.h>
 34 
 35 #define MOD_AUTHOR      "Venky Raju <dev@venky.ws>"
 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 
 88         struct lirc_driver *driver;
 89         struct usb_endpoint_descriptor *rx_endpoint;
 90         struct usb_endpoint_descriptor *tx_endpoint;
 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 
180 MODULE_AUTHOR(MOD_AUTHOR);
181 MODULE_DESCRIPTION(MOD_DESC);
182 MODULE_VERSION(MOD_VERSION);
183 MODULE_LICENSE("GPL");
184 MODULE_DEVICE_TABLE(usb, imon_usb_id_table);
185 module_param(debug, int, S_IRUGO | S_IWUSR);
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 
192         usb_free_urb(context->tx_urb);
193         usb_free_urb(context->rx_urb);
194         lirc_buffer_free(context->driver->rbuf);
195         kfree(context->driver->rbuf);
196         kfree(context->driver);
197         kfree(context);
198 
199         dev_dbg(dev, "%s: iMON context freed\n", __func__);
200 }
201 
202 static void deregister_from_lirc(struct imon_context *context)
203 {
204         int retval;
205         int minor = context->driver->minor;
206 
207         retval = lirc_unregister_driver(minor);
208         if (retval)
209                 dev_err(&context->usbdev->dev,
210                         "unable to deregister from lirc(%d)", retval);
211         else
212                 dev_info(&context->usbdev->dev,
213                          "Deregistered iMON driver (minor:%d)\n", minor);
214 }
215 
216 /**
217  * Called when the Display device (e.g. /dev/lcd0)
218  * is opened by the application.
219  */
220 static int display_open(struct inode *inode, struct file *file)
221 {
222         struct usb_interface *interface;
223         struct imon_context *context = NULL;
224         int subminor;
225         int retval = 0;
226 
227         /* prevent races with disconnect */
228         mutex_lock(&driver_lock);
229 
230         subminor = iminor(inode);
231         interface = usb_find_interface(&imon_driver, subminor);
232         if (!interface) {
233                 pr_err("%s: could not find interface for minor %d\n",
234                        __func__, subminor);
235                 retval = -ENODEV;
236                 goto exit;
237         }
238         context = usb_get_intfdata(interface);
239 
240         if (!context) {
241                 dev_err(&interface->dev, "no context found for minor %d\n",
242                         subminor);
243                 retval = -ENODEV;
244                 goto exit;
245         }
246 
247         mutex_lock(&context->ctx_lock);
248 
249         if (!context->display) {
250                 dev_err(&interface->dev,
251                         "%s: display not supported by device\n", __func__);
252                 retval = -ENODEV;
253         } else if (context->display_isopen) {
254                 dev_err(&interface->dev,
255                         "%s: display port is already open\n", __func__);
256                 retval = -EBUSY;
257         } else {
258                 context->display_isopen = 1;
259                 file->private_data = context;
260                 dev_info(context->driver->dev, "display port opened\n");
261         }
262 
263         mutex_unlock(&context->ctx_lock);
264 
265 exit:
266         mutex_unlock(&driver_lock);
267         return retval;
268 }
269 
270 /**
271  * Called when the display device (e.g. /dev/lcd0)
272  * is closed by the application.
273  */
274 static int display_close(struct inode *inode, struct file *file)
275 {
276         struct imon_context *context = NULL;
277         int retval = 0;
278 
279         context = file->private_data;
280 
281         if (!context) {
282                 pr_err("%s: no context for device\n", __func__);
283                 return -ENODEV;
284         }
285 
286         mutex_lock(&context->ctx_lock);
287 
288         if (!context->display) {
289                 dev_err(&context->usbdev->dev,
290                         "%s: display not supported by device\n", __func__);
291                 retval = -ENODEV;
292         } else if (!context->display_isopen) {
293                 dev_err(&context->usbdev->dev,
294                         "%s: display is not open\n", __func__);
295                 retval = -EIO;
296         } else {
297                 context->display_isopen = 0;
298                 dev_info(context->driver->dev, "display port closed\n");
299                 if (!context->dev_present && !context->ir_isopen) {
300                         /*
301                          * Device disconnected before close and IR port is not
302                          * open. If IR port is open, context will be deleted by
303                          * ir_close.
304                          */
305                         mutex_unlock(&context->ctx_lock);
306                         free_imon_context(context);
307                         return retval;
308                 }
309         }
310 
311         mutex_unlock(&context->ctx_lock);
312         return retval;
313 }
314 
315 /**
316  * Sends a packet to the device -- this function must be called
317  * with context->ctx_lock held.
318  */
319 static int send_packet(struct imon_context *context)
320 {
321         unsigned int pipe;
322         int interval = 0;
323         int retval = 0;
324 
325         /* Check if we need to use control or interrupt urb */
326         pipe = usb_sndintpipe(context->usbdev,
327                               context->tx_endpoint->bEndpointAddress);
328         interval = context->tx_endpoint->bInterval;
329 
330         usb_fill_int_urb(context->tx_urb, context->usbdev, pipe,
331                          context->usb_tx_buf,
332                          sizeof(context->usb_tx_buf),
333                          usb_tx_callback, context, interval);
334 
335         context->tx_urb->actual_length = 0;
336 
337         init_completion(&context->tx.finished);
338         atomic_set(&context->tx.busy, 1);
339 
340         retval = usb_submit_urb(context->tx_urb, GFP_KERNEL);
341         if (retval) {
342                 atomic_set(&context->tx.busy, 0);
343                 dev_err(&context->usbdev->dev, "error submitting urb(%d)\n",
344                         retval);
345         } else {
346                 /* Wait for transmission to complete (or abort) */
347                 mutex_unlock(&context->ctx_lock);
348                 retval = wait_for_completion_interruptible(
349                                 &context->tx.finished);
350                 if (retval)
351                         dev_err(&context->usbdev->dev,
352                                 "%s: task interrupted\n", __func__);
353                 mutex_lock(&context->ctx_lock);
354 
355                 retval = context->tx.status;
356                 if (retval)
357                         dev_err(&context->usbdev->dev,
358                                 "packet tx failed (%d)\n", retval);
359         }
360 
361         return retval;
362 }
363 
364 /**
365  * Writes data to the VFD.  The iMON VFD is 2x16 characters
366  * and requires data in 5 consecutive USB interrupt packets,
367  * each packet but the last carrying 7 bytes.
368  *
369  * I don't know if the VFD board supports features such as
370  * scrolling, clearing rows, blanking, etc. so at
371  * the caller must provide a full screen of data.  If fewer
372  * than 32 bytes are provided spaces will be appended to
373  * generate a full screen.
374  */
375 static ssize_t vfd_write(struct file *file, const char __user *buf,
376                          size_t n_bytes, loff_t *pos)
377 {
378         int i;
379         int offset;
380         int seq;
381         int retval = 0;
382         struct imon_context *context;
383         const unsigned char vfd_packet6[] = {
384                 0x01, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF };
385         int *data_buf = NULL;
386 
387         context = file->private_data;
388         if (!context) {
389                 pr_err("%s: no context for device\n", __func__);
390                 return -ENODEV;
391         }
392 
393         mutex_lock(&context->ctx_lock);
394 
395         if (!context->dev_present) {
396                 dev_err(&context->usbdev->dev,
397                         "%s: no iMON device present\n", __func__);
398                 retval = -ENODEV;
399                 goto exit;
400         }
401 
402         if (n_bytes <= 0 || n_bytes > IMON_DATA_BUF_SZ - 3) {
403                 dev_err(&context->usbdev->dev,
404                         "%s: invalid payload size\n", __func__);
405                 retval = -EINVAL;
406                 goto exit;
407         }
408 
409         data_buf = memdup_user(buf, n_bytes);
410         if (IS_ERR(data_buf)) {
411                 retval = PTR_ERR(data_buf);
412                 data_buf = NULL;
413                 goto exit;
414         }
415 
416         memcpy(context->tx.data_buf, data_buf, n_bytes);
417 
418         /* Pad with spaces */
419         for (i = n_bytes; i < IMON_DATA_BUF_SZ - 3; ++i)
420                 context->tx.data_buf[i] = ' ';
421 
422         for (i = IMON_DATA_BUF_SZ - 3; i < IMON_DATA_BUF_SZ; ++i)
423                 context->tx.data_buf[i] = 0xFF;
424 
425         offset = 0;
426         seq = 0;
427 
428         do {
429                 memcpy(context->usb_tx_buf, context->tx.data_buf + offset, 7);
430                 context->usb_tx_buf[7] = (unsigned char)seq;
431 
432                 retval = send_packet(context);
433                 if (retval) {
434                         dev_err(&context->usbdev->dev,
435                                 "send packet failed for packet #%d\n",
436                                 seq / 2);
437                         goto exit;
438                 } else {
439                         seq += 2;
440                         offset += 7;
441                 }
442 
443         } while (offset < IMON_DATA_BUF_SZ);
444 
445         if (context->vfd_proto_6p) {
446                 /* Send packet #6 */
447                 memcpy(context->usb_tx_buf, &vfd_packet6, sizeof(vfd_packet6));
448                 context->usb_tx_buf[7] = (unsigned char)seq;
449                 retval = send_packet(context);
450                 if (retval)
451                         dev_err(&context->usbdev->dev,
452                                 "send packet failed for packet #%d\n",
453                                 seq / 2);
454         }
455 
456 exit:
457         mutex_unlock(&context->ctx_lock);
458         kfree(data_buf);
459 
460         return (!retval) ? n_bytes : retval;
461 }
462 
463 /**
464  * Callback function for USB core API: transmit data
465  */
466 static void usb_tx_callback(struct urb *urb)
467 {
468         struct imon_context *context;
469 
470         if (!urb)
471                 return;
472         context = (struct imon_context *)urb->context;
473         if (!context)
474                 return;
475 
476         context->tx.status = urb->status;
477 
478         /* notify waiters that write has finished */
479         atomic_set(&context->tx.busy, 0);
480         complete(&context->tx.finished);
481 }
482 
483 /**
484  * Called by lirc_dev when the application opens /dev/lirc
485  */
486 static int ir_open(void *data)
487 {
488         struct imon_context *context;
489 
490         /* prevent races with disconnect */
491         mutex_lock(&driver_lock);
492 
493         context = data;
494 
495         /* initial IR protocol decode variables */
496         context->rx.count = 0;
497         context->rx.initial_space = 1;
498         context->rx.prev_bit = 0;
499 
500         context->ir_isopen = 1;
501         dev_info(context->driver->dev, "IR port opened\n");
502 
503         mutex_unlock(&driver_lock);
504         return 0;
505 }
506 
507 /**
508  * Called by lirc_dev when the application closes /dev/lirc
509  */
510 static void ir_close(void *data)
511 {
512         struct imon_context *context;
513 
514         context = data;
515         if (!context) {
516                 pr_err("%s: no context for device\n", __func__);
517                 return;
518         }
519 
520         mutex_lock(&context->ctx_lock);
521 
522         context->ir_isopen = 0;
523         dev_info(context->driver->dev, "IR port closed\n");
524 
525         if (!context->dev_present) {
526                 /*
527                  * Device disconnected while IR port was still open. Driver
528                  * was not deregistered at disconnect time, so do it now.
529                  */
530                 deregister_from_lirc(context);
531 
532                 if (!context->display_isopen) {
533                         mutex_unlock(&context->ctx_lock);
534                         free_imon_context(context);
535                         return;
536                 }
537                 /*
538                  * If display port is open, context will be deleted by
539                  * display_close
540                  */
541         }
542 
543         mutex_unlock(&context->ctx_lock);
544 }
545 
546 /**
547  * Convert bit count to time duration (in us) and submit
548  * the value to lirc_dev.
549  */
550 static void submit_data(struct imon_context *context)
551 {
552         unsigned char buf[4];
553         int value = context->rx.count;
554         int i;
555 
556         dev_dbg(context->driver->dev, "submitting data to LIRC\n");
557 
558         value *= BIT_DURATION;
559         value &= PULSE_MASK;
560         if (context->rx.prev_bit)
561                 value |= PULSE_BIT;
562 
563         for (i = 0; i < 4; ++i)
564                 buf[i] = value >> (i * 8);
565 
566         lirc_buffer_write(context->driver->rbuf, buf);
567         wake_up(&context->driver->rbuf->wait_poll);
568 }
569 
570 /**
571  * Process the incoming packet
572  */
573 static void imon_incoming_packet(struct imon_context *context,
574                                  struct urb *urb, int intf)
575 {
576         int len = urb->actual_length;
577         unsigned char *buf = urb->transfer_buffer;
578         struct device *dev = context->driver->dev;
579         int octet, bit;
580         unsigned char mask;
581 
582         /*
583          * just bail out if no listening IR client
584          */
585         if (!context->ir_isopen)
586                 return;
587 
588         if (len != 8) {
589                 dev_warn(dev, "imon %s: invalid incoming packet size (len = %d, intf%d)\n",
590                          __func__, len, intf);
591                 return;
592         }
593 
594         if (debug)
595                 dev_info(dev, "raw packet: %*ph\n", len, buf);
596         /*
597          * Translate received data to pulse and space lengths.
598          * Received data is active low, i.e. pulses are 0 and
599          * spaces are 1.
600          *
601          * My original algorithm was essentially similar to
602          * Changwoo Ryu's with the exception that he switched
603          * the incoming bits to active high and also fed an
604          * initial space to LIRC at the start of a new sequence
605          * if the previous bit was a pulse.
606          *
607          * I've decided to adopt his algorithm.
608          */
609 
610         if (buf[7] == 1 && context->rx.initial_space) {
611                 /* LIRC requires a leading space */
612                 context->rx.prev_bit = 0;
613                 context->rx.count = 4;
614                 submit_data(context);
615                 context->rx.count = 0;
616         }
617 
618         for (octet = 0; octet < 5; ++octet) {
619                 mask = 0x80;
620                 for (bit = 0; bit < 8; ++bit) {
621                         int curr_bit = !(buf[octet] & mask);
622 
623                         if (curr_bit != context->rx.prev_bit) {
624                                 if (context->rx.count) {
625                                         submit_data(context);
626                                         context->rx.count = 0;
627                                 }
628                                 context->rx.prev_bit = curr_bit;
629                         }
630                         ++context->rx.count;
631                         mask >>= 1;
632                 }
633         }
634 
635         if (buf[7] == 10) {
636                 if (context->rx.count) {
637                         submit_data(context);
638                         context->rx.count = 0;
639                 }
640                 context->rx.initial_space = context->rx.prev_bit;
641         }
642 }
643 
644 /**
645  * Callback function for USB core API: receive data
646  */
647 static void usb_rx_callback(struct urb *urb)
648 {
649         struct imon_context *context;
650         int intfnum = 0;
651 
652         if (!urb)
653                 return;
654 
655         context = (struct imon_context *)urb->context;
656         if (!context)
657                 return;
658 
659         switch (urb->status) {
660         case -ENOENT:           /* usbcore unlink successful! */
661                 return;
662 
663         case 0:
664                 imon_incoming_packet(context, urb, intfnum);
665                 break;
666 
667         default:
668                 dev_warn(context->driver->dev, "imon %s: status(%d): ignored\n",
669                          __func__, urb->status);
670                 break;
671         }
672 
673         usb_submit_urb(context->rx_urb, GFP_ATOMIC);
674 }
675 
676 /**
677  * Callback function for USB core API: Probe
678  */
679 static int imon_probe(struct usb_interface *interface,
680                       const struct usb_device_id *id)
681 {
682         struct usb_device *usbdev = NULL;
683         struct usb_host_interface *iface_desc = NULL;
684         struct usb_endpoint_descriptor *rx_endpoint = NULL;
685         struct usb_endpoint_descriptor *tx_endpoint = NULL;
686         struct urb *rx_urb = NULL;
687         struct urb *tx_urb = NULL;
688         struct lirc_driver *driver = NULL;
689         struct lirc_buffer *rbuf = NULL;
690         struct device *dev = &interface->dev;
691         int ifnum;
692         int lirc_minor = 0;
693         int num_endpts;
694         int retval = -ENOMEM;
695         int display_ep_found = 0;
696         int ir_ep_found = 0;
697         int vfd_proto_6p = 0;
698         struct imon_context *context = NULL;
699         int i;
700         u16 vendor, product;
701 
702         /* prevent races probing devices w/multiple interfaces */
703         mutex_lock(&driver_lock);
704 
705         context = kzalloc(sizeof(*context), GFP_KERNEL);
706         if (!context)
707                 goto driver_unlock;
708 
709         /*
710          * Try to auto-detect the type of display if the user hasn't set
711          * it by hand via the display_type modparam. Default is VFD.
712          */
713         if (usb_match_id(interface, ir_only_list))
714                 context->display = 0;
715         else
716                 context->display = 1;
717 
718         usbdev     = usb_get_dev(interface_to_usbdev(interface));
719         iface_desc = interface->cur_altsetting;
720         num_endpts = iface_desc->desc.bNumEndpoints;
721         ifnum      = iface_desc->desc.bInterfaceNumber;
722         vendor     = le16_to_cpu(usbdev->descriptor.idVendor);
723         product    = le16_to_cpu(usbdev->descriptor.idProduct);
724 
725         dev_dbg(dev, "%s: found iMON device (%04x:%04x, intf%d)\n",
726                 __func__, vendor, product, ifnum);
727 
728         /*
729          * Scan the endpoint list and set:
730          *      first input endpoint = IR endpoint
731          *      first output endpoint = display endpoint
732          */
733         for (i = 0; i < num_endpts && !(ir_ep_found && display_ep_found); ++i) {
734                 struct usb_endpoint_descriptor *ep;
735                 int ep_dir;
736                 int ep_type;
737 
738                 ep = &iface_desc->endpoint[i].desc;
739                 ep_dir = ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK;
740                 ep_type = usb_endpoint_type(ep);
741 
742                 if (!ir_ep_found &&
743                         ep_dir == USB_DIR_IN &&
744                         ep_type == USB_ENDPOINT_XFER_INT) {
745 
746                         rx_endpoint = ep;
747                         ir_ep_found = 1;
748                         dev_dbg(dev, "%s: found IR endpoint\n", __func__);
749 
750                 } else if (!display_ep_found && ep_dir == USB_DIR_OUT &&
751                            ep_type == USB_ENDPOINT_XFER_INT) {
752                         tx_endpoint = ep;
753                         display_ep_found = 1;
754                         dev_dbg(dev, "%s: found display endpoint\n", __func__);
755                 }
756         }
757 
758         /*
759          * Some iMON receivers have no display. Unfortunately, it seems
760          * that SoundGraph recycles device IDs between devices both with
761          * and without... :\
762          */
763         if (context->display == 0) {
764                 display_ep_found = 0;
765                 dev_dbg(dev, "%s: device has no display\n", __func__);
766         }
767 
768         /* Input endpoint is mandatory */
769         if (!ir_ep_found) {
770                 dev_err(dev, "%s: no valid input (IR) endpoint found.\n",
771                         __func__);
772                 retval = -ENODEV;
773                 goto free_context;
774         }
775 
776         /* Determine if display requires 6 packets */
777         if (display_ep_found) {
778                 if (usb_match_id(interface, vfd_proto_6p_list))
779                         vfd_proto_6p = 1;
780 
781                 dev_dbg(dev, "%s: vfd_proto_6p: %d\n",
782                         __func__, vfd_proto_6p);
783         }
784 
785         driver = kzalloc(sizeof(*driver), GFP_KERNEL);
786         if (!driver)
787                 goto free_context;
788 
789         rbuf = kmalloc(sizeof(*rbuf), GFP_KERNEL);
790         if (!rbuf)
791                 goto free_driver;
792 
793         if (lirc_buffer_init(rbuf, BUF_CHUNK_SIZE, BUF_SIZE)) {
794                 dev_err(dev, "%s: lirc_buffer_init failed\n", __func__);
795                 goto free_rbuf;
796         }
797         rx_urb = usb_alloc_urb(0, GFP_KERNEL);
798         if (!rx_urb)
799                 goto free_lirc_buf;
800         tx_urb = usb_alloc_urb(0, GFP_KERNEL);
801         if (!tx_urb)
802                 goto free_rx_urb;
803 
804         mutex_init(&context->ctx_lock);
805         context->vfd_proto_6p = vfd_proto_6p;
806 
807         strcpy(driver->name, MOD_NAME);
808         driver->minor = -1;
809         driver->code_length = BUF_CHUNK_SIZE * 8;
810         driver->sample_rate = 0;
811         driver->features = LIRC_CAN_REC_MODE2;
812         driver->data = context;
813         driver->rbuf = rbuf;
814         driver->set_use_inc = ir_open;
815         driver->set_use_dec = ir_close;
816         driver->dev = &interface->dev;
817         driver->owner = THIS_MODULE;
818 
819         mutex_lock(&context->ctx_lock);
820 
821         context->driver = driver;
822         /* start out in keyboard mode */
823 
824         lirc_minor = lirc_register_driver(driver);
825         if (lirc_minor < 0) {
826                 dev_err(dev, "%s: lirc_register_driver failed\n", __func__);
827                 goto free_tx_urb;
828         }
829 
830         dev_info(dev, "Registered iMON driver (lirc minor: %d)\n",
831                  lirc_minor);
832 
833         /* Needed while unregistering! */
834         driver->minor = lirc_minor;
835 
836         context->usbdev = usbdev;
837         context->dev_present = 1;
838         context->rx_endpoint = rx_endpoint;
839         context->rx_urb = rx_urb;
840 
841         /*
842          * tx is used to send characters to lcd/vfd, associate RF
843          * remotes, set IR protocol, and maybe more...
844          */
845         context->tx_endpoint = tx_endpoint;
846         context->tx_urb = tx_urb;
847 
848         if (display_ep_found)
849                 context->display = 1;
850 
851         usb_fill_int_urb(context->rx_urb, context->usbdev,
852                          usb_rcvintpipe(context->usbdev,
853                          context->rx_endpoint->bEndpointAddress),
854                 context->usb_rx_buf, sizeof(context->usb_rx_buf),
855                 usb_rx_callback, context,
856                 context->rx_endpoint->bInterval);
857 
858         retval = usb_submit_urb(context->rx_urb, GFP_KERNEL);
859         if (retval) {
860                 dev_err(dev, "usb_submit_urb failed for intf0 (%d)\n", retval);
861                 goto unregister_lirc;
862         }
863 
864         usb_set_intfdata(interface, context);
865 
866         if (context->display && ifnum == 0) {
867                 dev_dbg(dev, "%s: Registering iMON display with sysfs\n",
868                         __func__);
869 
870                 if (usb_register_dev(interface, &imon_class)) {
871                         /* Not a fatal error, so ignore */
872                         dev_info(dev, "%s: could not get a minor number for display\n",
873                                  __func__);
874                 }
875         }
876 
877         dev_info(dev, "iMON device (%04x:%04x, intf%d) on usb<%d:%d> initialized\n",
878                  vendor, product, ifnum, usbdev->bus->busnum, usbdev->devnum);
879 
880         /* Everything went fine. Just unlock and return retval (with is 0) */
881         mutex_unlock(&context->ctx_lock);
882         goto driver_unlock;
883 
884 unregister_lirc:
885         lirc_unregister_driver(driver->minor);
886 
887 free_tx_urb:
888         mutex_unlock(&context->ctx_lock);
889         usb_free_urb(tx_urb);
890 
891 free_rx_urb:
892         usb_free_urb(rx_urb);
893 
894 free_lirc_buf:
895         lirc_buffer_free(rbuf);
896 
897 free_rbuf:
898         kfree(rbuf);
899 
900 free_driver:
901         kfree(driver);
902 free_context:
903         kfree(context);
904         context = NULL;
905 
906 driver_unlock:
907         mutex_unlock(&driver_lock);
908 
909         return retval;
910 }
911 
912 /**
913  * Callback function for USB core API: disconnect
914  */
915 static void imon_disconnect(struct usb_interface *interface)
916 {
917         struct imon_context *context;
918         int ifnum;
919 
920         /* prevent races with ir_open()/display_open() */
921         mutex_lock(&driver_lock);
922 
923         context = usb_get_intfdata(interface);
924         ifnum = interface->cur_altsetting->desc.bInterfaceNumber;
925 
926         mutex_lock(&context->ctx_lock);
927 
928         usb_set_intfdata(interface, NULL);
929 
930         /* Abort ongoing write */
931         if (atomic_read(&context->tx.busy)) {
932                 usb_kill_urb(context->tx_urb);
933                 complete_all(&context->tx.finished);
934         }
935 
936         context->dev_present = 0;
937         usb_kill_urb(context->rx_urb);
938         if (context->display)
939                 usb_deregister_dev(interface, &imon_class);
940 
941         if (!context->ir_isopen && !context->dev_present) {
942                 deregister_from_lirc(context);
943                 mutex_unlock(&context->ctx_lock);
944                 if (!context->display_isopen)
945                         free_imon_context(context);
946         } else
947                 mutex_unlock(&context->ctx_lock);
948 
949         mutex_unlock(&driver_lock);
950 
951         dev_info(&interface->dev, "%s: iMON device (intf%d) disconnected\n",
952                  __func__, ifnum);
953 }
954 
955 static int imon_suspend(struct usb_interface *intf, pm_message_t message)
956 {
957         struct imon_context *context = usb_get_intfdata(intf);
958 
959         usb_kill_urb(context->rx_urb);
960 
961         return 0;
962 }
963 
964 static int imon_resume(struct usb_interface *intf)
965 {
966         struct imon_context *context = usb_get_intfdata(intf);
967 
968         usb_fill_int_urb(context->rx_urb, context->usbdev,
969                          usb_rcvintpipe(context->usbdev,
970                          context->rx_endpoint->bEndpointAddress),
971                 context->usb_rx_buf, sizeof(context->usb_rx_buf),
972                 usb_rx_callback, context,
973                 context->rx_endpoint->bInterval);
974 
975         return usb_submit_urb(context->rx_urb, GFP_ATOMIC);
976 }
977 
978 module_usb_driver(imon_driver);
979 

This page was automatically generated by LXR 0.3.1 (source).  •  Linux is a registered trademark of Linus Torvalds  •  Contact us