Added lirc.
[irreco.git] / lirc-0.8.4a / drivers / lirc_streamzap / lirc_streamzap.c
bloba0c45ec26baef7c6772e6e6c8f25b1bcd67ce409
1 /* $Id: lirc_streamzap.c,v 1.29 2008/09/17 18:20:16 lirc Exp $ */
3 /*
4 * Streamzap Remote Control driver
6 * Copyright (c) 2005 Christoph Bartelmus <lirc@bartelmus.de>
8 * This driver was based on the work of Greg Wickham and Adrian
9 * Dewhurst. It was substantially rewritten to support correct signal
10 * gaps and now maintains a delay buffer, which is used to present
11 * consistent timing behaviour to user space applications. Without the
12 * delay buffer an ugly hack would be required in lircd, which can
13 * cause sluggish signal decoding in certain situations.
15 * This driver is based on the USB skeleton driver packaged with the
16 * kernel; copyright (C) 2001-2003 Greg Kroah-Hartman (greg@kroah.com)
18 * This program is free software; you can redistribute it and/or modify
19 * it under the terms of the GNU General Public License as published by
20 * the Free Software Foundation; either version 2 of the License, or
21 * (at your option) any later version.
23 * This program is distributed in the hope that it will be useful,
24 * but WITHOUT ANY WARRANTY; without even the implied warranty of
25 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26 * GNU General Public License for more details.
28 * You should have received a copy of the GNU General Public License
29 * along with this program; if not, write to the Free Software
30 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
34 #include <linux/version.h>
35 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0)
36 #error "*******************************************************"
37 #error "Sorry, this driver needs kernel version 2.4.0 or higher"
38 #error "*******************************************************"
39 #endif
41 #include <linux/autoconf.h>
42 #include <linux/kernel.h>
43 #include <linux/errno.h>
44 #include <linux/init.h>
45 #include <linux/slab.h>
46 #include <linux/module.h>
47 #include <linux/smp_lock.h>
48 #include <linux/completion.h>
49 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18)
50 #include <asm/uaccess.h>
51 #else
52 #include <linux/uaccess.h>
53 #endif
54 #include <linux/usb.h>
56 #include "drivers/lirc.h"
57 #include "drivers/kcompat.h"
58 #include "drivers/lirc_dev/lirc_dev.h"
60 #define DRIVER_VERSION "$Revision: 1.29 $"
61 #define DRIVER_NAME "lirc_streamzap"
62 #define DRIVER_DESC "Streamzap Remote Control driver"
64 /* ------------------------------------------------------------------ */
66 static int debug;
68 #define USB_STREAMZAP_VENDOR_ID 0x0e9c
69 #define USB_STREAMZAP_PRODUCT_ID 0x0000
71 /* Use our own dbg macro */
72 #define dprintk(fmt, args...) \
73 do { \
74 if (debug) \
75 printk(KERN_DEBUG DRIVER_NAME "[%d]: " \
76 fmt "\n", ## args); \
77 } while (0)
80 * table of devices that work with this driver
82 static struct usb_device_id streamzap_table [] = {
83 /* Streamzap Remote Control */
84 { USB_DEVICE(USB_STREAMZAP_VENDOR_ID, USB_STREAMZAP_PRODUCT_ID) },
85 /* Terminating entry */
86 { }
89 MODULE_DEVICE_TABLE(usb, streamzap_table);
91 #define STREAMZAP_PULSE_MASK 0xf0
92 #define STREAMZAP_SPACE_MASK 0x0f
93 #define STREAMZAP_RESOLUTION 256
95 /* number of samples buffered */
96 #define STREAMZAP_BUFFER_SIZE 128
98 enum StreamzapDecoderState {
99 PulseSpace,
100 FullPulse,
101 FullSpace,
102 IgnorePulse
105 /* Structure to hold all of our device specific stuff */
106 /* some remarks regarding locking:
107 theoretically this struct can be accessed from three threads:
109 - from lirc_dev through set_use_inc/set_use_dec
111 - from the USB layer throuh probe/disconnect/irq
113 Careful placement of lirc_register_plugin/lirc_unregister_plugin
114 calls will prevent conflicts. lirc_dev makes sure that
115 set_use_inc/set_use_dec are not being executed and will not be
116 called after lirc_unregister_plugin returns.
118 - by the timer callback
120 The timer is only running when the device is connected and the
121 LIRC device is open. Making sure the timer is deleted by
122 set_use_dec will make conflicts impossible.
124 struct usb_streamzap {
126 /* usb */
127 /* save off the usb device pointer */
128 struct usb_device *udev;
129 /* the interface for this device */
130 struct usb_interface *interface;
132 /* buffer & dma */
133 unsigned char *buf_in;
134 dma_addr_t dma_in;
135 unsigned int buf_in_len;
137 struct usb_endpoint_descriptor *endpoint;
139 /* IRQ */
140 struct urb *urb_in;
142 /* lirc */
143 struct lirc_plugin plugin;
144 struct lirc_buffer delay_buf;
145 struct lirc_buffer lirc_buf;
147 /* timer used to support delay buffering */
148 struct timer_list delay_timer;
149 int timer_running;
150 spinlock_t timer_lock;
152 /* tracks whether we are currently receiving some signal */
153 int idle;
154 /* sum of signal lengths received since signal start */
155 unsigned long sum;
156 /* start time of signal; necessary for gap tracking */
157 struct timeval signal_last;
158 struct timeval signal_start;
159 enum StreamzapDecoderState decoder_state;
160 struct timer_list flush_timer;
161 int flush;
162 int in_use;
166 /* local function prototypes */
167 #ifdef KERNEL_2_5
168 static int streamzap_probe(struct usb_interface *interface,
169 const struct usb_device_id *id);
170 static void streamzap_disconnect(struct usb_interface *interface);
171 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19)
172 static void usb_streamzap_irq(struct urb *urb, struct pt_regs *regs);
173 #else
174 static void usb_streamzap_irq(struct urb *urb);
175 #endif
176 #else
177 static void *streamzap_probe(struct usb_device *udev, unsigned int ifnum,
178 const struct usb_device_id *id);
179 static void streamzap_disconnect(struct usb_device *dev, void *ptr);
180 static void usb_streamzap_irq(struct urb *urb);
181 #endif
182 static int streamzap_use_inc(void *data);
183 static void streamzap_use_dec(void *data);
184 static int streamzap_ioctl(struct inode *node, struct file *filep,
185 unsigned int cmd, unsigned long arg);
186 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)
187 static int streamzap_suspend(struct usb_interface *intf, pm_message_t message);
188 static int streamzap_resume(struct usb_interface *intf);
189 #endif
191 /* usb specific object needed to register this driver with the usb subsystem */
193 static struct usb_driver streamzap_driver = {
194 LIRC_THIS_MODULE(.owner = THIS_MODULE)
195 .name = DRIVER_NAME,
196 .probe = streamzap_probe,
197 .disconnect = streamzap_disconnect,
198 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)
199 .suspend = streamzap_suspend,
200 .resume = streamzap_resume,
201 #endif
202 .id_table = streamzap_table,
205 static void stop_timer(struct usb_streamzap *sz)
207 unsigned long flags;
209 spin_lock_irqsave(&sz->timer_lock, flags);
210 if (sz->timer_running) {
211 sz->timer_running = 0;
212 spin_unlock_irqrestore(&sz->timer_lock, flags);
213 del_timer_sync(&sz->delay_timer);
214 } else {
215 spin_unlock_irqrestore(&sz->timer_lock, flags);
219 static void flush_timeout(unsigned long arg)
221 struct usb_streamzap *sz = (struct usb_streamzap *) arg;
223 /* finally start accepting data */
224 sz->flush = 0;
226 static void delay_timeout(unsigned long arg)
228 unsigned long flags;
229 /* deliver data every 10 ms */
230 static unsigned long timer_inc =
231 (10000/(1000000/HZ)) == 0 ? 1:(10000/(1000000/HZ));
232 struct usb_streamzap *sz = (struct usb_streamzap *) arg;
233 lirc_t data;
235 spin_lock_irqsave(&sz->timer_lock, flags);
237 if (!lirc_buffer_empty(&sz->delay_buf) &&
238 !lirc_buffer_full(&sz->lirc_buf)) {
239 lirc_buffer_read_1(&sz->delay_buf, (unsigned char *) &data);
240 lirc_buffer_write_1(&sz->lirc_buf, (unsigned char *) &data);
242 if (!lirc_buffer_empty(&sz->delay_buf)) {
243 while (lirc_buffer_available(&sz->delay_buf) <
244 STREAMZAP_BUFFER_SIZE/2 &&
245 !lirc_buffer_full(&sz->lirc_buf)) {
246 lirc_buffer_read_1(&sz->delay_buf,
247 (unsigned char *) &data);
248 lirc_buffer_write_1(&sz->lirc_buf,
249 (unsigned char *) &data);
251 if (sz->timer_running) {
252 sz->delay_timer.expires += timer_inc;
253 add_timer(&sz->delay_timer);
255 } else {
256 sz->timer_running = 0;
259 if (!lirc_buffer_empty(&sz->lirc_buf))
260 wake_up(&sz->lirc_buf.wait_poll);
262 spin_unlock_irqrestore(&sz->timer_lock, flags);
265 static inline void flush_delay_buffer(struct usb_streamzap *sz)
267 lirc_t data;
268 int empty = 1;
270 while (!lirc_buffer_empty(&sz->delay_buf)) {
271 empty = 0;
272 lirc_buffer_read_1(&sz->delay_buf, (unsigned char *) &data);
273 if (!lirc_buffer_full(&sz->lirc_buf)) {
274 lirc_buffer_write_1(&sz->lirc_buf,
275 (unsigned char *) &data);
276 } else {
277 dprintk("buffer overflow\n", sz->plugin.minor);
280 if (!empty)
281 wake_up(&sz->lirc_buf.wait_poll);
284 static inline void push(struct usb_streamzap *sz, unsigned char *data)
286 unsigned long flags;
288 spin_lock_irqsave(&sz->timer_lock, flags);
289 if (lirc_buffer_full(&sz->delay_buf)) {
290 lirc_t data;
292 lirc_buffer_read_1(&sz->delay_buf, (unsigned char *) &data);
293 if (!lirc_buffer_full(&sz->lirc_buf)) {
294 lirc_buffer_write_1(&sz->lirc_buf,
295 (unsigned char *) &data);
296 } else {
297 dprintk("buffer overflow", sz->plugin.minor);
301 lirc_buffer_write_1(&sz->delay_buf, data);
303 if (!sz->timer_running) {
304 sz->delay_timer.expires = jiffies + HZ/10;
305 add_timer(&sz->delay_timer);
306 sz->timer_running = 1;
309 spin_unlock_irqrestore(&sz->timer_lock, flags);
312 static inline void push_full_pulse(struct usb_streamzap *sz,
313 unsigned char value)
315 lirc_t pulse;
317 if (sz->idle) {
318 long deltv;
319 lirc_t tmp;
321 sz->signal_last = sz->signal_start;
322 do_gettimeofday(&sz->signal_start);
324 deltv = sz->signal_start.tv_sec-sz->signal_last.tv_sec;
325 if (deltv > 15) {
326 tmp = PULSE_MASK; /* really long time */
327 } else {
328 tmp = (lirc_t) (deltv*1000000+
329 sz->signal_start.tv_usec -
330 sz->signal_last.tv_usec);
331 tmp -= sz->sum;
333 dprintk("ls %u", sz->plugin.minor, tmp);
334 push(sz, (char *)&tmp);
336 sz->idle = 0;
337 sz->sum = 0;
340 pulse = ((lirc_t) value)*STREAMZAP_RESOLUTION;
341 pulse += STREAMZAP_RESOLUTION/2;
342 sz->sum += pulse;
343 pulse |= PULSE_BIT;
345 dprintk("p %u", sz->plugin.minor, pulse&PULSE_MASK);
346 push(sz, (char *)&pulse);
349 static inline void push_half_pulse(struct usb_streamzap *sz,
350 unsigned char value)
352 push_full_pulse(sz, (value & STREAMZAP_PULSE_MASK)>>4);
355 static inline void push_full_space(struct usb_streamzap *sz,
356 unsigned char value)
358 lirc_t space;
360 space = ((lirc_t) value)*STREAMZAP_RESOLUTION;
361 space += STREAMZAP_RESOLUTION/2;
362 sz->sum += space;
363 dprintk("s %u", sz->plugin.minor, space);
364 push(sz, (char *)&space);
367 static inline void push_half_space(struct usb_streamzap *sz,
368 unsigned char value)
370 push_full_space(sz, value & STREAMZAP_SPACE_MASK);
374 * usb_streamzap_irq - IRQ handler
376 * This procedure is invoked on reception of data from
377 * the usb remote.
379 #if defined(KERNEL_2_5) && LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19)
380 static void usb_streamzap_irq(struct urb *urb, struct pt_regs *regs)
381 #else
382 static void usb_streamzap_irq(struct urb *urb)
383 #endif
385 struct usb_streamzap *sz;
386 int len;
387 unsigned int i = 0;
389 if (!urb)
390 return;
392 sz = urb->context;
393 len = urb->actual_length;
395 switch (urb->status) {
396 case -ECONNRESET:
397 case -ENOENT:
398 case -ESHUTDOWN:
399 /* this urb is terminated, clean up */
400 /* sz might already be invalid at this point */
401 dprintk("urb status: %d", -1, urb->status);
402 return;
403 default:
404 break;
407 dprintk("received %d", sz->plugin.minor, urb->actual_length);
408 if (!sz->flush) {
409 for (i = 0; i < urb->actual_length; i++) {
410 dprintk("%d: %x", sz->plugin.minor,
411 i, (unsigned char) sz->buf_in[i]);
412 switch (sz->decoder_state) {
413 case PulseSpace:
414 if ((sz->buf_in[i]&STREAMZAP_PULSE_MASK) ==
415 STREAMZAP_PULSE_MASK) {
416 sz->decoder_state = FullPulse;
417 continue;
418 } else if ((sz->buf_in[i]&STREAMZAP_SPACE_MASK)
419 == STREAMZAP_SPACE_MASK) {
420 push_half_pulse(sz, sz->buf_in[i]);
421 sz->decoder_state = FullSpace;
422 continue;
423 } else {
424 push_half_pulse(sz, sz->buf_in[i]);
425 push_half_space(sz, sz->buf_in[i]);
427 break;
428 case FullPulse:
429 push_full_pulse(sz, sz->buf_in[i]);
430 sz->decoder_state = IgnorePulse;
431 break;
432 case FullSpace:
433 if (sz->buf_in[i] == 0xff) {
434 sz->idle = 1;
435 stop_timer(sz);
436 flush_delay_buffer(sz);
437 } else
438 push_full_space(sz, sz->buf_in[i]);
439 sz->decoder_state = PulseSpace;
440 break;
441 case IgnorePulse:
442 if ((sz->buf_in[i]&STREAMZAP_SPACE_MASK) ==
443 STREAMZAP_SPACE_MASK) {
444 sz->decoder_state = FullSpace;
445 continue;
447 push_half_space(sz, sz->buf_in[i]);
448 sz->decoder_state = PulseSpace;
449 break;
454 #ifdef KERNEL_2_5
455 /* resubmit only for 2.6 */
456 usb_submit_urb(urb, GFP_ATOMIC);
457 #endif
459 return;
463 * streamzap_probe
465 * Called by usb-core to associated with a candidate device
466 * On any failure the return value is the ERROR
467 * On success return 0
469 #ifdef KERNEL_2_5
470 static int streamzap_probe(struct usb_interface *interface,
471 const struct usb_device_id *id)
473 struct usb_device *udev = interface_to_usbdev(interface);
474 struct usb_host_interface *iface_host;
475 #else
476 static void *streamzap_probe(struct usb_device *udev, unsigned int ifnum,
477 const struct usb_device_id *id)
479 struct usb_interface *interface = &udev->actconfig->interface[ifnum];
480 struct usb_interface_descriptor *iface_host;
481 #endif
482 int retval = -ENOMEM;
483 struct usb_streamzap *sz = NULL;
484 char buf[63], name[128] = "";
486 /***************************************************
487 * Allocate space for device driver specific data
489 sz = kmalloc(sizeof(struct usb_streamzap), GFP_KERNEL);
490 if (sz == NULL)
491 goto error;
493 memset(sz, 0, sizeof(*sz));
494 sz->udev = udev;
495 sz->interface = interface;
497 /***************************************************
498 * Check to ensure endpoint information matches requirements
500 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 5)
501 iface_host = &interface->altsetting[interface->act_altsetting];
502 #else
503 iface_host = interface->cur_altsetting;
504 #endif
506 #ifdef KERNEL_2_5
507 if (iface_host->desc.bNumEndpoints != 1) {
508 #else
509 if (iface_host->bNumEndpoints != 1) {
510 #endif
511 #ifdef KERNEL_2_5
512 err("%s: Unexpected desc.bNumEndpoints (%d)", __FUNCTION__,
513 iface_host->desc.bNumEndpoints);
514 #else
515 err("%s: Unexpected desc.bNumEndpoints (%d)", __FUNCTION__,
516 iface_host->bNumEndpoints);
517 #endif
518 retval = -ENODEV;
519 goto error;
522 #ifdef KERNEL_2_5
523 sz->endpoint = &(iface_host->endpoint[0].desc);
524 #else
525 sz->endpoint = &(iface_host->endpoint[0]);
526 #endif
527 if ((sz->endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK)
528 != USB_DIR_IN) {
529 err("%s: endpoint doesn't match input device 02%02x",
530 __FUNCTION__, sz->endpoint->bEndpointAddress);
531 retval = -ENODEV;
532 goto error;
535 if ((sz->endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
536 != USB_ENDPOINT_XFER_INT) {
537 err("%s: endpoint attributes don't match xfer 02%02x",
538 __FUNCTION__, sz->endpoint->bmAttributes);
539 retval = -ENODEV;
540 goto error;
543 if (sz->endpoint->wMaxPacketSize == 0) {
544 err("%s: endpoint message size==0? ", __FUNCTION__);
545 retval = -ENODEV;
546 goto error;
549 /***************************************************
550 * Allocate the USB buffer and IRQ URB
553 sz->buf_in_len = sz->endpoint->wMaxPacketSize;
554 #ifdef KERNEL_2_5
555 sz->buf_in = usb_buffer_alloc(sz->udev, sz->buf_in_len,
556 GFP_ATOMIC, &sz->dma_in);
557 #else
558 sz->buf_in = kmalloc(sz->buf_in_len, GFP_KERNEL);
559 #endif
560 if (sz->buf_in == NULL)
561 goto error;
563 #ifdef KERNEL_2_5
564 sz->urb_in = usb_alloc_urb(0, GFP_KERNEL);
565 #else
567 sz->urb_in = usb_alloc_urb(0);
568 #endif
569 if (sz->urb_in == NULL)
570 goto error;
572 /***************************************************
573 * Connect this device to the LIRC sub-system
576 if (lirc_buffer_init(&sz->lirc_buf, sizeof(lirc_t),
577 STREAMZAP_BUFFER_SIZE))
578 goto error;
580 if (lirc_buffer_init(&sz->delay_buf, sizeof(lirc_t),
581 STREAMZAP_BUFFER_SIZE)) {
582 lirc_buffer_free(&sz->lirc_buf);
583 goto error;
586 /***************************************************
587 * As required memory is allocated now populate the plugin structure
590 memset(&sz->plugin, 0, sizeof(sz->plugin));
592 strcpy(sz->plugin.name, DRIVER_NAME);
593 sz->plugin.minor = -1;
594 sz->plugin.sample_rate = 0;
595 sz->plugin.code_length = sizeof(lirc_t) * 8;
596 sz->plugin.features = LIRC_CAN_REC_MODE2|LIRC_CAN_GET_REC_RESOLUTION;
597 sz->plugin.data = sz;
598 sz->plugin.rbuf = &sz->lirc_buf;
599 sz->plugin.set_use_inc = &streamzap_use_inc;
600 sz->plugin.set_use_dec = &streamzap_use_dec;
601 sz->plugin.ioctl = streamzap_ioctl;
602 #ifdef LIRC_HAVE_SYSFS
603 sz->plugin.dev = &udev->dev;
604 #endif
605 sz->plugin.owner = THIS_MODULE;
607 sz->idle = 1;
608 sz->decoder_state = PulseSpace;
609 init_timer(&sz->delay_timer);
610 sz->delay_timer.function = delay_timeout;
611 sz->delay_timer.data = (unsigned long) sz;
612 sz->timer_running = 0;
613 spin_lock_init(&sz->timer_lock);
615 init_timer(&sz->flush_timer);
616 sz->flush_timer.function = flush_timeout;
617 sz->flush_timer.data = (unsigned long) sz;
618 /***************************************************
619 * Complete final initialisations
622 usb_fill_int_urb(sz->urb_in, udev,
623 usb_rcvintpipe(udev, sz->endpoint->bEndpointAddress),
624 sz->buf_in, sz->buf_in_len, usb_streamzap_irq, sz,
625 sz->endpoint->bInterval);
627 if (udev->descriptor.iManufacturer
628 && usb_string(udev, udev->descriptor.iManufacturer, buf, 63) > 0)
629 strncpy(name, buf, 128);
631 if (udev->descriptor.iProduct
632 && usb_string(udev, udev->descriptor.iProduct, buf, 63) > 0)
633 snprintf(name, 128, "%s %s", name, buf);
635 printk(KERN_INFO DRIVER_NAME "[%d]: %s on usb%d:%d attached\n",
636 sz->plugin.minor, name,
637 udev->bus->busnum, sz->udev->devnum);
639 #ifdef KERNEL_2_5
640 usb_set_intfdata(interface, sz);
641 #endif
643 if (lirc_register_plugin(&sz->plugin) < 0) {
644 lirc_buffer_free(&sz->delay_buf);
645 lirc_buffer_free(&sz->lirc_buf);
646 goto error;
649 #ifdef KERNEL_2_5
650 return 0;
651 #else
652 return sz;
653 #endif
655 error:
657 /***************************************************
658 * Premise is that a 'goto error' can be invoked from inside the
659 * probe function and all necessary cleanup actions will be taken
660 * including freeing any necessary memory blocks
663 if (retval == -ENOMEM)
664 err("Out of memory");
666 if (sz) {
668 if (sz->urb_in)
669 usb_free_urb(sz->urb_in);
671 if (sz->buf_in) {
672 #ifdef KERNEL_2_5
673 usb_buffer_free(udev, sz->buf_in_len,
674 sz->buf_in, sz->dma_in);
675 #else
676 kfree(sz->buf_in);
677 #endif
679 kfree(sz);
682 #ifdef KERNEL_2_5
683 return retval;
684 #else
685 return NULL;
686 #endif
689 static int streamzap_use_inc(void *data)
691 struct usb_streamzap *sz = data;
693 if (!sz) {
694 dprintk("%s called with no context", -1, __FUNCTION__);
695 return -EINVAL;
697 dprintk("set use inc", sz->plugin.minor);
699 MOD_INC_USE_COUNT;
701 while (!lirc_buffer_empty(&sz->lirc_buf))
702 lirc_buffer_remove_1(&sz->lirc_buf);
703 while (!lirc_buffer_empty(&sz->delay_buf))
704 lirc_buffer_remove_1(&sz->delay_buf);
706 sz->flush_timer.expires = jiffies + HZ;
707 sz->flush = 1;
708 add_timer(&sz->flush_timer);
710 sz->urb_in->dev = sz->udev;
711 #ifdef KERNEL_2_5
712 if (usb_submit_urb(sz->urb_in, GFP_ATOMIC)) {
713 #else
714 if (usb_submit_urb(sz->urb_in)) {
715 #endif
716 dprintk("open result = -EIO error submitting urb",
717 sz->plugin.minor);
718 MOD_DEC_USE_COUNT;
719 return -EIO;
721 sz->in_use++;
723 return 0;
726 static void streamzap_use_dec(void *data)
728 struct usb_streamzap *sz = data;
730 if (!sz) {
731 dprintk("%s called with no context", -1, __FUNCTION__);
732 return;
734 dprintk("set use dec", sz->plugin.minor);
736 if (sz->flush) {
737 sz->flush = 0;
738 del_timer_sync(&sz->flush_timer);
741 usb_kill_urb(sz->urb_in);
743 stop_timer(sz);
745 MOD_DEC_USE_COUNT;
746 sz->in_use--;
749 static int streamzap_ioctl(struct inode *node, struct file *filep,
750 unsigned int cmd, unsigned long arg)
752 int result;
754 switch (cmd) {
755 case LIRC_GET_REC_RESOLUTION:
756 result = put_user(STREAMZAP_RESOLUTION, (unsigned long *) arg);
757 if (result)
758 return(result);
759 break;
760 default:
761 return -ENOIOCTLCMD;
763 return 0;
767 * streamzap_disconnect
769 * Called by the usb core when the device is removed from the system.
771 * This routine guarantees that the driver will not submit any more urbs
772 * by clearing dev->udev. It is also supposed to terminate any currently
773 * active urbs. Unfortunately, usb_bulk_msg(), used in streamzap_read(),
774 * does not provide any way to do this.
776 #ifdef KERNEL_2_5
777 static void streamzap_disconnect(struct usb_interface *interface)
778 #else
779 static void streamzap_disconnect(struct usb_device *dev, void *ptr)
780 #endif
782 struct usb_streamzap *sz;
783 int errnum;
784 int minor;
786 #ifdef KERNEL_2_5
787 sz = usb_get_intfdata(interface);
788 #else
789 sz = ptr;
790 #endif
793 * unregister from the LIRC sub-system
796 errnum = lirc_unregister_plugin(sz->plugin.minor);
797 if (errnum != 0)
798 dprintk("error in lirc_unregister: (returned %d)",
799 sz->plugin.minor, errnum);
801 lirc_buffer_free(&sz->delay_buf);
802 lirc_buffer_free(&sz->lirc_buf);
805 * unregister from the USB sub-system
808 usb_free_urb(sz->urb_in);
810 #ifdef KERNEL_2_5
811 usb_buffer_free(sz->udev, sz->buf_in_len, sz->buf_in, sz->dma_in);
812 #else
813 kfree(sz->buf_in);
814 #endif
816 minor = sz->plugin.minor;
817 kfree(sz);
819 printk(KERN_INFO DRIVER_NAME "[%d]: disconnected\n", minor);
822 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)
823 static int streamzap_suspend(struct usb_interface *intf, pm_message_t message)
825 struct usb_streamzap *sz = usb_get_intfdata(intf);
827 printk(DRIVER_NAME "[%d]: suspend\n", sz->plugin.minor);
828 if (sz->in_use) {
829 if (sz->flush) {
830 sz->flush = 0;
831 del_timer_sync(&sz->flush_timer);
834 stop_timer(sz);
836 usb_kill_urb(sz->urb_in);
838 return 0;
841 static int streamzap_resume(struct usb_interface *intf)
843 struct usb_streamzap *sz = usb_get_intfdata(intf);
845 while (!lirc_buffer_empty(&sz->lirc_buf))
846 lirc_buffer_remove_1(&sz->lirc_buf);
847 while (!lirc_buffer_empty(&sz->delay_buf))
848 lirc_buffer_remove_1(&sz->delay_buf);
850 if (sz->in_use) {
851 sz->flush_timer.expires = jiffies + HZ;
852 sz->flush = 1;
853 add_timer(&sz->flush_timer);
855 sz->urb_in->dev = sz->udev;
856 #ifdef KERNEL_2_5
857 if (usb_submit_urb(sz->urb_in, GFP_ATOMIC)) {
858 #else
859 if (usb_submit_urb(sz->urb_in)) {
860 #endif
861 dprintk("open result = -EIO error submitting urb",
862 sz->plugin.minor);
863 MOD_DEC_USE_COUNT;
864 return -EIO;
867 return 0;
869 #endif
871 #ifdef MODULE
874 * usb_streamzap_init
876 static int __init usb_streamzap_init(void)
878 int result;
880 /* register this driver with the USB subsystem */
882 result = usb_register(&streamzap_driver);
884 if (result) {
885 err("usb_register failed. Error number %d",
886 result);
887 return result;
890 printk(KERN_INFO DRIVER_NAME " " DRIVER_VERSION " registered\n");
891 return 0;
895 * usb_streamzap_exit
897 static void __exit usb_streamzap_exit(void)
899 /* deregister this driver with the USB subsystem */
900 usb_deregister(&streamzap_driver);
904 module_init(usb_streamzap_init);
905 module_exit(usb_streamzap_exit);
907 MODULE_AUTHOR("Christoph Bartelmus, Greg Wickham, Adrian Dewhurst");
908 MODULE_DESCRIPTION(DRIVER_DESC);
909 MODULE_LICENSE("GPL");
911 module_param(debug, bool, 0644);
912 MODULE_PARM_DESC(debug, "Enable debugging messages");
914 EXPORT_NO_SYMBOLS;
916 #endif /* MODULE */