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/usb/input.h> 39 #include <media/rc-core.h> 40 41 #define DRIVER_VERSION "1.61" 42 #define DRIVER_NAME "streamzap" 43 #define DRIVER_DESC "Streamzap Remote Control driver" 44 45 #define USB_STREAMZAP_VENDOR_ID 0x0e9c 46 #define USB_STREAMZAP_PRODUCT_ID 0x0000 47 48 /* table of devices that work with this driver */ 49 static struct usb_device_id streamzap_table[] = { 50 /* Streamzap Remote Control */ 51 { USB_DEVICE(USB_STREAMZAP_VENDOR_ID, USB_STREAMZAP_PRODUCT_ID) }, 52 /* Terminating entry */ 53 { } 54 }; 55 56 MODULE_DEVICE_TABLE(usb, streamzap_table); 57 58 #define SZ_PULSE_MASK 0xf0 59 #define SZ_SPACE_MASK 0x0f 60 #define SZ_TIMEOUT 0xff 61 #define SZ_RESOLUTION 256 62 63 /* number of samples buffered */ 64 #define SZ_BUF_LEN 128 65 66 enum StreamzapDecoderState { 67 PulseSpace, 68 FullPulse, 69 FullSpace, 70 IgnorePulse 71 }; 72 73 /* structure to hold our device specific stuff */ 74 struct streamzap_ir { 75 /* ir-core */ 76 struct rc_dev *rdev; 77 78 /* core device info */ 79 struct device *dev; 80 81 /* usb */ 82 struct usb_device *usbdev; 83 struct usb_interface *interface; 84 struct usb_endpoint_descriptor *endpoint; 85 struct urb *urb_in; 86 87 /* buffer & dma */ 88 unsigned char *buf_in; 89 dma_addr_t dma_in; 90 unsigned int buf_in_len; 91 92 /* track what state we're in */ 93 enum StreamzapDecoderState decoder_state; 94 /* tracks whether we are currently receiving some signal */ 95 bool idle; 96 /* sum of signal lengths received since signal start */ 97 unsigned long sum; 98 /* start time of signal; necessary for gap tracking */ 99 struct timeval signal_last; 100 struct timeval signal_start; 101 bool timeout_enabled; 102 103 char name[128]; 104 char phys[64]; 105 }; 106 107 108 /* local function prototypes */ 109 static int streamzap_probe(struct usb_interface *interface, 110 const struct usb_device_id *id); 111 static void streamzap_disconnect(struct usb_interface *interface); 112 static void streamzap_callback(struct urb *urb); 113 static int streamzap_suspend(struct usb_interface *intf, pm_message_t message); 114 static int streamzap_resume(struct usb_interface *intf); 115 116 /* usb specific object needed to register this driver with the usb subsystem */ 117 static struct usb_driver streamzap_driver = { 118 .name = DRIVER_NAME, 119 .probe = streamzap_probe, 120 .disconnect = streamzap_disconnect, 121 .suspend = streamzap_suspend, 122 .resume = streamzap_resume, 123 .id_table = streamzap_table, 124 }; 125 126 static void sz_push(struct streamzap_ir *sz, struct ir_raw_event rawir) 127 { 128 dev_dbg(sz->dev, "Storing %s with duration %u us\n", 129 (rawir.pulse ? "pulse" : "space"), rawir.duration); 130 ir_raw_event_store_with_filter(sz->rdev, &rawir); 131 } 132 133 static void sz_push_full_pulse(struct streamzap_ir *sz, 134 unsigned char value) 135 { 136 DEFINE_IR_RAW_EVENT(rawir); 137 138 if (sz->idle) { 139 long deltv; 140 141 sz->signal_last = sz->signal_start; 142 do_gettimeofday(&sz->signal_start); 143 144 deltv = sz->signal_start.tv_sec - sz->signal_last.tv_sec; 145 rawir.pulse = false; 146 if (deltv > 15) { 147 /* really long time */ 148 rawir.duration = IR_MAX_DURATION; 149 } else { 150 rawir.duration = (int)(deltv * 1000000 + 151 sz->signal_start.tv_usec - 152 sz->signal_last.tv_usec); 153 rawir.duration -= sz->sum; 154 rawir.duration = US_TO_NS(rawir.duration); 155 rawir.duration = (rawir.duration > IR_MAX_DURATION) ? 156 IR_MAX_DURATION : rawir.duration; 157 } 158 sz_push(sz, rawir); 159 160 sz->idle = false; 161 sz->sum = 0; 162 } 163 164 rawir.pulse = true; 165 rawir.duration = ((int) value) * SZ_RESOLUTION; 166 rawir.duration += SZ_RESOLUTION / 2; 167 sz->sum += rawir.duration; 168 rawir.duration = US_TO_NS(rawir.duration); 169 rawir.duration = (rawir.duration > IR_MAX_DURATION) ? 170 IR_MAX_DURATION : rawir.duration; 171 sz_push(sz, rawir); 172 } 173 174 static void sz_push_half_pulse(struct streamzap_ir *sz, 175 unsigned char value) 176 { 177 sz_push_full_pulse(sz, (value & SZ_PULSE_MASK) >> 4); 178 } 179 180 static void sz_push_full_space(struct streamzap_ir *sz, 181 unsigned char value) 182 { 183 DEFINE_IR_RAW_EVENT(rawir); 184 185 rawir.pulse = false; 186 rawir.duration = ((int) value) * SZ_RESOLUTION; 187 rawir.duration += SZ_RESOLUTION / 2; 188 sz->sum += rawir.duration; 189 rawir.duration = US_TO_NS(rawir.duration); 190 sz_push(sz, rawir); 191 } 192 193 static void sz_push_half_space(struct streamzap_ir *sz, 194 unsigned long value) 195 { 196 sz_push_full_space(sz, value & SZ_SPACE_MASK); 197 } 198 199 /** 200 * streamzap_callback - usb IRQ handler callback 201 * 202 * This procedure is invoked on reception of data from 203 * the usb remote. 204 */ 205 static void streamzap_callback(struct urb *urb) 206 { 207 struct streamzap_ir *sz; 208 unsigned int i; 209 int len; 210 211 if (!urb) 212 return; 213 214 sz = urb->context; 215 len = urb->actual_length; 216 217 switch (urb->status) { 218 case -ECONNRESET: 219 case -ENOENT: 220 case -ESHUTDOWN: 221 /* 222 * this urb is terminated, clean up. 223 * sz might already be invalid at this point 224 */ 225 dev_err(sz->dev, "urb terminated, status: %d\n", urb->status); 226 return; 227 default: 228 break; 229 } 230 231 dev_dbg(sz->dev, "%s: received urb, len %d\n", __func__, len); 232 for (i = 0; i < len; i++) { 233 dev_dbg(sz->dev, "sz->buf_in[%d]: %x\n", 234 i, (unsigned char)sz->buf_in[i]); 235 switch (sz->decoder_state) { 236 case PulseSpace: 237 if ((sz->buf_in[i] & SZ_PULSE_MASK) == 238 SZ_PULSE_MASK) { 239 sz->decoder_state = FullPulse; 240 continue; 241 } else if ((sz->buf_in[i] & SZ_SPACE_MASK) 242 == SZ_SPACE_MASK) { 243 sz_push_half_pulse(sz, sz->buf_in[i]); 244 sz->decoder_state = FullSpace; 245 continue; 246 } else { 247 sz_push_half_pulse(sz, sz->buf_in[i]); 248 sz_push_half_space(sz, sz->buf_in[i]); 249 } 250 break; 251 case FullPulse: 252 sz_push_full_pulse(sz, sz->buf_in[i]); 253 sz->decoder_state = IgnorePulse; 254 break; 255 case FullSpace: 256 if (sz->buf_in[i] == SZ_TIMEOUT) { 257 DEFINE_IR_RAW_EVENT(rawir); 258 259 rawir.pulse = false; 260 rawir.duration = sz->rdev->timeout; 261 sz->idle = true; 262 if (sz->timeout_enabled) 263 sz_push(sz, rawir); 264 ir_raw_event_handle(sz->rdev); 265 ir_raw_event_reset(sz->rdev); 266 } else { 267 sz_push_full_space(sz, sz->buf_in[i]); 268 } 269 sz->decoder_state = PulseSpace; 270 break; 271 case IgnorePulse: 272 if ((sz->buf_in[i] & SZ_SPACE_MASK) == 273 SZ_SPACE_MASK) { 274 sz->decoder_state = FullSpace; 275 continue; 276 } 277 sz_push_half_space(sz, sz->buf_in[i]); 278 sz->decoder_state = PulseSpace; 279 break; 280 } 281 } 282 283 ir_raw_event_handle(sz->rdev); 284 usb_submit_urb(urb, GFP_ATOMIC); 285 286 return; 287 } 288 289 static struct rc_dev *streamzap_init_rc_dev(struct streamzap_ir *sz) 290 { 291 struct rc_dev *rdev; 292 struct device *dev = sz->dev; 293 int ret; 294 295 rdev = rc_allocate_device(); 296 if (!rdev) { 297 dev_err(dev, "remote dev allocation failed\n"); 298 goto out; 299 } 300 301 snprintf(sz->name, sizeof(sz->name), "Streamzap PC Remote Infrared " 302 "Receiver (%04x:%04x)", 303 le16_to_cpu(sz->usbdev->descriptor.idVendor), 304 le16_to_cpu(sz->usbdev->descriptor.idProduct)); 305 usb_make_path(sz->usbdev, sz->phys, sizeof(sz->phys)); 306 strlcat(sz->phys, "/input0", sizeof(sz->phys)); 307 308 rdev->input_name = sz->name; 309 rdev->input_phys = sz->phys; 310 usb_to_input_id(sz->usbdev, &rdev->input_id); 311 rdev->dev.parent = dev; 312 rdev->priv = sz; 313 rdev->driver_type = RC_DRIVER_IR_RAW; 314 rdev->allowed_protocols = RC_BIT_ALL; 315 rdev->driver_name = DRIVER_NAME; 316 rdev->map_name = RC_MAP_STREAMZAP; 317 318 ret = rc_register_device(rdev); 319 if (ret < 0) { 320 dev_err(dev, "remote input device register failed\n"); 321 goto out; 322 } 323 324 return rdev; 325 326 out: 327 rc_free_device(rdev); 328 return NULL; 329 } 330 331 /** 332 * streamzap_probe 333 * 334 * Called by usb-core to associated with a candidate device 335 * On any failure the return value is the ERROR 336 * On success return 0 337 */ 338 static int streamzap_probe(struct usb_interface *intf, 339 const struct usb_device_id *id) 340 { 341 struct usb_device *usbdev = interface_to_usbdev(intf); 342 struct usb_host_interface *iface_host; 343 struct streamzap_ir *sz = NULL; 344 char buf[63], name[128] = ""; 345 int retval = -ENOMEM; 346 int pipe, maxp; 347 348 /* Allocate space for device driver specific data */ 349 sz = kzalloc(sizeof(struct streamzap_ir), GFP_KERNEL); 350 if (!sz) 351 return -ENOMEM; 352 353 sz->usbdev = usbdev; 354 sz->interface = intf; 355 356 /* Check to ensure endpoint information matches requirements */ 357 iface_host = intf->cur_altsetting; 358 359 if (iface_host->desc.bNumEndpoints != 1) { 360 dev_err(&intf->dev, "%s: Unexpected desc.bNumEndpoints (%d)\n", 361 __func__, iface_host->desc.bNumEndpoints); 362 retval = -ENODEV; 363 goto free_sz; 364 } 365 366 sz->endpoint = &(iface_host->endpoint[0].desc); 367 if (!usb_endpoint_dir_in(sz->endpoint)) { 368 dev_err(&intf->dev, "%s: endpoint doesn't match input device " 369 "02%02x\n", __func__, sz->endpoint->bEndpointAddress); 370 retval = -ENODEV; 371 goto free_sz; 372 } 373 374 if (!usb_endpoint_xfer_int(sz->endpoint)) { 375 dev_err(&intf->dev, "%s: endpoint attributes don't match xfer " 376 "02%02x\n", __func__, sz->endpoint->bmAttributes); 377 retval = -ENODEV; 378 goto free_sz; 379 } 380 381 pipe = usb_rcvintpipe(usbdev, sz->endpoint->bEndpointAddress); 382 maxp = usb_maxpacket(usbdev, pipe, usb_pipeout(pipe)); 383 384 if (maxp == 0) { 385 dev_err(&intf->dev, "%s: endpoint Max Packet Size is 0!?!\n", 386 __func__); 387 retval = -ENODEV; 388 goto free_sz; 389 } 390 391 /* Allocate the USB buffer and IRQ URB */ 392 sz->buf_in = usb_alloc_coherent(usbdev, maxp, GFP_ATOMIC, &sz->dma_in); 393 if (!sz->buf_in) 394 goto free_sz; 395 396 sz->urb_in = usb_alloc_urb(0, GFP_KERNEL); 397 if (!sz->urb_in) 398 goto free_buf_in; 399 400 sz->dev = &intf->dev; 401 sz->buf_in_len = maxp; 402 403 if (usbdev->descriptor.iManufacturer 404 && usb_string(usbdev, usbdev->descriptor.iManufacturer, 405 buf, sizeof(buf)) > 0) 406 strlcpy(name, buf, sizeof(name)); 407 408 if (usbdev->descriptor.iProduct 409 && usb_string(usbdev, usbdev->descriptor.iProduct, 410 buf, sizeof(buf)) > 0) 411 snprintf(name + strlen(name), sizeof(name) - strlen(name), 412 " %s", buf); 413 414 sz->rdev = streamzap_init_rc_dev(sz); 415 if (!sz->rdev) 416 goto rc_dev_fail; 417 418 sz->idle = true; 419 sz->decoder_state = PulseSpace; 420 /* FIXME: don't yet have a way to set this */ 421 sz->timeout_enabled = true; 422 sz->rdev->timeout = ((US_TO_NS(SZ_TIMEOUT * SZ_RESOLUTION) & 423 IR_MAX_DURATION) | 0x03000000); 424 #if 0 425 /* not yet supported, depends on patches from maxim */ 426 /* see also: LIRC_GET_REC_RESOLUTION and LIRC_SET_REC_TIMEOUT */ 427 sz->min_timeout = US_TO_NS(SZ_TIMEOUT * SZ_RESOLUTION); 428 sz->max_timeout = US_TO_NS(SZ_TIMEOUT * SZ_RESOLUTION); 429 #endif 430 431 do_gettimeofday(&sz->signal_start); 432 433 /* Complete final initialisations */ 434 usb_fill_int_urb(sz->urb_in, usbdev, pipe, sz->buf_in, 435 maxp, (usb_complete_t)streamzap_callback, 436 sz, sz->endpoint->bInterval); 437 sz->urb_in->transfer_dma = sz->dma_in; 438 sz->urb_in->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; 439 440 usb_set_intfdata(intf, sz); 441 442 if (usb_submit_urb(sz->urb_in, GFP_ATOMIC)) 443 dev_err(sz->dev, "urb submit failed\n"); 444 445 dev_info(sz->dev, "Registered %s on usb%d:%d\n", name, 446 usbdev->bus->busnum, usbdev->devnum); 447 448 return 0; 449 450 rc_dev_fail: 451 usb_free_urb(sz->urb_in); 452 free_buf_in: 453 usb_free_coherent(usbdev, maxp, sz->buf_in, sz->dma_in); 454 free_sz: 455 kfree(sz); 456 457 return retval; 458 } 459 460 /** 461 * streamzap_disconnect 462 * 463 * Called by the usb core when the device is removed from the system. 464 * 465 * This routine guarantees that the driver will not submit any more urbs 466 * by clearing dev->usbdev. It is also supposed to terminate any currently 467 * active urbs. Unfortunately, usb_bulk_msg(), used in streamzap_read(), 468 * does not provide any way to do this. 469 */ 470 static void streamzap_disconnect(struct usb_interface *interface) 471 { 472 struct streamzap_ir *sz = usb_get_intfdata(interface); 473 struct usb_device *usbdev = interface_to_usbdev(interface); 474 475 usb_set_intfdata(interface, NULL); 476 477 if (!sz) 478 return; 479 480 sz->usbdev = NULL; 481 rc_unregister_device(sz->rdev); 482 usb_kill_urb(sz->urb_in); 483 usb_free_urb(sz->urb_in); 484 usb_free_coherent(usbdev, sz->buf_in_len, sz->buf_in, sz->dma_in); 485 486 kfree(sz); 487 } 488 489 static int streamzap_suspend(struct usb_interface *intf, pm_message_t message) 490 { 491 struct streamzap_ir *sz = usb_get_intfdata(intf); 492 493 usb_kill_urb(sz->urb_in); 494 495 return 0; 496 } 497 498 static int streamzap_resume(struct usb_interface *intf) 499 { 500 struct streamzap_ir *sz = usb_get_intfdata(intf); 501 502 if (usb_submit_urb(sz->urb_in, GFP_ATOMIC)) { 503 dev_err(sz->dev, "Error sumbiting urb\n"); 504 return -EIO; 505 } 506 507 return 0; 508 } 509 510 module_usb_driver(streamzap_driver); 511 512 MODULE_AUTHOR("Jarod Wilson <jarod@wilsonet.com>"); 513 MODULE_DESCRIPTION(DRIVER_DESC); 514 MODULE_LICENSE("GPL"); 515