Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
lirc_igorplugusb.c
Go to the documentation of this file.
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
15  *
16  * This driver was derived from:
17  * Paul Miller <[email protected]>
18  * "lirc_atiusb" module
19  * Vladimir Dergachev <[email protected]>'s 2002
20  * "USB ATI Remote support" (input device)
21  * Adrian Dewhurst <[email protected]>'s 2002
22  * "USB StreamZap remote driver" (LIRC)
23  * Artur Lipowski <[email protected]>'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 <[email protected]>"
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
65 static bool debug = 1;
66 #else
67 static 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
95 static int sample_rate = SAMPLE_RATE;
96 
97 
98 /**** Igor's USB Request Codes */
99 
100 #define SET_INFRABUFFER_EMPTY 1
101 
106 #define GET_INFRACODE 2
107 
114 #define SET_DATAPORT_DIRECTION 3
115 
122 #define GET_DATAPORT_DIRECTION 4
123 
129 #define SET_OUT_DATAPORT 5
130 
137 #define GET_OUT_DATAPORT 6
138 
144 #define GET_IN_DATAPORT 7
145 
151 #define READ_EEPROM 8
152 
159 #define WRITE_EEPROM 9
160 
168 #define SEND_RS232 10
169 
176 #define RECV_RS232 11
177 
183 #define SET_RS232_BAUD 12
184 
191 #define GET_RS232_BAUD 13
192 
199 /* data structure for each usb remote */
200 struct 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;
210 
212 
213  /* lirc */
214  struct lirc_driver *d;
215 
216  /* handle sending (init strings) */
218 };
219 
220 static 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);
242 
243  kfree(d);
244  ir->d = NULL;
245  kfree(ir);
246 
247  return devnum;
248 }
249 
250 static 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 
267 static 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 
279 static 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 
305 static 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),
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: %*ph\n",
329  ret, 3, ir->buf_in);
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 {
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),
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 
382 static 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;
407  != USB_DIR_IN)
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 
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;
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 
456 mem_failure_switch:
457 
458  switch (mem_failure) {
459  case 9:
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;
477  ir->in_space = 1; /* First mode2 event is a space. */
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),
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 
506 static 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 
527 static 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 
537 static 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 
544 module_usb_driver(igorplugusb_remote_driver);
545 
546 #include <linux/vermagic.h>
547 MODULE_INFO(vermagic, VERMAGIC_STRING);
548 
551 MODULE_LICENSE("GPL");
552 MODULE_DEVICE_TABLE(usb, igorplugusb_remote_id_table);
553 
554 module_param(sample_rate, int, S_IRUGO | S_IWUSR);
555 MODULE_PARM_DESC(sample_rate, "Sampling rate in Hz (default: 100)");
556 
558 MODULE_PARM_DESC(debug, "Debug enabled or not");