Commit 8e9e60640067858e8036d4d43bbf725c60613359

Authored by Jarod Wilson
Committed by Mauro Carvalho Chehab
1 parent 7c294402d5

V4L/DVB: staging/lirc: port lirc_streamzap to ir-core

This ports lirc_streamzap.c over to ir-core in-place, to be followed by
a patch moving the driver over to drivers/media/IR/streamzap.c and
enabling the proper Kconfig bits.

Presently, the in-kernel keymap doesn't work, as the stock Streamzap
remote uses an RC-5-like, but not-quite-RC-5 protocol, which the
in-kernel RC-5 decoder doesn't cope with. The remote can be used right
now with the lirc bridge driver though, and other remotes (at least an
RC-6(A) MCE remote) work perfectly with the driver.

I'll take a look at making the existing RC-5 decoder cope with this odd
duck, possibly implement another standalone decoder engine, or just
throw up my hands and say "meh, use lirc"... But the driver itself
should be perfectly sound.

Remaining items on the streamzap TODO list:
- add LIRC_SET_REC_TIMEOUT-alike support
- add LIRC_GET_M{AX,IN}_TIMEOUT-alike support
- add LIRC_GET_REC_RESOLUTION-alike support

All of the above should be trivial to add. There are patches pending to
add this support to ir-core from Maxim Levitsky, and I'll take care of
these once his patches get integrated. None of them are currently
essential though.

Signed-off-by: Jarod Wilson <jarod@redhat.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>

Showing 4 changed files with 449 additions and 446 deletions Side-by-side Diff

drivers/media/IR/keymaps/Makefile
... ... @@ -59,6 +59,7 @@
59 59 rc-purpletv.o \
60 60 rc-pv951.o \
61 61 rc-rc5-hauppauge-new.o \
  62 + rc-rc5-streamzap.o \
62 63 rc-rc5-tv.o \
63 64 rc-rc6-mce.o \
64 65 rc-real-audio-220-32-keys.o \
drivers/media/IR/keymaps/rc-rc5-streamzap.c
  1 +/* rc-rc5-streamzap.c - Keytable for Streamzap PC Remote, for use
  2 + * with the Streamzap PC Remote IR Receiver.
  3 + *
  4 + * Copyright (c) 2010 by Jarod Wilson <jarod@redhat.com>
  5 + *
  6 + * This program is free software; you can redistribute it and/or modify
  7 + * it under the terms of the GNU General Public License as published by
  8 + * the Free Software Foundation; either version 2 of the License, or
  9 + * (at your option) any later version.
  10 + */
  11 +
  12 +#include <media/rc-map.h>
  13 +
  14 +static struct ir_scancode rc5_streamzap[] = {
  15 +/*
  16 + * FIXME: The Streamzap remote isn't actually true RC-5, it has an extra
  17 + * bit in it, which presently throws the in-kernel RC-5 decoder for a loop.
  18 + * We either have to enhance the decoder to support it, add a new decoder,
  19 + * or just rely on lirc userspace decoding.
  20 + */
  21 + { 0x00, KEY_NUMERIC_0 },
  22 + { 0x01, KEY_NUMERIC_1 },
  23 + { 0x02, KEY_NUMERIC_2 },
  24 + { 0x03, KEY_NUMERIC_3 },
  25 + { 0x04, KEY_NUMERIC_4 },
  26 + { 0x05, KEY_NUMERIC_5 },
  27 + { 0x06, KEY_NUMERIC_6 },
  28 + { 0x07, KEY_NUMERIC_7 },
  29 + { 0x08, KEY_NUMERIC_8 },
  30 + { 0x0a, KEY_POWER },
  31 + { 0x0b, KEY_MUTE },
  32 + { 0x0c, KEY_CHANNELUP },
  33 + { 0x0d, KEY_VOLUMEUP },
  34 + { 0x0e, KEY_CHANNELDOWN },
  35 + { 0x0f, KEY_VOLUMEDOWN },
  36 + { 0x10, KEY_UP },
  37 + { 0x11, KEY_LEFT },
  38 + { 0x12, KEY_OK },
  39 + { 0x13, KEY_RIGHT },
  40 + { 0x14, KEY_DOWN },
  41 + { 0x15, KEY_MENU },
  42 + { 0x16, KEY_EXIT },
  43 + { 0x17, KEY_PLAY },
  44 + { 0x18, KEY_PAUSE },
  45 + { 0x19, KEY_STOP },
  46 + { 0x1a, KEY_BACK },
  47 + { 0x1b, KEY_FORWARD },
  48 + { 0x1c, KEY_RECORD },
  49 + { 0x1d, KEY_REWIND },
  50 + { 0x1e, KEY_FASTFORWARD },
  51 + { 0x20, KEY_RED },
  52 + { 0x21, KEY_GREEN },
  53 + { 0x22, KEY_YELLOW },
  54 + { 0x23, KEY_BLUE },
  55 +
  56 +};
  57 +
  58 +static struct rc_keymap rc5_streamzap_map = {
  59 + .map = {
  60 + .scan = rc5_streamzap,
  61 + .size = ARRAY_SIZE(rc5_streamzap),
  62 + .ir_type = IR_TYPE_RC5,
  63 + .name = RC_MAP_RC5_STREAMZAP,
  64 + }
  65 +};
  66 +
  67 +static int __init init_rc_map_rc5_streamzap(void)
  68 +{
  69 + return ir_register_map(&rc5_streamzap_map);
  70 +}
  71 +
  72 +static void __exit exit_rc_map_rc5_streamzap(void)
  73 +{
  74 + ir_unregister_map(&rc5_streamzap_map);
  75 +}
  76 +
  77 +module_init(init_rc_map_rc5_streamzap)
  78 +module_exit(exit_rc_map_rc5_streamzap)
  79 +
  80 +MODULE_LICENSE("GPL");
  81 +MODULE_AUTHOR("Jarod Wilson <jarod@redhat.com>");
drivers/staging/lirc/lirc_streamzap.c
Changes suppressed. Click to show
... ... @@ -2,6 +2,7 @@
2 2 * Streamzap Remote Control driver
3 3 *
4 4 * Copyright (c) 2005 Christoph Bartelmus <lirc@bartelmus.de>
  5 + * Copyright (c) 2010 Jarod Wilson <jarod@wilsonet.com>
5 6 *
6 7 * This driver was based on the work of Greg Wickham and Adrian
7 8 * Dewhurst. It was substantially rewritten to support correct signal
... ... @@ -10,6 +11,8 @@
10 11 * delay buffer an ugly hack would be required in lircd, which can
11 12 * cause sluggish signal decoding in certain situations.
12 13 *
  14 + * Ported to in-kernel ir-core interface by Jarod Wilson
  15 + *
13 16 * This driver is based on the USB skeleton driver packaged with the
14 17 * kernel; copyright (C) 2001-2003 Greg Kroah-Hartman (greg@kroah.com)
15 18 *
16 19  
17 20  
18 21  
19 22  
20 23  
21 24  
... ... @@ -28,36 +31,26 @@
28 31 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
29 32 */
30 33  
31   -#include <linux/kernel.h>
32   -#include <linux/errno.h>
33   -#include <linux/init.h>
34   -#include <linux/slab.h>
  34 +#include <linux/device.h>
