1/* 2 * lirc_igorplugusb - USB remote support for LIRC 3 * 4 * Supports the standard homebrew IgorPlugUSB receiver with Igor's firmware. 5 * See http://www.cesko.host.sk/IgorPlugUSB/IgorPlug-USB%20(AVR)_eng.htm 6 * 7 * The device can only record bursts of up to 36 pulses/spaces. 8 * Works fine with RC5. Longer commands lead to device buffer overrun. 9 * (Maybe a better firmware or a microcontroller with more ram can help?) 10 * 11 * Version 0.1 [beta status] 12 * 13 * Copyright (C) 2004 Jan M. Hochstein 14 * <hochstein@algo.informatik.tu-darmstadt.de> 15 * 16 * This driver was derived from: 17 * Paul Miller <pmiller9@users.sourceforge.net> 18 * "lirc_atiusb" module 19 * Vladimir Dergachev <volodya@minspring.com>'s 2002 20 * "USB ATI Remote support" (input device) 21 * Adrian Dewhurst <sailor-lk@sailorfrag.net>'s 2002 22 * "USB StreamZap remote driver" (LIRC) 23 * Artur Lipowski <alipowski@kki.net.pl>'s 2002 24 * "lirc_dev" and "lirc_gpio" LIRC modules 25 */ 26 27/* 28 * This program is free software; you can redistribute it and/or modify 29 * it under the terms of the GNU General Public License as published by 30 * the Free Software Foundation; either version 2 of the License, or 31 * (at your option) any later version. 32 * 33 * This program is distributed in the hope that it will be useful, 34 * but WITHOUT ANY WARRANTY; without even the implied warranty of 35 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 36 * GNU General Public License for more details. 37 * 38 * You should have received a copy of the GNU General Public License 39 * along with this program; if not, write to the Free Software 40 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 41 */ 42 43#include <linux/module.h> 44#include <linux/kernel.h> 45#include <linux/kmod.h> 46#include <linux/sched.h> 47#include <linux/errno.h> 48#include <linux/fs.h> 49#include <linux/usb.h> 50#include <linux/time.h> 51 52#include <media/lirc.h> 53#include <media/lirc_dev.h> 54 55 56/* module identification */ 57#define DRIVER_VERSION "0.2" 58#define DRIVER_AUTHOR \ 59 "Jan M. Hochstein <hochstein@algo.informatik.tu-darmstadt.de>" 60#define DRIVER_DESC "Igorplug USB remote driver for LIRC" 61#define DRIVER_NAME "lirc_igorplugusb" 62 63/* debugging support */ 64#ifdef CONFIG_USB_DEBUG 65static bool debug = 1; 66#else 67static bool debug; 68#endif 69 70#define dprintk(fmt, args...) \ 71 do { \ 72 if (debug) \ 73 printk(KERN_DEBUG fmt, ## args); \ 74 } while (0) 75 76/* One mode2 pulse/space has 4 bytes. */ 77#define CODE_LENGTH sizeof(int) 78 79/* Igor's firmware cannot record bursts longer than 36. */ 80#define DEVICE_BUFLEN 36 81 82/* 83 * Header at the beginning of the device's buffer: 84 * unsigned char data_length 85 * unsigned char data_start (!=0 means ring-buffer overrun) 86 * unsigned char counter (incremented by each burst) 87 */ 88#define DEVICE_HEADERLEN 3 89 90/* This is for the gap */ 91#define ADDITIONAL_LIRC_BYTES 2 92 93/* times to poll per second */ 94#define SAMPLE_RATE 100 95static int sample_rate = SAMPLE_RATE; 96 97 98/**** Igor's USB Request Codes */ 99 100#define SET_INFRABUFFER_EMPTY 1 101/** 102 * Params: none 103 * Answer: empty 104 */ 105 106#define GET_INFRACODE 2 107/** 108 * Params: 109 * wValue: offset to begin reading infra buffer 110 * 111 * Answer: infra data 112 */ 113 114#define SET_DATAPORT_DIRECTION 3 115/** 116 * Params: 117 * wValue: (byte) 1 bit for each data port pin (0=in, 1=out) 118 * 119 * Answer: empty 120 */ 121 122#define GET_DATAPORT_DIRECTION 4 123/** 124 * Params: none 125 * 126 * Answer: (byte) 1 bit for each data port pin (0=in, 1=out) 127 */ 128 129#define SET_OUT_DATAPORT 5 130/** 131 * Params: 132 * wValue: byte to write to output data port 133 * 134 * Answer: empty 135 */ 136 137#define GET_OUT_DATAPORT 6 138/** 139 * Params: none 140 * 141 * Answer: least significant 3 bits read from output data port 142 */ 143 144#define GET_IN_DATAPORT 7 145/** 146 * Params: none 147 * 148 * Answer: least significant 3 bits read from input data port 149 */ 150 151#define READ_EEPROM 8 152/** 153 * Params: 154 * wValue: offset to begin reading EEPROM 155 * 156 * Answer: EEPROM bytes 157 */ 158 159#define WRITE_EEPROM 9 160/** 161 * Params: 162 * wValue: offset to EEPROM byte 163 * wIndex: byte to write 164 * 165 * Answer: empty 166 */ 167 168#define SEND_RS232 10 169/** 170 * Params: 171 * wValue: byte to send 172 * 173 * Answer: empty 174 */ 175 176#define RECV_RS232 11 177/** 178 * Params: none 179 * 180 * Answer: byte received 181 */ 182 183#define SET_RS232_BAUD 12 184/** 185 * Params: 186 * wValue: byte to write to UART bit rate register (UBRR) 187 * 188 * Answer: empty 189 */ 190 191#define GET_RS232_BAUD 13 192/** 193 * Params: none 194 * 195 * Answer: byte read from UART bit rate register (UBRR) 196 */ 197 198 199/* data structure for each usb remote */ 200struct igorplug { 201 202 /* usb */ 203 struct usb_device *usbdev; 204 int devnum; 205 206 unsigned char *buf_in; 207 unsigned int len_in; 208 int in_space; 209 struct timeval last_time; 210 211 dma_addr_t dma_in; 212 213 /* lirc */ 214 struct lirc_driver *d; 215 216 /* handle sending (init strings) */ 217 int send_flags; 218}; 219 220static int unregister_from_lirc(struct igorplug *ir) 221{ 222 struct lirc_driver *d; 223 int devnum; 224 225 if (!ir) { 226 printk(KERN_ERR "%s: called with NULL device struct!\n", 227 __func__); 228 return -EINVAL; 229 } 230 231 devnum = ir->devnum; 232 d = ir->d; 233 234 if (!d) { 235 printk(KERN_ERR "%s: called with NULL lirc driver struct!\n", 236 __func__); 237 return -EINVAL; 238 } 239 240 dprintk(DRIVER_NAME "[%d]: calling lirc_unregister_driver\n", devnum); 241 lirc_unregister_driver(d->minor); 242 243 kfree(d); 244 ir->d = NULL; 245 kfree(ir); 246 247 return devnum; 248} 249 250static int set_use_inc(void *data) 251{ 252 struct igorplug *ir = data; 253 254 if (!ir) { 255 printk(DRIVER_NAME "[?]: set_use_inc called with no context\n"); 256 return -EIO; 257 } 258 259 dprintk(DRIVER_NAME "[%d]: set use inc\n", ir->devnum); 260 261 if (!ir->usbdev) 262 return -ENODEV; 263 264 return 0; 265} 266 267static void set_use_dec(void *data) 268{ 269 struct igorplug *ir = data; 270 271 if (!ir) { 272 printk(DRIVER_NAME "[?]: set_use_dec called with no context\n"); 273 return; 274 } 275 276 dprintk(DRIVER_NAME "[%d]: set use dec\n", ir->devnum); 277} 278 279static void send_fragment(struct igorplug *ir, struct lirc_buffer *buf, 280 int i, int max) 281{ 282 int code; 283 284 /* MODE2: pulse/space (PULSE_BIT) in 1us units */ 285 while (i < max) { 286 /* 1 Igor-tick = 85.333333 us */ 287 code = (unsigned int)ir->buf_in[i] * 85 + 288 (unsigned int)ir->buf_in[i] / 3; 289 ir->last_time.tv_usec += code; 290 if (ir->in_space) 291 code |= PULSE_BIT; 292 lirc_buffer_write(buf, (unsigned char *)&code); 293 /* 1 chunk = CODE_LENGTH bytes */ 294 ir->in_space ^= 1; 295 ++i; 296 } 297} 298 299/** 300 * Called in user context. 301 * return 0 if data was added to the buffer and 302 * -ENODATA if none was available. This should add some number of bits 303 * evenly divisible by code_length to the buffer 304 */ 305static int igorplugusb_remote_poll(void *data, struct lirc_buffer *buf) 306{ 307 int ret; 308 struct igorplug *ir = (struct igorplug *)data; 309 310 if (!ir || !ir->usbdev) /* Has the device been removed? */ 311 return -ENODEV; 312 313 memset(ir->buf_in, 0, ir->len_in); 314 315 ret = usb_control_msg(ir->usbdev, usb_rcvctrlpipe(ir->usbdev, 0), 316 GET_INFRACODE, USB_TYPE_VENDOR | USB_DIR_IN, 317 0/* offset */, /*unused*/0, 318 ir->buf_in, ir->len_in, 319 /*timeout*/HZ * USB_CTRL_GET_TIMEOUT); 320 if (ret > 0) { 321 int code, timediff; 322 struct timeval now; 323 324 /* ACK packet has 1 byte --> ignore */ 325 if (ret < DEVICE_HEADERLEN) 326 return -ENODATA; 327 328 dprintk(DRIVER_NAME ": Got %d bytes. Header: %02x %02x %02x\n", 329 ret, ir->buf_in[0], ir->buf_in[1], ir->buf_in[2]); 330 331 do_gettimeofday(&now); 332 timediff = now.tv_sec - ir->last_time.tv_sec; 333 if (timediff + 1 > PULSE_MASK / 1000000) 334 timediff = PULSE_MASK; 335 else { 336 timediff *= 1000000; 337 timediff += now.tv_usec - ir->last_time.tv_usec; 338 } 339 ir->last_time.tv_sec = now.tv_sec; 340 ir->last_time.tv_usec = now.tv_usec; 341 342 /* create leading gap */ 343 code = timediff; 344 lirc_buffer_write(buf, (unsigned char *)&code); 345 ir->in_space = 1; /* next comes a pulse */ 346 347 if (ir->buf_in[2] == 0) 348 send_fragment(ir, buf, DEVICE_HEADERLEN, ret); 349 else { 350 printk(KERN_WARNING DRIVER_NAME 351 "[%d]: Device buffer overrun.\n", ir->devnum); 352 /* HHHNNNNNNNNNNNOOOOOOOO H = header 353 <---[2]---> N = newer 354 <---------ret--------> O = older */ 355 ir->buf_in[2] %= ret - DEVICE_HEADERLEN; /* sanitize */ 356 /* keep even-ness to not desync pulse/pause */ 357 send_fragment(ir, buf, DEVICE_HEADERLEN + 358 ir->buf_in[2] - (ir->buf_in[2] & 1), ret); 359 send_fragment(ir, buf, DEVICE_HEADERLEN, 360 DEVICE_HEADERLEN + ir->buf_in[2]); 361 } 362 363 ret = usb_control_msg( 364 ir->usbdev, usb_rcvctrlpipe(ir->usbdev, 0), 365 SET_INFRABUFFER_EMPTY, USB_TYPE_VENDOR|USB_DIR_IN, 366 /*unused*/0, /*unused*/0, 367 /*dummy*/ir->buf_in, /*dummy*/ir->len_in, 368 /*timeout*/HZ * USB_CTRL_GET_TIMEOUT); 369 if (ret < 0) 370 printk(DRIVER_NAME "[%d]: SET_INFRABUFFER_EMPTY: " 371 "error %d\n", ir->devnum, ret); 372 return 0; 373 } else if (ret < 0) 374 printk(DRIVER_NAME "[%d]: GET_INFRACODE: error %d\n", 375 ir->devnum, ret); 376 377 return -ENODATA; 378} 379 380 381 382static int igorplugusb_remote_probe(struct usb_interface *intf, 383 const struct usb_device_id *id) 384{ 385 struct usb_device *dev = NULL; 386 struct usb_host_interface *idesc = NULL; 387 struct usb_endpoint_descriptor *ep; 388 struct igorplug *ir = NULL; 389 struct lirc_driver *driver = NULL; 390 int devnum, pipe, maxp; 391 int minor = 0; 392 char buf[63], name[128] = ""; 393 int mem_failure = 0; 394 int ret; 395 396 dprintk(DRIVER_NAME ": usb probe called.\n"); 397 398 dev = interface_to_usbdev(intf); 399 400 idesc = intf->cur_altsetting; 401 402 if (idesc->desc.bNumEndpoints != 1) 403 return -ENODEV; 404 405 ep = &idesc->endpoint->desc; 406 if (((ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK) 407 != USB_DIR_IN) 408 || (ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) 409 != USB_ENDPOINT_XFER_CONTROL) 410 return -ENODEV; 411 412 pipe = usb_rcvctrlpipe(dev, ep->bEndpointAddress); 413 devnum = dev->devnum; 414 maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe)); 415 416 dprintk(DRIVER_NAME "[%d]: bytes_in_key=%zu maxp=%d\n", 417 devnum, CODE_LENGTH, maxp); 418 419 mem_failure = 0; 420 ir = kzalloc(sizeof(struct igorplug), GFP_KERNEL); 421 if (!ir) { 422 mem_failure = 1; 423 goto mem_failure_switch; 424 } 425 driver = kzalloc(sizeof(struct lirc_driver), GFP_KERNEL); 426 if (!driver) { 427 mem_failure = 2; 428 goto mem_failure_switch; 429 } 430 431 ir->buf_in = usb_alloc_coherent(dev, DEVICE_BUFLEN + DEVICE_HEADERLEN, 432 GFP_ATOMIC, &ir->dma_in); 433 if (!ir->buf_in) { 434 mem_failure = 3; 435 goto mem_failure_switch; 436 } 437 438 strcpy(driver->name, DRIVER_NAME " "); 439 driver->minor = -1; 440 driver->code_length = CODE_LENGTH * 8; /* in bits */ 441 driver->features = LIRC_CAN_REC_MODE2; 442 driver->data = ir; 443 driver->chunk_size = CODE_LENGTH; 444 driver->buffer_size = DEVICE_BUFLEN + ADDITIONAL_LIRC_BYTES; 445 driver->set_use_inc = &set_use_inc; 446 driver->set_use_dec = &set_use_dec; 447 driver->sample_rate = sample_rate; /* per second */ 448 driver->add_to_buf = &igorplugusb_remote_poll; 449 driver->dev = &intf->dev; 450 driver->owner = THIS_MODULE; 451 452 minor = lirc_register_driver(driver); 453 if (minor < 0) 454 mem_failure = 9; 455 456mem_failure_switch: 457 458 switch (mem_failure) { 459 case 9: 460 usb_free_coherent(dev, DEVICE_BUFLEN + DEVICE_HEADERLEN, 461 ir->buf_in, ir->dma_in); 462 case 3: 463 kfree(driver); 464 case 2: 465 kfree(ir); 466 case 1: 467 printk(DRIVER_NAME "[%d]: out of memory (code=%d)\n", 468 devnum, mem_failure); 469 return -ENOMEM; 470 } 471 472 driver->minor = minor; 473 ir->d = driver; 474 ir->devnum = devnum; 475 ir->usbdev = dev; 476 ir->len_in = DEVICE_BUFLEN + DEVICE_HEADERLEN; 477 ir->in_space = 1; /* First mode2 event is a space. */ 478 do_gettimeofday(&ir->last_time); 479 480 if (dev->descriptor.iManufacturer 481 && usb_string(dev, dev->descriptor.iManufacturer, 482 buf, sizeof(buf)) > 0) 483 strlcpy(name, buf, sizeof(name)); 484 if (dev->descriptor.iProduct 485 && usb_string(dev, dev->descriptor.iProduct, buf, sizeof(buf)) > 0) 486 snprintf(name + strlen(name), sizeof(name) - strlen(name), 487 " %s", buf); 488 printk(DRIVER_NAME "[%d]: %s on usb%d:%d\n", devnum, name, 489 dev->bus->busnum, devnum); 490 491 /* clear device buffer */ 492 ret = usb_control_msg(ir->usbdev, usb_rcvctrlpipe(ir->usbdev, 0), 493 SET_INFRABUFFER_EMPTY, USB_TYPE_VENDOR|USB_DIR_IN, 494 /*unused*/0, /*unused*/0, 495 /*dummy*/ir->buf_in, /*dummy*/ir->len_in, 496 /*timeout*/HZ * USB_CTRL_GET_TIMEOUT); 497 if (ret < 0) 498 printk(DRIVER_NAME "[%d]: SET_INFRABUFFER_EMPTY: error %d\n", 499 devnum, ret); 500 501 usb_set_intfdata(intf, ir); 502 return 0; 503} 504 505 506static void igorplugusb_remote_disconnect(struct usb_interface *intf) 507{ 508 struct usb_device *usbdev = interface_to_usbdev(intf); 509 struct igorplug *ir = usb_get_intfdata(intf); 510 struct device *dev = &intf->dev; 511 int devnum; 512 513 usb_set_intfdata(intf, NULL); 514 515 if (!ir || !ir->d) 516 return; 517 518 ir->usbdev = NULL; 519 520 usb_free_coherent(usbdev, ir->len_in, ir->buf_in, ir->dma_in); 521 522 devnum = unregister_from_lirc(ir); 523 524 dev_info(dev, DRIVER_NAME "[%d]: %s done\n", devnum, __func__); 525} 526 527static struct usb_device_id igorplugusb_remote_id_table[] = { 528 /* Igor Plug USB (Atmel's Manufact. ID) */ 529 { USB_DEVICE(0x03eb, 0x0002) }, 530 /* Fit PC2 Infrared Adapter */ 531 { USB_DEVICE(0x03eb, 0x21fe) }, 532 533 /* Terminating entry */ 534 { } 535}; 536 537static struct usb_driver igorplugusb_remote_driver = { 538 .name = DRIVER_NAME, 539 .probe = igorplugusb_remote_probe, 540 .disconnect = igorplugusb_remote_disconnect, 541 .id_table = igorplugusb_remote_id_table 542}; 543 544module_usb_driver(igorplugusb_remote_driver); 545 546#include <linux/vermagic.h> 547MODULE_INFO(vermagic, VERMAGIC_STRING); 548 549MODULE_DESCRIPTION(DRIVER_DESC); 550MODULE_AUTHOR(DRIVER_AUTHOR); 551MODULE_LICENSE("GPL"); 552MODULE_DEVICE_TABLE(usb, igorplugusb_remote_id_table); 553 554module_param(sample_rate, int, S_IRUGO | S_IWUSR); 555MODULE_PARM_DESC(sample_rate, "Sampling rate in Hz (default: 100)"); 556 557module_param(debug, bool, S_IRUGO | S_IWUSR); 558MODULE_PARM_DESC(debug, "Debug enabled or not"); 559