]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blob - drivers/media/IR/streamzap.c
623ee2dc198e9a5934434c51cfadcde4bf205a09
[mirror_ubuntu-artful-kernel.git] / drivers / media / IR / streamzap.c
1 /*
2 * Streamzap Remote Control driver
3 *
4 * Copyright (c) 2005 Christoph Bartelmus <lirc@bartelmus.de>
5 * Copyright (c) 2010 Jarod Wilson <jarod@wilsonet.com>
6 *
7 * This driver was based on the work of Greg Wickham and Adrian
8 * Dewhurst. It was substantially rewritten to support correct signal
9 * gaps and now maintains a delay buffer, which is used to present
10 * consistent timing behaviour to user space applications. Without the
11 * delay buffer an ugly hack would be required in lircd, which can
12 * cause sluggish signal decoding in certain situations.
13 *
14 * Ported to in-kernel ir-core interface by Jarod Wilson
15 *
16 * This driver is based on the USB skeleton driver packaged with the
17 * kernel; copyright (C) 2001-2003 Greg Kroah-Hartman (greg@kroah.com)
18 *
19 * This program is free software; you can redistribute it and/or modify
20 * it under the terms of the GNU General Public License as published by
21 * the Free Software Foundation; either version 2 of the License, or
22 * (at your option) any later version.
23 *
24 * This program is distributed in the hope that it will be useful,
25 * but WITHOUT ANY WARRANTY; without even the implied warranty of
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27 * GNU General Public License for more details.
28 *
29 * You should have received a copy of the GNU General Public License
30 * along with this program; if not, write to the Free Software
31 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
32 */
33
34 #include <linux/device.h>
35 #include <linux/module.h>
36 #include <linux/slab.h>
37 #include <linux/usb.h>
38 #include <linux/input.h>
39 #include <media/ir-core.h>
40
41 #define DRIVER_VERSION "1.61"
42 #define DRIVER_NAME "streamzap"
43 #define DRIVER_DESC "Streamzap Remote Control driver"
44
45 #ifdef CONFIG_USB_DEBUG
46 static int debug = 1;
47 #else
48 static int debug;
49 #endif
50
51 #define USB_STREAMZAP_VENDOR_ID 0x0e9c
52 #define USB_STREAMZAP_PRODUCT_ID 0x0000
53
54 /* table of devices that work with this driver */
55 static struct usb_device_id streamzap_table[] = {
56 /* Streamzap Remote Control */
57 { USB_DEVICE(USB_STREAMZAP_VENDOR_ID, USB_STREAMZAP_PRODUCT_ID) },
58 /* Terminating entry */
59 { }
60 };
61
62 MODULE_DEVICE_TABLE(usb, streamzap_table);
63
64 #define SZ_PULSE_MASK 0xf0
65 #define SZ_SPACE_MASK 0x0f
66 #define SZ_TIMEOUT 0xff
67 #define SZ_RESOLUTION 256
68
69 /* number of samples buffered */
70 #define SZ_BUF_LEN 128
71
72 /* from ir-rc5-sz-decoder.c */
73 #ifdef CONFIG_IR_RC5_SZ_DECODER_MODULE
74 #define load_rc5_sz_decode() request_module("ir-rc5-sz-decoder")
75 #else
76 #define load_rc5_sz_decode() 0
77 #endif
78
79 enum StreamzapDecoderState {
80 PulseSpace,
81 FullPulse,
82 FullSpace,
83 IgnorePulse
84 };
85
86 /* structure to hold our device specific stuff */
87 struct streamzap_ir {
88
89 /* ir-core */
90 struct ir_dev_props *props;
91
92 /* core device info */
93 struct device *dev;
94 struct input_dev *idev;
95
96 /* usb */
97 struct usb_device *usbdev;
98 struct usb_interface *interface;
99 struct usb_endpoint_descriptor *endpoint;
100 struct urb *urb_in;
101
102 /* buffer & dma */
103 unsigned char *buf_in;
104 dma_addr_t dma_in;
105 unsigned int buf_in_len;
106
107 /* track what state we're in */
108 enum StreamzapDecoderState decoder_state;
109 /* tracks whether we are currently receiving some signal */
110 bool idle;
111 /* sum of signal lengths received since signal start */
112 unsigned long sum;
113 /* start time of signal; necessary for gap tracking */
114 struct timeval signal_last;
115 struct timeval signal_start;
116 bool timeout_enabled;
117
118 char name[128];
119 char phys[64];
120 };
121
122
123 /* local function prototypes */
124 static int streamzap_probe(struct usb_interface *interface,
125 const struct usb_device_id *id);
126 static void streamzap_disconnect(struct usb_interface *interface);
127 static void streamzap_callback(struct urb *urb);
128 static int streamzap_suspend(struct usb_interface *intf, pm_message_t message);
129 static int streamzap_resume(struct usb_interface *intf);
130
131 /* usb specific object needed to register this driver with the usb subsystem */
132 static struct usb_driver streamzap_driver = {
133 .name = DRIVER_NAME,
134 .probe = streamzap_probe,
135 .disconnect = streamzap_disconnect,
136 .suspend = streamzap_suspend,
137 .resume = streamzap_resume,
138 .id_table = streamzap_table,
139 };
140
141 static void sz_push(struct streamzap_ir *sz, struct ir_raw_event rawir)
142 {
143 ir_raw_event_store(sz->idev, &rawir);
144 }
145
146 static void sz_push_full_pulse(struct streamzap_ir *sz,
147 unsigned char value)
148 {
149 struct ir_raw_event rawir;
150
151 if (sz->idle) {
152 long deltv;
153
154 sz->signal_last = sz->signal_start;
155 do_gettimeofday(&sz->signal_start);
156
157 deltv = sz->signal_start.tv_sec - sz->signal_last.tv_sec;
158 rawir.pulse = false;
159 if (deltv > 15) {
160 /* really long time */
161 rawir.duration = IR_MAX_DURATION;
162 } else {
163 rawir.duration = (int)(deltv * 1000000 +
164 sz->signal_start.tv_usec -
165 sz->signal_last.tv_usec);
166 rawir.duration -= sz->sum;
167 rawir.duration *= 1000;
168 rawir.duration &= IR_MAX_DURATION;
169 }
170 dev_dbg(sz->dev, "ls %u\n", rawir.duration);
171 sz_push(sz, rawir);
172
173 sz->idle = false;
174 sz->sum = 0;
175 }
176
177 rawir.pulse = true;
178 rawir.duration = ((int) value) * SZ_RESOLUTION;
179 rawir.duration += SZ_RESOLUTION / 2;
180 sz->sum += rawir.duration;
181 rawir.duration *= 1000;
182 rawir.duration &= IR_MAX_DURATION;
183 dev_dbg(sz->dev, "p %u\n", rawir.duration);
184 sz_push(sz, rawir);
185 }
186
187 static void sz_push_half_pulse(struct streamzap_ir *sz,
188 unsigned char value)
189 {
190 sz_push_full_pulse(sz, (value & SZ_PULSE_MASK) >> 4);
191 }
192
193 static void sz_push_full_space(struct streamzap_ir *sz,
194 unsigned char value)
195 {
196 struct ir_raw_event rawir;
197
198 rawir.pulse = false;
199 rawir.duration = ((int) value) * SZ_RESOLUTION;
200 rawir.duration += SZ_RESOLUTION / 2;
201 sz->sum += rawir.duration;
202 rawir.duration *= 1000;
203 dev_dbg(sz->dev, "s %u\n", rawir.duration);
204 sz_push(sz, rawir);
205 }
206
207 static void sz_push_half_space(struct streamzap_ir *sz,
208 unsigned long value)
209 {
210 sz_push_full_space(sz, value & SZ_SPACE_MASK);
211 }
212
213 /**
214 * streamzap_callback - usb IRQ handler callback
215 *
216 * This procedure is invoked on reception of data from
217 * the usb remote.
218 */
219 static void streamzap_callback(struct urb *urb)
220 {
221 struct streamzap_ir *sz;
222 unsigned int i;
223 int len;
224 static int timeout = (((SZ_TIMEOUT * SZ_RESOLUTION) &
225 IR_MAX_DURATION) | 0x03000000);
226
227 if (!urb)
228 return;
229
230 sz = urb->context;
231 len = urb->actual_length;
232
233 switch (urb->status) {
234 case -ECONNRESET:
235 case -ENOENT:
236 case -ESHUTDOWN:
237 /*
238 * this urb is terminated, clean up.
239 * sz might already be invalid at this point
240 */
241 dev_err(sz->dev, "urb terminated, status: %d\n", urb->status);
242 return;
243 default:
244 break;
245 }
246
247 dev_dbg(sz->dev, "%s: received urb, len %d\n", __func__, len);
248 for (i = 0; i < len; i++) {
249 dev_dbg(sz->dev, "sz idx %d: %x\n",
250 i, (unsigned char)sz->buf_in[i]);
251 switch (sz->decoder_state) {
252 case PulseSpace:
253 if ((sz->buf_in[i] & SZ_PULSE_MASK) ==
254 SZ_PULSE_MASK) {
255 sz->decoder_state = FullPulse;
256 continue;
257 } else if ((sz->buf_in[i] & SZ_SPACE_MASK)
258 == SZ_SPACE_MASK) {
259 sz_push_half_pulse(sz, sz->buf_in[i]);
260 sz->decoder_state = FullSpace;
261 continue;
262 } else {
263 sz_push_half_pulse(sz, sz->buf_in[i]);
264 sz_push_half_space(sz, sz->buf_in[i]);
265 }
266 break;
267 case FullPulse:
268 sz_push_full_pulse(sz, sz->buf_in[i]);
269 sz->decoder_state = IgnorePulse;
270 break;
271 case FullSpace:
272 if (sz->buf_in[i] == SZ_TIMEOUT) {
273 struct ir_raw_event rawir;
274
275 rawir.pulse = false;
276 rawir.duration = timeout * 1000;
277 sz->idle = true;
278 if (sz->timeout_enabled)
279 sz_push(sz, rawir);
280 ir_raw_event_handle(sz->idev);
281 } else {
282 sz_push_full_space(sz, sz->buf_in[i]);
283 }
284 sz->decoder_state = PulseSpace;
285 break;
286 case IgnorePulse:
287 if ((sz->buf_in[i] & SZ_SPACE_MASK) ==
288 SZ_SPACE_MASK) {
289 sz->decoder_state = FullSpace;
290 continue;
291 }
292 sz_push_half_space(sz, sz->buf_in[i]);
293 sz->decoder_state = PulseSpace;
294 break;
295 }
296 }
297
298 usb_submit_urb(urb, GFP_ATOMIC);
299
300 return;
301 }
302
303 static struct input_dev *streamzap_init_input_dev(struct streamzap_ir *sz)
304 {
305 struct input_dev *idev;
306 struct ir_dev_props *props;
307 struct device *dev = sz->dev;
308 int ret;
309
310 idev = input_allocate_device();
311 if (!idev) {
312 dev_err(dev, "remote input dev allocation failed\n");
313 goto idev_alloc_failed;
314 }
315
316 props = kzalloc(sizeof(struct ir_dev_props), GFP_KERNEL);
317 if (!props) {
318 dev_err(dev, "remote ir dev props allocation failed\n");
319 goto props_alloc_failed;
320 }
321
322 snprintf(sz->name, sizeof(sz->name), "Streamzap PC Remote Infrared "
323 "Receiver (%04x:%04x)",
324 le16_to_cpu(sz->usbdev->descriptor.idVendor),
325 le16_to_cpu(sz->usbdev->descriptor.idProduct));
326
327 idev->name = sz->name;
328 usb_make_path(sz->usbdev, sz->phys, sizeof(sz->phys));
329 strlcat(sz->phys, "/input0", sizeof(sz->phys));
330 idev->phys = sz->phys;
331
332 props->priv = sz;
333 props->driver_type = RC_DRIVER_IR_RAW;
334 props->allowed_protos = IR_TYPE_ALL;
335
336 sz->props = props;
337
338 ret = ir_input_register(idev, RC_MAP_STREAMZAP, props, DRIVER_NAME);
339 if (ret < 0) {
340 dev_err(dev, "remote input device register failed\n");
341 goto irdev_failed;
342 }
343
344 return idev;
345
346 irdev_failed:
347 kfree(props);
348 props_alloc_failed:
349 input_free_device(idev);
350 idev_alloc_failed:
351 return NULL;
352 }
353
354 /**
355 * streamzap_probe
356 *
357 * Called by usb-core to associated with a candidate device
358 * On any failure the return value is the ERROR
359 * On success return 0
360 */
361 static int __devinit streamzap_probe(struct usb_interface *intf,
362 const struct usb_device_id *id)
363 {
364 struct usb_device *usbdev = interface_to_usbdev(intf);
365 struct usb_host_interface *iface_host;
366 struct streamzap_ir *sz = NULL;
367 char buf[63], name[128] = "";
368 int retval = -ENOMEM;
369 int pipe, maxp;
370
371 /* Allocate space for device driver specific data */
372 sz = kzalloc(sizeof(struct streamzap_ir), GFP_KERNEL);
373 if (!sz)
374 return -ENOMEM;
375
376 sz->usbdev = usbdev;
377 sz->interface = intf;
378
379 /* Check to ensure endpoint information matches requirements */
380 iface_host = intf->cur_altsetting;
381
382 if (iface_host->desc.bNumEndpoints != 1) {
383 dev_err(&intf->dev, "%s: Unexpected desc.bNumEndpoints (%d)\n",
384 __func__, iface_host->desc.bNumEndpoints);
385 retval = -ENODEV;
386 goto free_sz;
387 }
388
389 sz->endpoint = &(iface_host->endpoint[0].desc);
390 if ((sz->endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK)
391 != USB_DIR_IN) {
392 dev_err(&intf->dev, "%s: endpoint doesn't match input device "
393 "02%02x\n", __func__, sz->endpoint->bEndpointAddress);
394 retval = -ENODEV;
395 goto free_sz;
396 }
397
398 if ((sz->endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
399 != USB_ENDPOINT_XFER_INT) {
400 dev_err(&intf->dev, "%s: endpoint attributes don't match xfer "
401 "02%02x\n", __func__, sz->endpoint->bmAttributes);
402 retval = -ENODEV;
403 goto free_sz;
404 }
405
406 pipe = usb_rcvintpipe(usbdev, sz->endpoint->bEndpointAddress);
407 maxp = usb_maxpacket(usbdev, pipe, usb_pipeout(pipe));
408
409 if (maxp == 0) {
410 dev_err(&intf->dev, "%s: endpoint Max Packet Size is 0!?!\n",
411 __func__);
412 retval = -ENODEV;
413 goto free_sz;
414 }
415
416 /* Allocate the USB buffer and IRQ URB */
417 sz->buf_in = usb_alloc_coherent(usbdev, maxp, GFP_ATOMIC, &sz->dma_in);
418 if (!sz->buf_in)
419 goto free_sz;
420
421 sz->urb_in = usb_alloc_urb(0, GFP_KERNEL);
422 if (!sz->urb_in)
423 goto free_buf_in;
424
425 sz->dev = &intf->dev;
426 sz->buf_in_len = maxp;
427
428 if (usbdev->descriptor.iManufacturer
429 && usb_string(usbdev, usbdev->descriptor.iManufacturer,
430 buf, sizeof(buf)) > 0)
431 strlcpy(name, buf, sizeof(name));
432
433 if (usbdev->descriptor.iProduct
434 && usb_string(usbdev, usbdev->descriptor.iProduct,
435 buf, sizeof(buf)) > 0)
436 snprintf(name + strlen(name), sizeof(name) - strlen(name),
437 " %s", buf);
438
439 sz->idev = streamzap_init_input_dev(sz);
440 if (!sz->idev)
441 goto input_dev_fail;
442
443 sz->idle = true;
444 sz->decoder_state = PulseSpace;
445 /* FIXME: don't yet have a way to set this */
446 sz->timeout_enabled = true;
447 #if 0
448 /* not yet supported, depends on patches from maxim */
449 /* see also: LIRC_GET_REC_RESOLUTION and LIRC_SET_REC_TIMEOUT */
450 sz->min_timeout = SZ_TIMEOUT * SZ_RESOLUTION * 1000;
451 sz->max_timeout = SZ_TIMEOUT * SZ_RESOLUTION * 1000;
452 #endif
453
454 do_gettimeofday(&sz->signal_start);
455
456 /* Complete final initialisations */
457 usb_fill_int_urb(sz->urb_in, usbdev, pipe, sz->buf_in,
458 maxp, (usb_complete_t)streamzap_callback,
459 sz, sz->endpoint->bInterval);
460 sz->urb_in->transfer_dma = sz->dma_in;
461 sz->urb_in->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
462
463 usb_set_intfdata(intf, sz);
464
465 if (usb_submit_urb(sz->urb_in, GFP_ATOMIC))
466 dev_err(sz->dev, "urb submit failed\n");
467
468 dev_info(sz->dev, "Registered %s on usb%d:%d\n", name,
469 usbdev->bus->busnum, usbdev->devnum);
470
471 /* Load the streamzap not-quite-rc5 decoder too */
472 load_rc5_sz_decode();
473
474 return 0;
475
476 input_dev_fail:
477 usb_free_urb(sz->urb_in);
478 free_buf_in:
479 usb_free_coherent(usbdev, maxp, sz->buf_in, sz->dma_in);
480 free_sz:
481 kfree(sz);
482
483 return retval;
484 }
485
486 /**
487 * streamzap_disconnect
488 *
489 * Called by the usb core when the device is removed from the system.
490 *
491 * This routine guarantees that the driver will not submit any more urbs
492 * by clearing dev->usbdev. It is also supposed to terminate any currently
493 * active urbs. Unfortunately, usb_bulk_msg(), used in streamzap_read(),
494 * does not provide any way to do this.
495 */
496 static void streamzap_disconnect(struct usb_interface *interface)
497 {
498 struct streamzap_ir *sz = usb_get_intfdata(interface);
499 struct usb_device *usbdev = interface_to_usbdev(interface);
500
501 usb_set_intfdata(interface, NULL);
502
503 if (!sz)
504 return;
505
506 sz->usbdev = NULL;
507 ir_input_unregister(sz->idev);
508 usb_kill_urb(sz->urb_in);
509 usb_free_urb(sz->urb_in);
510 usb_free_coherent(usbdev, sz->buf_in_len, sz->buf_in, sz->dma_in);
511
512 kfree(sz);
513 }
514
515 static int streamzap_suspend(struct usb_interface *intf, pm_message_t message)
516 {
517 struct streamzap_ir *sz = usb_get_intfdata(intf);
518
519 usb_kill_urb(sz->urb_in);
520
521 return 0;
522 }
523
524 static int streamzap_resume(struct usb_interface *intf)
525 {
526 struct streamzap_ir *sz = usb_get_intfdata(intf);
527
528 if (usb_submit_urb(sz->urb_in, GFP_ATOMIC)) {
529 dev_err(sz->dev, "Error sumbiting urb\n");
530 return -EIO;
531 }
532
533 return 0;
534 }
535
536 /**
537 * streamzap_init
538 */
539 static int __init streamzap_init(void)
540 {
541 int ret;
542
543 /* register this driver with the USB subsystem */
544 ret = usb_register(&streamzap_driver);
545 if (ret < 0)
546 printk(KERN_ERR DRIVER_NAME ": usb register failed, "
547 "result = %d\n", ret);
548
549 return ret;
550 }
551
552 /**
553 * streamzap_exit
554 */
555 static void __exit streamzap_exit(void)
556 {
557 usb_deregister(&streamzap_driver);
558 }
559
560
561 module_init(streamzap_init);
562 module_exit(streamzap_exit);
563
564 MODULE_AUTHOR("Jarod Wilson <jarod@wilsonet.com>");
565 MODULE_DESCRIPTION(DRIVER_DESC);
566 MODULE_LICENSE("GPL");
567
568 module_param(debug, bool, S_IRUGO | S_IWUSR);
569 MODULE_PARM_DESC(debug, "Enable debugging messages");