35 35 #include <linux/module.h>
36   -#include <linux/smp_lock.h>
37   -#include <linux/completion.h>
38   -#include <linux/uaccess.h>
  36 +#include <linux/slab.h>
39 37 #include <linux/usb.h>
  38 +#include <linux/input.h>
  39 +#include <media/ir-core.h>
40 40  
41   -#include <media/lirc.h>
42   -#include <media/lirc_dev.h>
43   -
44   -#define DRIVER_VERSION "1.28"
45   -#define DRIVER_NAME "lirc_streamzap"
  41 +#define DRIVER_VERSION "1.60"
  42 +#define DRIVER_NAME "streamzap"
46 43 #define DRIVER_DESC "Streamzap Remote Control driver"
47 44  
  45 +#ifdef CONFIG_USB_DEBUG
  46 +static int debug = 1;
  47 +#else
48 48 static int debug;
  49 +#endif
49 50  
50 51 #define USB_STREAMZAP_VENDOR_ID 0x0e9c
51 52 #define USB_STREAMZAP_PRODUCT_ID 0x0000
52 53  
53   -/* Use our own dbg macro */
54   -#define dprintk(fmt, args...) \
55   - do { \
56   - if (debug) \
57   - printk(KERN_DEBUG DRIVER_NAME "[%d]: " \
58   - fmt "\n", ## args); \
59   - } while (0)
60   -
61 54 /* table of devices that work with this driver */
62 55 static struct usb_device_id streamzap_table[] = {
63 56 /* Streamzap Remote Control */
... ... @@ -74,7 +67,7 @@
74 67 #define STREAMZAP_RESOLUTION 256
75 68  
76 69 /* number of samples buffered */
77   -#define STREAMZAP_BUF_LEN 128
  70 +#define SZ_BUF_LEN 128
78 71  
79 72 enum StreamzapDecoderState {
80 73 PulseSpace,
81 74  
82 75  
83 76  
84 77  
85 78  
86 79  
87 80  
88 81  
89 82  
... ... @@ -83,65 +76,52 @@
83 76 IgnorePulse
84 77 };
85 78  
86   -/* Structure to hold all of our device specific stuff
87   - *
88   - * some remarks regarding locking:
89   - * theoretically this struct can be accessed from three threads:
90   - *
91   - * - from lirc_dev through set_use_inc/set_use_dec
92   - *
93   - * - from the USB layer throuh probe/disconnect/irq
94   - *
95   - * Careful placement of lirc_register_driver/lirc_unregister_driver
96   - * calls will prevent conflicts. lirc_dev makes sure that
97   - * set_use_inc/set_use_dec are not being executed and will not be
98   - * called after lirc_unregister_driver returns.
99   - *
100   - * - by the timer callback
101   - *
102   - * The timer is only running when the device is connected and the
103   - * LIRC device is open. Making sure the timer is deleted by
104   - * set_use_dec will make conflicts impossible.
105   - */
106   -struct usb_streamzap {
  79 +/* structure to hold our device specific stuff */
  80 +struct streamzap_ir {
107 81  
  82 + /* ir-core */
  83 + struct ir_dev_props *props;
  84 + struct ir_raw_event rawir;
  85 +
  86 + /* core device info */
  87 + struct device *dev;
  88 + struct input_dev *idev;
  89 +
108 90 /* usb */
109   - /* save off the usb device pointer */
110   - struct usb_device *udev;
111   - /* the interface for this device */
  91 + struct usb_device *usbdev;
112 92 struct usb_interface *interface;
  93 + struct usb_endpoint_descriptor *endpoint;
  94 + struct urb *urb_in;
113 95  
114 96 /* buffer & dma */
115 97 unsigned char *buf_in;
116 98 dma_addr_t dma_in;
117 99 unsigned int buf_in_len;
118 100  
119   - struct usb_endpoint_descriptor *endpoint;
120   -
121   - /* IRQ */
122   - struct urb *urb_in;
123   -
124   - /* lirc */
125   - struct lirc_driver *driver;
126   - struct lirc_buffer *delay_buf;
127   -
128 101 /* timer used to support delay buffering */
129 102 struct timer_list delay_timer;
130   - int timer_running;
  103 + bool timer_running;
131 104 spinlock_t timer_lock;
  105 + struct timer_list flush_timer;
  106 + bool flush;
132 107  
  108 + /* delay buffer */
  109 + struct kfifo fifo;
  110 + bool fifo_initialized;
  111 +
  112 + /* track what state we're in */
  113 + enum StreamzapDecoderState decoder_state;
133 114 /* tracks whether we are currently receiving some signal */
134   - int idle;
  115 + bool idle;
135 116 /* sum of signal lengths received since signal start */
136 117 unsigned long sum;
137 118 /* start time of signal; necessary for gap tracking */
138 119 struct timeval signal_last;
139 120 struct timeval signal_start;
140   - enum StreamzapDecoderState decoder_state;
141   - struct timer_list flush_timer;
142   - int flush;
143   - int in_use;
144   - int timeout_enabled;
  121 + /* bool timeout_enabled; */
  122 +
  123 + char name[128];
  124 + char phys[64];
145 125 };
146 126  
147 127  
148 128  
... ... @@ -149,16 +129,11 @@
149 129 static int streamzap_probe(struct usb_interface *interface,
150 130 const struct usb_device_id *id);
151 131 static void streamzap_disconnect(struct usb_interface *interface);
152   -static void usb_streamzap_irq(struct urb *urb);
153   -static int streamzap_use_inc(void *data);
154   -static void streamzap_use_dec(void *data);
155   -static long streamzap_ioctl(struct file *filep, unsigned int cmd,
156   - unsigned long arg);
  132 +static void streamzap_callback(struct urb *urb);
157 133 static int streamzap_suspend(struct usb_interface *intf, pm_message_t message);
158 134 static int streamzap_resume(struct usb_interface *intf);
159 135  
160 136 /* usb specific object needed to register this driver with the usb subsystem */
161   -
162 137 static struct usb_driver streamzap_driver = {
163 138 .name = DRIVER_NAME,
164 139 .probe = streamzap_probe,
165 140  
... ... @@ -168,13 +143,13 @@
168 143 .id_table = streamzap_table,
169 144 };
170 145  
171   -static void stop_timer(struct usb_streamzap *sz)
  146 +static void streamzap_stop_timer(struct streamzap_ir *sz)
172 147 {
173 148 unsigned long flags;
174 149  
175 150 spin_lock_irqsave(&sz->timer_lock, flags);
176 151 if (sz->timer_running) {
177   - sz->timer_running = 0;
  152 + sz->timer_running = false;
178 153 spin_unlock_irqrestore(&sz->timer_lock, flags);
179 154 del_timer_sync(&sz->delay_timer);
180 155 } else {
181 156  
182 157  
183 158  
184 159  
185 160  
186 161  
187 162  
188 163  
189 164  
190 165  
191 166  
192 167  
193 168  
194 169  
195 170  
196 171  
197 172  
198 173  
199 174  
200 175  
201 176  
202 177  
203 178  
204 179  
205 180  
206 181  
207 182  
208 183  
209 184  
210 185  
211 186  
212 187  
213 188  
214 189  
215 190  
216 191  
217 192  
218 193  
219 194  
220 195  
... ... @@ -182,175 +157,183 @@
182 157 }
183 158 }
184 159  
185   -static void flush_timeout(unsigned long arg)
  160 +static void streamzap_flush_timeout(unsigned long arg)
186 161 {
187   - struct usb_streamzap *sz = (struct usb_streamzap *) arg;
  162 + struct streamzap_ir *sz = (struct streamzap_ir *)arg;
188 163  
  164 + dev_info(sz->dev, "%s: callback firing\n", __func__);
  165 +
189 166 /* finally start accepting data */
190   - sz->flush = 0;
  167 + sz->flush = false;
191 168 }
192   -static void delay_timeout(unsigned long arg)
  169 +
  170 +static void streamzap_delay_timeout(unsigned long arg)
193 171 {
  172 + struct streamzap_ir *sz = (struct streamzap_ir *)arg;
  173 + struct ir_raw_event rawir = { .pulse = false, .duration = 0 };
194 174 unsigned long flags;
  175 + int len, ret;
  176 + static unsigned long delay;
  177 + bool wake = false;
  178 +
195 179 /* deliver data every 10 ms */
196   - static unsigned long timer_inc =
197   - (10000/(1000000/HZ)) == 0 ? 1 : (10000/(1000000/HZ));
198   - struct usb_streamzap *sz = (struct usb_streamzap *) arg;
199   - int data;
  180 + delay = msecs_to_jiffies(10);
200 181  
201 182 spin_lock_irqsave(&sz->timer_lock, flags);
202 183  
203   - if (!lirc_buffer_empty(sz->delay_buf) &&
204   - !lirc_buffer_full(sz->driver->rbuf)) {
205   - lirc_buffer_read(sz->delay_buf, (unsigned char *) &data);
206   - lirc_buffer_write(sz->driver->rbuf, (unsigned char *) &data);
  184 + if (kfifo_len(&sz->fifo) > 0) {
  185 + ret = kfifo_out(&sz->fifo, &rawir, sizeof(rawir));
  186 + if (ret != sizeof(rawir))
  187 + dev_err(sz->dev, "Problem w/kfifo_out...\n");
  188 + ir_raw_event_store(sz->idev, &rawir);
  189 + wake = true;
207 190 }
208   - if (!lirc_buffer_empty(sz->delay_buf)) {
209   - while (lirc_buffer_available(sz->delay_buf) <
210   - STREAMZAP_BUF_LEN / 2 &&
211   - !lirc_buffer_full(sz->driver->rbuf)) {
212   - lirc_buffer_read(sz->delay_buf,
213   - (unsigned char *) &data);
214   - lirc_buffer_write(sz->driver->rbuf,
215   - (unsigned char *) &data);
  191 +
  192 + len = kfifo_len(&sz->fifo);
  193 + if (len > 0) {
  194 + while ((len < SZ_BUF_LEN / 2) &&
  195 + (len < SZ_BUF_LEN * sizeof(int))) {
  196 + ret = kfifo_out(&sz->fifo, &rawir, sizeof(rawir));
  197 + if (ret != sizeof(rawir))
  198 + dev_err(sz->dev, "Problem w/kfifo_out...\n");
  199 + ir_raw_event_store(sz->idev, &rawir);
  200 + wake = true;
  201 + len = kfifo_len(&sz->fifo);
216 202 }
217   - if (sz->timer_running) {
218   - sz->delay_timer.expires = jiffies + timer_inc;
219   - add_timer(&sz->delay_timer);
220   - }
  203 + if (sz->timer_running)
  204 + mod_timer(&sz->delay_timer, jiffies + delay);
  205 +
221 206 } else {
222   - sz->timer_running = 0;
  207 + sz->timer_running = false;
223 208 }
224 209  
225   - if (!lirc_buffer_empty(sz->driver->rbuf))
226   - wake_up(&sz->driver->rbuf->wait_poll);
  210 + if (wake)
  211 + ir_raw_event_handle(sz->idev);
227 212  
228 213 spin_unlock_irqrestore(&sz->timer_lock, flags);
229 214 }
230 215  
231   -static void flush_delay_buffer(struct usb_streamzap *sz)
  216 +static void streamzap_flush_delay_buffer(struct streamzap_ir *sz)
232 217 {
233   - int data;
234   - int empty = 1;
  218 + struct ir_raw_event rawir = { .pulse = false, .duration = 0 };
  219 + bool wake = false;
  220 + int ret;
235 221  
236   - while (!lirc_buffer_empty(sz->delay_buf)) {
237   - empty = 0;
238   - lirc_buffer_read(sz->delay_buf, (unsigned char *) &data);
239   - if (!lirc_buffer_full(sz->driver->rbuf)) {
240   - lirc_buffer_write(sz->driver->rbuf,
241   - (unsigned char *) &data);
242   - } else {
243   - dprintk("buffer overflow", sz->driver->minor);
244   - }
  222 + while (kfifo_len(&sz->fifo) > 0) {
  223 + ret = kfifo_out(&sz->fifo, &rawir, sizeof(rawir));
  224 + if (ret != sizeof(rawir))
  225 + dev_err(sz->dev, "Problem w/kfifo_out...\n");
  226 + ir_raw_event_store(sz->idev, &rawir);
  227 + wake = true;
245 228 }
246   - if (!empty)
247   - wake_up(&sz->driver->rbuf->wait_poll);
  229 +
  230 + if (wake)
  231 + ir_raw_event_handle(sz->idev);
248 232 }
249 233  
250   -static void push(struct usb_streamzap *sz, unsigned char *data)
  234 +static void sz_push(struct streamzap_ir *sz)
251 235 {
  236 + struct ir_raw_event rawir = { .pulse = false, .duration = 0 };
252 237 unsigned long flags;
  238 + int ret;
253 239  
254 240 spin_lock_irqsave(&sz->timer_lock, flags);
255   - if (lirc_buffer_full(sz->delay_buf)) {
256   - int read_data;
257   -
258   - lirc_buffer_read(sz->delay_buf,
259   - (unsigned char *) &read_data);
260   - if (!lirc_buffer_full(sz->driver->rbuf)) {
261   - lirc_buffer_write(sz->driver->rbuf,
262   - (unsigned char *) &read_data);
263   - } else {
264   - dprintk("buffer overflow", sz->driver->minor);
265   - }
  241 + if (kfifo_len(&sz->fifo) >= sizeof(int) * SZ_BUF_LEN) {
  242 + ret = kfifo_out(&sz->fifo, &rawir, sizeof(rawir));
  243 + if (ret != sizeof(rawir))
  244 + dev_err(sz->dev, "Problem w/kfifo_out...\n");
  245 + ir_raw_event_store(sz->idev, &rawir);
266 246 }
267 247  
268   - lirc_buffer_write(sz->delay_buf, data);
  248 + kfifo_in(&sz->fifo, &sz->rawir, sizeof(rawir));
269 249  
270 250 if (!sz->timer_running) {
271   - sz->delay_timer.expires = jiffies + HZ/10;
  251 + sz->delay_timer.expires = jiffies + (HZ / 10);
272 252 add_timer(&sz->delay_timer);
273   - sz->timer_running = 1;
  253 + sz->timer_running = true;
274 254 }
275 255  
276 256 spin_unlock_irqrestore(&sz->timer_lock, flags);
277 257 }
278 258  
279   -static void push_full_pulse(struct usb_streamzap *sz,
280   - unsigned char value)
  259 +static void sz_push_full_pulse(struct streamzap_ir *sz,
  260 + unsigned char value)
281 261 {
282   - int pulse;
283   -
284 262 if (sz->idle) {
285 263 long deltv;
286   - int tmp;
287 264  
288 265 sz->signal_last = sz->signal_start;
289 266 do_gettimeofday(&sz->signal_start);
290 267  
291   - deltv = sz->signal_start.tv_sec-sz->signal_last.tv_sec;
  268 + deltv = sz->signal_start.tv_sec - sz->signal_last.tv_sec;
  269 + sz->rawir.pulse = false;
292 270 if (deltv > 15) {
293 271 /* really long time */
294   - tmp = LIRC_SPACE(LIRC_VALUE_MASK);
  272 + sz->rawir.duration = IR_MAX_DURATION;
295 273 } else {
296   - tmp = (int) (deltv*1000000+
297   - sz->signal_start.tv_usec -
298   - sz->signal_last.tv_usec);
299   - tmp -= sz->sum;
300   - tmp = LIRC_SPACE(tmp);
  274 + sz->rawir.duration = (int)(deltv * 1000000 +
  275 + sz->signal_start.tv_usec -
  276 + sz->signal_last.tv_usec);
  277 + sz->rawir.duration -= sz->sum;
  278 + sz->rawir.duration *= 1000;
  279 + sz->rawir.duration &= IR_MAX_DURATION;
301 280 }
302   - dprintk("ls %u", sz->driver->minor, tmp);
303   - push(sz, (char *)&tmp);
  281 + dev_dbg(sz->dev, "ls %u\n", sz->rawir.duration);
  282 + sz_push(sz);
304 283  
305 284 sz->idle = 0;
306 285 sz->sum = 0;
307 286 }
308 287  
309   - pulse = ((int) value) * STREAMZAP_RESOLUTION;
310   - pulse += STREAMZAP_RESOLUTION / 2;
311   - sz->sum += pulse;
312   - pulse = LIRC_PULSE(pulse);
313   -
314   - dprintk("p %u", sz->driver->minor, pulse & PULSE_MASK);
315   - push(sz, (char *)&pulse);
  288 + sz->rawir.pulse = true;
  289 + sz->rawir.duration = ((int) value) * STREAMZAP_RESOLUTION;
  290 + sz->rawir.duration += STREAMZAP_RESOLUTION / 2;
  291 + sz->sum += sz->rawir.duration;
  292 + sz->rawir.duration *= 1000;
  293 + sz->rawir.duration &= IR_MAX_DURATION;
  294 + dev_dbg(sz->dev, "p %u\n", sz->rawir.duration);
  295 + sz_push(sz);
316 296 }
317 297  
318   -static void push_half_pulse(struct usb_streamzap *sz,
319   - unsigned char value)
  298 +static void sz_push_half_pulse(struct streamzap_ir *sz,
  299 + unsigned char value)
320 300 {
321   - push_full_pulse(sz, (value & STREAMZAP_PULSE_MASK)>>4);
  301 + sz_push_full_pulse(sz, (value & STREAMZAP_PULSE_MASK) >> 4);
322 302 }
323 303  
324   -static void push_full_space(struct usb_streamzap *sz,
325   - unsigned char value)
  304 +static void sz_push_full_space(struct streamzap_ir *sz,
  305 + unsigned char value)
326 306 {
327   - int space;
328   -
329   - space = ((int) value)*STREAMZAP_RESOLUTION;
330   - space += STREAMZAP_RESOLUTION/2;
331   - sz->sum += space;
332   - space = LIRC_SPACE(space);
333   - dprintk("s %u", sz->driver->minor, space);
334   - push(sz, (char *)&space);
  307 + sz->rawir.pulse = false;
  308 + sz->rawir.duration = ((int) value) * STREAMZAP_RESOLUTION;
  309 + sz->rawir.duration += STREAMZAP_RESOLUTION / 2;
  310 + sz->sum += sz->rawir.duration;
  311 + sz->rawir.duration *= 1000;
  312 + dev_dbg(sz->dev, "s %u\n", sz->rawir.duration);
  313 + sz_push(sz);
335 314 }
336 315  
337   -static void push_half_space(struct usb_streamzap *sz,
338   - unsigned char value)
  316 +static void sz_push_half_space(struct streamzap_ir *sz,
  317 + unsigned long value)
339 318 {
340   - push_full_space(sz, value & STREAMZAP_SPACE_MASK);
  319 + sz_push_full_space(sz, value & STREAMZAP_SPACE_MASK);
341 320 }
342 321  
343 322 /**
344   - * usb_streamzap_irq - IRQ handler
  323 + * streamzap_callback - usb IRQ handler callback
345 324 *
346 325 * This procedure is invoked on reception of data from
347 326 * the usb remote.
348 327 */
349   -static void usb_streamzap_irq(struct urb *urb)
  328 +static void streamzap_callback(struct urb *urb)
350 329 {
351   - struct usb_streamzap *sz;
352   - int len;
353   - unsigned int i = 0;
  330 + struct streamzap_ir *sz;
  331 + unsigned int i;
  332 + int len;
  333 + #if 0
  334 + static int timeout = (((STREAMZAP_TIMEOUT * STREAMZAP_RESOLUTION) &
  335 + IR_MAX_DURATION) | 0x03000000);
  336 + #endif
354 337  
355 338 if (!urb)
356 339 return;
357 340  
358 341  
359 342  
360 343  
361 344  
362 345  
363 346  
364 347  
365 348  
366 349  
367 350  
... ... @@ -366,51 +349,52 @@
366 349 * this urb is terminated, clean up.
367 350 * sz might already be invalid at this point
368 351 */
369   - dprintk("urb status: %d", -1, urb->status);
  352 + dev_err(sz->dev, "urb terminated, status: %d\n", urb->status);
370 353 return;
371 354 default:
372 355 break;
373 356 }
374 357  
375   - dprintk("received %d", sz->driver->minor, urb->actual_length);
  358 + dev_dbg(sz->dev, "%s: received urb, len %d\n", __func__, len);
376 359 if (!sz->flush) {
377 360 for (i = 0; i < urb->actual_length; i++) {
378   - dprintk("%d: %x", sz->driver->minor,
379   - i, (unsigned char) sz->buf_in[i]);
  361 + dev_dbg(sz->dev, "%d: %x\n", i,
  362 + (unsigned char)sz->buf_in[i]);
380 363 switch (sz->decoder_state) {
381 364 case PulseSpace:
382   - if ((sz->buf_in[i]&STREAMZAP_PULSE_MASK) ==
  365 + if ((sz->buf_in[i] & STREAMZAP_PULSE_MASK) ==
383 366 STREAMZAP_PULSE_MASK) {
384 367 sz->decoder_state = FullPulse;
385 368 continue;
386   - } else if ((sz->buf_in[i]&STREAMZAP_SPACE_MASK)
  369 + } else if ((sz->buf_in[i] & STREAMZAP_SPACE_MASK)
387 370 == STREAMZAP_SPACE_MASK) {
388   - push_half_pulse(sz, sz->buf_in[i]);
  371 + sz_push_half_pulse(sz, sz->buf_in[i]);
389 372 sz->decoder_state = FullSpace;
390 373 continue;
391 374 } else {
392   - push_half_pulse(sz, sz->buf_in[i]);
393   - push_half_space(sz, sz->buf_in[i]);
  375 + sz_push_half_pulse(sz, sz->buf_in[i]);
  376 + sz_push_half_space(sz, sz->buf_in[i]);
394 377 }
395 378 break;
396 379 case FullPulse:
397   - push_full_pulse(sz, sz->buf_in[i]);
  380 + sz_push_full_pulse(sz, sz->buf_in[i]);
398 381 sz->decoder_state = IgnorePulse;
399 382 break;
400 383 case FullSpace:
401 384 if (sz->buf_in[i] == STREAMZAP_TIMEOUT) {
402 385 sz->idle = 1;
403   - stop_timer(sz);
  386 + streamzap_stop_timer(sz);
  387 + #if 0
404 388 if (sz->timeout_enabled) {
405   - int timeout =
406   - LIRC_TIMEOUT
407   - (STREAMZAP_TIMEOUT *
408   - STREAMZAP_RESOLUTION);
409   - push(sz, (char *)&timeout);
  389 + sz->rawir.pulse = false;
  390 + sz->rawir.duration = timeout;
  391 + sz->rawir.duration *= 1000;
  392 + sz_push(sz);
410 393 }
411   - flush_delay_buffer(sz);
  394 + #endif
  395 + streamzap_flush_delay_buffer(sz);
412 396 } else
413   - push_full_space(sz, sz->buf_in[i]);
  397 + sz_push_full_space(sz, sz->buf_in[i]);
414 398 sz->decoder_state = PulseSpace;
415 399 break;
416 400 case IgnorePulse:
... ... @@ -419,7 +403,7 @@
419 403 sz->decoder_state = FullSpace;
420 404 continue;
421 405 }
422   - push_half_space(sz, sz->buf_in[i]);
  406 + sz_push_half_space(sz, sz->buf_in[i]);
423 407 sz->decoder_state = PulseSpace;
424 408 break;
425 409 }
426 410  
427 411  
... ... @@ -431,17 +415,81 @@
431 415 return;
432 416 }
433 417  
434   -static const struct file_operations streamzap_fops = {
435   - .owner = THIS_MODULE,
436   - .unlocked_ioctl = streamzap_ioctl,
437   - .read = lirc_dev_fop_read,
438   - .write = lirc_dev_fop_write,
439   - .poll = lirc_dev_fop_poll,
440   - .open = lirc_dev_fop_open,
441   - .release = lirc_dev_fop_close,
442   -};
  418 +static struct input_dev *streamzap_init_input_dev(struct streamzap_ir *sz)
  419 +{
  420 + struct input_dev *idev;
  421 + struct ir_dev_props *props;
  422 + struct device *dev = sz->dev;
  423 + int ret;
443 424  
  425 + idev = input_allocate_device();
  426 + if (!idev) {
  427 + dev_err(dev, "remote input dev allocation failed\n");
  428 + goto idev_alloc_failed;
  429 + }
444 430  
  431 + props = kzalloc(sizeof(struct ir_dev_props), GFP_KERNEL);
  432 + if (!props) {
  433 + dev_err(dev, "remote ir dev props allocation failed\n");
  434 + goto props_alloc_failed;
  435 + }
  436 +
  437 + snprintf(sz->name, sizeof(sz->name), "Streamzap PC Remote Infrared "
  438 + "Receiver (%04x:%04x)",
  439 + le16_to_cpu(sz->usbdev->descriptor.idVendor),
  440 + le16_to_cpu(sz->usbdev->descriptor.idProduct));
  441 +
  442 + idev->name = sz->name;
  443 + usb_make_path(sz->usbdev, sz->phys, sizeof(sz->phys));
  444 + strlcat(sz->phys, "/input0", sizeof(sz->phys));
  445 + idev->phys = sz->phys;
  446 +
  447 + props->priv = sz;
  448 + props->driver_type = RC_DRIVER_IR_RAW;
  449 + /* FIXME: not sure about supported protocols, check on this */
  450 + props->allowed_protos = IR_TYPE_RC5 | IR_TYPE_RC6;
  451 +
  452 + sz->props = props;
  453 +
  454 + ret = ir_input_register(idev, RC_MAP_RC5_STREAMZAP, props, DRIVER_NAME);
  455 + if (ret < 0) {
  456 + dev_err(dev, "remote input device register failed\n");
  457 + goto irdev_failed;
  458 + }
  459 +
  460 + return idev;
  461 +
  462 +irdev_failed:
  463 + kfree(props);
  464 +props_alloc_failed:
  465 + input_free_device(idev);
  466 +idev_alloc_failed:
  467 + return NULL;
  468 +}
  469 +
  470 +static int streamzap_delay_buf_init(struct streamzap_ir *sz)
  471 +{
  472 + int ret;
  473 +
  474 + ret = kfifo_alloc(&sz->fifo, sizeof(int) * SZ_BUF_LEN,
  475 + GFP_KERNEL);
  476 + if (ret == 0)
  477 + sz->fifo_initialized = 1;
  478 +
  479 + return ret;
  480 +}
  481 +
  482 +static void streamzap_start_flush_timer(struct streamzap_ir *sz)
  483 +{
  484 + sz->flush_timer.expires = jiffies + HZ;
  485 + sz->flush = true;
  486 + add_timer(&sz->flush_timer);
  487 +
  488 + sz->urb_in->dev = sz->usbdev;
  489 + if (usb_submit_urb(sz->urb_in, GFP_ATOMIC))
  490 + dev_err(sz->dev, "urb submit failed\n");
  491 +}
  492 +
445 493 /**
446 494 * streamzap_probe
447 495 *
448 496  
449 497  
450 498  
451 499  
452 500  
453 501  
454 502  
... ... @@ -449,33 +497,30 @@
449 497 * On any failure the return value is the ERROR
450 498 * On success return 0
451 499 */
452   -static int streamzap_probe(struct usb_interface *interface,
453   - const struct usb_device_id *id)
  500 +static int __devinit streamzap_probe(struct usb_interface *intf,
  501 + const struct usb_device_id *id)
454 502 {
455   - struct usb_device *udev = interface_to_usbdev(interface);
  503 + struct usb_device *usbdev = interface_to_usbdev(intf);
456 504 struct usb_host_interface *iface_host;
457   - struct usb_streamzap *sz;
458   - struct lirc_driver *driver;
459   - struct lirc_buffer *lirc_buf;
460   - struct lirc_buffer *delay_buf;
  505 + struct streamzap_ir *sz = NULL;
461 506 char buf[63], name[128] = "";
462 507 int retval = -ENOMEM;
463   - int minor = 0;
  508 + int pipe, maxp;
464 509  
465 510 /* Allocate space for device driver specific data */
466   - sz = kzalloc(sizeof(struct usb_streamzap), GFP_KERNEL);
467   - if (sz == NULL)
  511 + sz = kzalloc(sizeof(struct streamzap_ir), GFP_KERNEL);
  512 + if (!sz)
468 513 return -ENOMEM;
469 514  
470   - sz->udev = udev;
471   - sz->interface = interface;
  515 + sz->usbdev = usbdev;
  516 + sz->interface = intf;
472 517  
473 518 /* Check to ensure endpoint information matches requirements */
474   - iface_host = interface->cur_altsetting;
  519 + iface_host = intf->cur_altsetting;
475 520  
476 521 if (iface_host->desc.bNumEndpoints != 1) {
477   - err("%s: Unexpected desc.bNumEndpoints (%d)", __func__,
478   - iface_host->desc.bNumEndpoints);
  522 + dev_err(&intf->dev, "%s: Unexpected desc.bNumEndpoints (%d)\n",
  523 + __func__, iface_host->desc.bNumEndpoints);
479 524 retval = -ENODEV;
480 525 goto free_sz;
481 526 }
482 527  
483 528  
484 529  
485 530  
486 531  
487 532  
488 533  
489 534  
490 535  
491 536  
492 537  
493 538  
494 539  
495 540  
496 541  
497 542  
498 543  
499 544  
500 545  
501 546  
502 547  
503 548  
504 549  
505 550  
506 551  
507 552  
508 553  
509 554  
510 555  
511 556  
512 557  
513 558  
514 559  
515 560  
516 561  
517 562  
518 563  
519 564  
520 565  
521 566  
522 567  
523 568  
524 569  
525 570  
526 571  
527 572  
528 573  
529 574  
530 575  
... ... @@ -483,337 +528,212 @@
483 528 sz->endpoint = &(iface_host->endpoint[0].desc);
484 529 if ((sz->endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK)
485 530 != USB_DIR_IN) {
486   - err("%s: endpoint doesn't match input device 02%02x",
487   - __func__, sz->endpoint->bEndpointAddress);
  531 + dev_err(&intf->dev, "%s: endpoint doesn't match input device "
  532 + "02%02x\n", __func__, sz->endpoint->bEndpointAddress);
488 533 retval = -ENODEV;
489 534 goto free_sz;
490 535 }
491 536  
492 537 if ((sz->endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
493 538 != USB_ENDPOINT_XFER_INT) {
494   - err("%s: endpoint attributes don't match xfer 02%02x",
495   - __func__, sz->endpoint->bmAttributes);
  539 + dev_err(&intf->dev, "%s: endpoint attributes don't match xfer "
  540 + "02%02x\n", __func__, sz->endpoint->bmAttributes);
496 541 retval = -ENODEV;
497 542 goto free_sz;
498 543 }
499 544  
500   - if (sz->endpoint->wMaxPacketSize == 0) {
501   - err("%s: endpoint message size==0? ", __func__);
  545 + pipe = usb_rcvintpipe(usbdev, sz->endpoint->bEndpointAddress);
  546 + maxp = usb_maxpacket(usbdev, pipe, usb_pipeout(pipe));
  547 +
  548 + if (maxp == 0) {
  549 + dev_err(&intf->dev, "%s: endpoint Max Packet Size is 0!?!\n",
  550 + __func__);
502 551 retval = -ENODEV;
503 552 goto free_sz;
504 553 }
505 554  
506 555 /* Allocate the USB buffer and IRQ URB */
507   -
508   - sz->buf_in_len = sz->endpoint->wMaxPacketSize;
509   - sz->buf_in = usb_alloc_coherent(sz->udev, sz->buf_in_len,
510   - GFP_ATOMIC, &sz->dma_in);
511   - if (sz->buf_in == NULL)
  556 + sz->buf_in = usb_alloc_coherent(usbdev, maxp, GFP_ATOMIC, &sz->dma_in);
  557 + if (!sz->buf_in)
512 558 goto free_sz;
513 559  
514 560 sz->urb_in = usb_alloc_urb(0, GFP_KERNEL);
515   - if (sz->urb_in == NULL)
516   - goto free_sz;
  561 + if (!sz->urb_in)
  562 + goto free_buf_in;
517 563  
518   - /* Connect this device to the LIRC sub-system */
519   - driver = kzalloc(sizeof(struct lirc_driver), GFP_KERNEL);
520   - if (!driver)
521   - goto free_sz;
  564 + sz->dev = &intf->dev;
  565 + sz->buf_in_len = maxp;
522 566  
523   - lirc_buf = kmalloc(sizeof(struct lirc_buffer), GFP_KERNEL);
524   - if (!lirc_buf)
525   - goto free_driver;
526   - if (lirc_buffer_init(lirc_buf, sizeof(int), STREAMZAP_BUF_LEN))
527   - goto kfree_lirc_buf;
  567 + if (usbdev->descriptor.iManufacturer
  568 + && usb_string(usbdev, usbdev->descriptor.iManufacturer,
  569 + buf, sizeof(buf)) > 0)
  570 + strlcpy(name, buf, sizeof(name));
528 571  
529   - delay_buf = kmalloc(sizeof(struct lirc_buffer), GFP_KERNEL);
530   - if (!delay_buf)
531   - goto free_lirc_buf;
532   - if (lirc_buffer_init(delay_buf, sizeof(int), STREAMZAP_BUF_LEN))
533   - goto kfree_delay_buf;
  572 + if (usbdev->descriptor.iProduct
  573 + && usb_string(usbdev, usbdev->descriptor.iProduct,
  574 + buf, sizeof(buf)) > 0)
  575 + snprintf(name + strlen(name), sizeof(name) - strlen(name),
  576 + " %s", buf);
534 577  
535   - sz->driver = driver;
536   - strcpy(sz->driver->name, DRIVER_NAME);
537   - sz->driver->minor = -1;
538   - sz->driver->sample_rate = 0;
539   - sz->driver->code_length = sizeof(int) * 8;
540   - sz->driver->features = LIRC_CAN_REC_MODE2 |
541   - LIRC_CAN_GET_REC_RESOLUTION |
542   - LIRC_CAN_SET_REC_TIMEOUT;
543   - sz->driver->data = sz;
544   - sz->driver->min_timeout = STREAMZAP_TIMEOUT * STREAMZAP_RESOLUTION;
545   - sz->driver->max_timeout = STREAMZAP_TIMEOUT * STREAMZAP_RESOLUTION;
546   - sz->driver->rbuf = lirc_buf;
547   - sz->delay_buf = delay_buf;
548   - sz->driver->set_use_inc = &streamzap_use_inc;
549   - sz->driver->set_use_dec = &streamzap_use_dec;
550   - sz->driver->fops = &streamzap_fops;
551   - sz->driver->dev = &interface->dev;
552   - sz->driver->owner = THIS_MODULE;
  578 + retval = streamzap_delay_buf_init(sz);
  579 + if (retval) {
  580 + dev_err(&intf->dev, "%s: delay buffer init failed\n", __func__);
  581 + goto free_urb_in;
  582 + }
553 583  
554   - sz->idle = 1;
  584 + sz->idev = streamzap_init_input_dev(sz);
  585 + if (!sz->idev)
  586 + goto input_dev_fail;
  587 +
  588 + sz->idle = true;
555 589 sz->decoder_state = PulseSpace;
  590 + #if 0
  591 + /* not yet supported, depends on patches from maxim */
  592 + /* see also: LIRC_GET_REC_RESOLUTION and LIRC_SET_REC_TIMEOUT */
  593 + sz->timeout_enabled = false;
  594 + sz->min_timeout = STREAMZAP_TIMEOUT * STREAMZAP_RESOLUTION * 1000;
  595 + sz->max_timeout = STREAMZAP_TIMEOUT * STREAMZAP_RESOLUTION * 1000;
  596 + #endif
  597 +
556 598 init_timer(&sz->delay_timer);
557   - sz->delay_timer.function = delay_timeout;
558   - sz->delay_timer.data = (unsigned long) sz;
559   - sz->timer_running = 0;
  599 + sz->delay_timer.function = streamzap_delay_timeout;
  600 + sz->delay_timer.data = (unsigned long)sz;
560 601 spin_lock_init(&sz->timer_lock);
561 602  
562 603 init_timer(&sz->flush_timer);
563   - sz->flush_timer.function = flush_timeout;
564   - sz->flush_timer.data = (unsigned long) sz;
565   - /* Complete final initialisations */
  604 + sz->flush_timer.function = streamzap_flush_timeout;
  605 + sz->flush_timer.data = (unsigned long)sz;
566 606  
567   - usb_fill_int_urb(sz->urb_in, udev,
568   - usb_rcvintpipe(udev, sz->endpoint->bEndpointAddress),
569   - sz->buf_in, sz->buf_in_len, usb_streamzap_irq, sz,
570   - sz->endpoint->bInterval);
  607 + do_gettimeofday(&sz->signal_start);
  608 +
  609 + /* Complete final initialisations */
  610 + usb_fill_int_urb(sz->urb_in, usbdev, pipe, sz->buf_in,
  611 + maxp, (usb_complete_t)streamzap_callback,
  612 + sz, sz->endpoint->bInterval);
571 613 sz->urb_in->transfer_dma = sz->dma_in;
572 614 sz->urb_in->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
573 615  
574   - if (udev->descriptor.iManufacturer
575   - && usb_string(udev, udev->descriptor.iManufacturer,
576   - buf, sizeof(buf)) > 0)
577   - strlcpy(name, buf, sizeof(name));
  616 + usb_set_intfdata(intf, sz);
578 617  
579   - if (udev->descriptor.iProduct
580   - && usb_string(udev, udev->descriptor.iProduct,
581   - buf, sizeof(buf)) > 0)
582   - snprintf(name + strlen(name), sizeof(name) - strlen(name),
583   - " %s", buf);
  618 + streamzap_start_flush_timer(sz);
584 619  
585   - minor = lirc_register_driver(driver);
  620 + dev_info(sz->dev, "Registered %s on usb%d:%d\n", name,
  621 + usbdev->bus->busnum, usbdev->devnum);
586 622  
587   - if (minor < 0)
588   - goto free_delay_buf;
589   -
590   - sz->driver->minor = minor;
591   -
592   - usb_set_intfdata(interface, sz);
593   -
594   - printk(KERN_INFO DRIVER_NAME "[%d]: %s on usb%d:%d attached\n",
595   - sz->driver->minor, name,
596   - udev->bus->busnum, sz->udev->devnum);
597   -
598 623 return 0;
599 624  
600   -free_delay_buf:
601   - lirc_buffer_free(sz->delay_buf);
602   -kfree_delay_buf:
603   - kfree(delay_buf);
604   -free_lirc_buf:
605   - lirc_buffer_free(sz->driver->rbuf);
606   -kfree_lirc_buf:
607   - kfree(lirc_buf);
608   -free_driver:
609   - kfree(driver);
  625 +input_dev_fail:
  626 + kfifo_free(&sz->fifo);
  627 +free_urb_in:
  628 + usb_free_urb(sz->urb_in);
  629 +free_buf_in:
  630 + usb_free_coherent(usbdev, maxp, sz->buf_in, sz->dma_in);
610 631 free_sz:
611   - if (retval == -ENOMEM)
612   - err("Out of memory");
  632 + kfree(sz);
613 633  
614   - if (sz) {
615   - usb_free_urb(sz->urb_in);
616   - usb_free_coherent(udev, sz->buf_in_len, sz->buf_in, sz->dma_in);
617   - kfree(sz);
618   - }
619   -
620 634 return retval;
621 635 }
622 636  
623   -static int streamzap_use_inc(void *data)
624   -{
625   - struct usb_streamzap *sz = data;
626   -
627   - if (!sz) {
628   - dprintk("%s called with no context", -1, __func__);
629   - return -EINVAL;
630   - }
631   - dprintk("set use inc", sz->driver->minor);
632   -
633   - lirc_buffer_clear(sz->driver->rbuf);
634   - lirc_buffer_clear(sz->delay_buf);
635   -
636   - sz->flush_timer.expires = jiffies + HZ;
637   - sz->flush = 1;
638   - add_timer(&sz->flush_timer);
639   -
640   - sz->urb_in->dev = sz->udev;
641   - if (usb_submit_urb(sz->urb_in, GFP_ATOMIC)) {
642   - dprintk("open result = -EIO error submitting urb",
643   - sz->driver->minor);
644   - return -EIO;
645   - }
646   - sz->in_use++;
647   -
648   - return 0;
649   -}
650   -
651   -static void streamzap_use_dec(void *data)
652   -{
653   - struct usb_streamzap *sz = data;
654   -
655   - if (!sz) {
656   - dprintk("%s called with no context", -1, __func__);
657   - return;
658   - }
659   - dprintk("set use dec", sz->driver->minor);
660   -
661   - if (sz->flush) {
662   - sz->flush = 0;
663   - del_timer_sync(&sz->flush_timer);
664   - }
665   -
666   - usb_kill_urb(sz->urb_in);
667   -
668   - stop_timer(sz);
669   -
670   - sz->in_use--;
671   -}
672   -
673   -static long streamzap_ioctl(struct file *filep, unsigned int cmd,
674   - unsigned long arg)
675   -{
676   - int result = 0;
677   - int val;
678   - struct usb_streamzap *sz = lirc_get_pdata(filep);
679   -
680   - switch (cmd) {
681   - case LIRC_GET_REC_RESOLUTION:
682   - result = put_user(STREAMZAP_RESOLUTION, (unsigned int *) arg);
683   - break;
684   - case LIRC_SET_REC_TIMEOUT:
685   - result = get_user(val, (int *)arg);
686   - if (result == 0) {
687   - if (val == STREAMZAP_TIMEOUT * STREAMZAP_RESOLUTION)
688   - sz->timeout_enabled = 1;
689   - else if (val == 0)
690   - sz->timeout_enabled = 0;
691   - else
692   - result = -EINVAL;
693   - }
694   - break;
695   - default:
696   - return lirc_dev_fop_ioctl(filep, cmd, arg);
697   - }
698   - return result;
699   -}
700   -
701 637 /**
702 638 * streamzap_disconnect
703 639 *
704 640 * Called by the usb core when the device is removed from the system.
705 641 *
706 642 * This routine guarantees that the driver will not submit any more urbs
707   - * by clearing dev->udev. It is also supposed to terminate any currently
  643 + * by clearing dev->usbdev. It is also supposed to terminate any currently
708 644 * active urbs. Unfortunately, usb_bulk_msg(), used in streamzap_read(),
709 645 * does not provide any way to do this.
710 646 */
711 647 static void streamzap_disconnect(struct usb_interface *interface)
712 648 {
713   - struct usb_streamzap *sz;
714   - int errnum;
715   - int minor;
  649 + struct streamzap_ir *sz = usb_get_intfdata(interface);
  650 + struct usb_device *usbdev = interface_to_usbdev(interface);
716 651  
717   - sz = usb_get_intfdata(interface);
  652 + usb_set_intfdata(interface, NULL);
718 653  
719   - /* unregister from the LIRC sub-system */
  654 + if (!sz)
  655 + return;
720 656  
721   - errnum = lirc_unregister_driver(sz->driver->minor);
722   - if (errnum != 0)
723   - dprintk("error in lirc_unregister: (returned %d)",
724   - sz->driver->minor, errnum);
  657 + if (sz->flush) {
  658 + sz->flush = false;
  659 + del_timer_sync(&sz->flush_timer);
  660 + }
725 661  
726   - lirc_buffer_free(sz->delay_buf);
727   - lirc_buffer_free(sz->driver->rbuf);
  662 + streamzap_stop_timer(sz);
728 663  
729   - /* unregister from the USB sub-system */
730   -
  664 + sz->usbdev = NULL;
  665 + ir_input_unregister(sz->idev);
  666 + usb_kill_urb(sz->urb_in);
731 667 usb_free_urb(sz->urb_in);
  668 + usb_free_coherent(usbdev, sz->buf_in_len, sz->buf_in, sz->dma_in);
732 669  
733   - usb_free_coherent(sz->udev, sz->buf_in_len, sz->buf_in, sz->dma_in);
734   -
735   - minor = sz->driver->minor;
736   - kfree(sz->driver->rbuf);
737   - kfree(sz->driver);
738   - kfree(sz->delay_buf);
739 670 kfree(sz);
740   -
741   - printk(KERN_INFO DRIVER_NAME "[%d]: disconnected\n", minor);
742 671 }
743 672  
744 673 static int streamzap_suspend(struct usb_interface *intf, pm_message_t message)
745 674 {
746   - struct usb_streamzap *sz = usb_get_intfdata(intf);
  675 + struct streamzap_ir *sz = usb_get_intfdata(intf);
747 676  
748   - printk(KERN_INFO DRIVER_NAME "[%d]: suspend\n", sz->driver->minor);
749   - if (sz->in_use) {
750   - if (sz->flush) {
751   - sz->flush = 0;
752   - del_timer_sync(&sz->flush_timer);
753   - }
  677 + if (sz->flush) {
  678 + sz->flush = false;
  679 + del_timer_sync(&sz->flush_timer);
  680 + }
754 681  
755   - stop_timer(sz);
  682 + streamzap_stop_timer(sz);
756 683  
757   - usb_kill_urb(sz->urb_in);
758   - }
  684 + usb_kill_urb(sz->urb_in);
  685 +
759 686 return 0;
760 687 }
761 688  
762 689 static int streamzap_resume(struct usb_interface *intf)
763 690 {
764   - struct usb_streamzap *sz = usb_get_intfdata(intf);
  691 + struct streamzap_ir *sz = usb_get_intfdata(intf);
765 692  
766   - lirc_buffer_clear(sz->driver->rbuf);
767   - lirc_buffer_clear(sz->delay_buf);
  693 + if (sz->fifo_initialized)
  694 + kfifo_reset(&sz->fifo);
768 695  
769   - if (sz->in_use) {
770   - sz->flush_timer.expires = jiffies + HZ;
771   - sz->flush = 1;
772   - add_timer(&sz->flush_timer);
  696 + sz->flush_timer.expires = jiffies + HZ;
  697 + sz->flush = true;
  698 + add_timer(&sz->flush_timer);
773 699  
774   - sz->urb_in->dev = sz->udev;
775   - if (usb_submit_urb(sz->urb_in, GFP_ATOMIC)) {
776   - dprintk("open result = -EIO error submitting urb",
777   - sz->driver->minor);
778   - return -EIO;
779   - }
  700 + if (usb_submit_urb(sz->urb_in, GFP_ATOMIC)) {
  701 + dev_err(sz->dev, "Error sumbiting urb\n");
  702 + return -EIO;
780 703 }
  704 +
781 705 return 0;
782 706 }
783 707  
784 708 /**
785   - * usb_streamzap_init
  709 + * streamzap_init
786 710 */
787   -static int __init usb_streamzap_init(void)
  711 +static int __init streamzap_init(void)
788 712 {
789   - int result;
  713 + int ret;
790 714  
791 715 /* register this driver with the USB subsystem */
792   - result = usb_register(&streamzap_driver);
  716 + ret = usb_register(&streamzap_driver);
  717 + if (ret < 0)
  718 + printk(KERN_ERR DRIVER_NAME ": usb register failed, "
  719 + "result = %d\n", ret);
793 720  
794   - if (result) {
795   - err("usb_register failed. Error number %d",
796   - result);
797   - return result;
798   - }
799   -
800   - printk(KERN_INFO DRIVER_NAME " " DRIVER_VERSION " registered\n");
801   - return 0;
  721 + return ret;
802 722 }
803 723  
804 724 /**
805   - * usb_streamzap_exit
  725 + * streamzap_exit
806 726 */
807   -static void __exit usb_streamzap_exit(void)
  727 +static void __exit streamzap_exit(void)
808 728 {
809 729 usb_deregister(&streamzap_driver);
810 730 }
811 731  
812 732  
813   -module_init(usb_streamzap_init);
814   -module_exit(usb_streamzap_exit);
  733 +module_init(streamzap_init);
  734 +module_exit(streamzap_exit);
815 735  
816   -MODULE_AUTHOR("Christoph Bartelmus, Greg Wickham, Adrian Dewhurst");
  736 +MODULE_AUTHOR("Jarod Wilson <jarod@wilsonet.com>");
817 737 MODULE_DESCRIPTION(DRIVER_DESC);
818 738 MODULE_LICENSE("GPL");
819 739  
include/media/rc-map.h
... ... @@ -114,6 +114,7 @@
114 114 #define RC_MAP_PURPLETV "rc-purpletv"
115 115 #define RC_MAP_PV951 "rc-pv951"
116 116 #define RC_MAP_RC5_HAUPPAUGE_NEW "rc-rc5-hauppauge-new"
  117 +#define RC_MAP_RC5_STREAMZAP "rc-rc5-streamzap"
117 118 #define RC_MAP_RC5_TV "rc-rc5-tv"
118 119 #define RC_MAP_RC6_MCE "rc-rc6-mce"
119 120 #define RC_MAP_REAL_AUDIO_220_32_KEYS "rc-real-audio-220-32-keys"