linux/drivers/staging/lirc/lirc_ttusbir.c
<<
>>
Prefs
   1/*
   2 * lirc_ttusbir.c
   3 *
   4 * lirc_ttusbir - LIRC device driver for the TechnoTrend USB IR Receiver
   5 *
   6 * Copyright (C) 2007 Stefan Macher <st_maker-lirc@yahoo.de>
   7 *
   8 * This LIRC driver provides access to the TechnoTrend USB IR Receiver.
   9 * The receiver delivers the IR signal as raw sampled true/false data in
  10 * isochronous USB packets each of size 128 byte.
  11 * Currently the driver reduces the sampling rate by factor of 8 as this
  12 * is still more than enough to decode RC-5 - others should be analyzed.
  13 * But the driver does not rely on RC-5 it should be able to decode every
  14 * IR signal that is not too fast.
  15 */
  16
  17/*
  18 *  This program is free software; you can redistribute it and/or modify
  19 *  it under the terms of the GNU General Public License as published by
  20 *  the Free Software Foundation; either version 2 of the License, or
  21 *  (at your option) any later version.
  22 *
  23 *  This program is distributed in the hope that it will be useful,
  24 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  25 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  26 *  GNU General Public License for more details.
  27 *
  28 *  You should have received a copy of the GNU General Public License
  29 *  along with this program; if not, write to the Free Software
  30 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  31 */
  32
  33#include <linux/version.h>
  34#include <linux/kernel.h>
  35#include <linux/init.h>
  36#include <linux/module.h>
  37#include <linux/errno.h>
  38#include <linux/slab.h>
  39#include <linux/usb.h>
  40
  41#include <media/lirc.h>
  42#include <media/lirc_dev.h>
  43
  44MODULE_DESCRIPTION("TechnoTrend USB IR device driver for LIRC");
  45MODULE_AUTHOR("Stefan Macher (st_maker-lirc@yahoo.de)");
  46MODULE_LICENSE("GPL");
  47
  48/* #define DEBUG */
  49#ifdef DEBUG
  50#define DPRINTK printk
  51#else
  52#define DPRINTK(_x_, a...)
  53#endif
  54
  55/* function declarations */
  56static int probe(struct usb_interface *intf, const struct usb_device_id *id);
  57static void disconnect(struct usb_interface *intf);
  58static void urb_complete(struct urb *urb);
  59static int set_use_inc(void *data);
  60static void set_use_dec(void *data);
  61
  62static int num_urbs = 2;
  63module_param(num_urbs, int, S_IRUGO);
  64MODULE_PARM_DESC(num_urbs,
  65                 "Number of URBs in queue. Try to increase to 4 in case "
  66                 "of problems (default: 2; minimum: 2)");
  67
  68/* table of devices that work with this driver */
  69static struct usb_device_id device_id_table[] = {
  70        /* TechnoTrend USB IR Receiver */
  71        { USB_DEVICE(0x0B48, 0x2003) },
  72        /* Terminating entry */
  73        { }
  74};
  75MODULE_DEVICE_TABLE(usb, device_id_table);
  76
  77/* USB driver definition */
  78static struct usb_driver usb_driver = {
  79        .name = "TTUSBIR",
  80        .id_table = &(device_id_table[0]),
  81        .probe = probe,
  82        .disconnect = disconnect,
  83};
  84
  85/* USB device definition */
  86struct ttusbir_device {
  87        struct usb_driver *usb_driver;
  88        struct usb_device *udev;
  89        struct usb_interface *interf;
  90        struct usb_class_driver class_driver;
  91        unsigned int ifnum; /* Interface number to use */
  92        unsigned int alt_setting; /* alternate setting to use */
  93        unsigned int endpoint; /* Endpoint to use */
  94        struct urb **urb; /* num_urb URB pointers*/
  95        char **buffer; /* 128 byte buffer for each URB */
  96        struct lirc_buffer rbuf; /* Buffer towards LIRC */
  97        struct lirc_driver driver;
  98        int minor;
  99        int last_pulse; /* remembers if last received byte was pulse or space */
 100        int last_num; /* remembers how many last bytes appeared */
 101        int opened;
 102};
 103
 104/*** LIRC specific functions ***/
 105static int set_use_inc(void *data)
 106{
 107        int i, retval;
 108        struct ttusbir_device *ttusbir = data;
 109
 110        DPRINTK("Sending first URBs\n");
 111        /* @TODO Do I need to check if I am already opened */
 112        ttusbir->opened = 1;
 113
 114        for (i = 0; i < num_urbs; i++) {
 115                retval = usb_submit_urb(ttusbir->urb[i], GFP_KERNEL);
 116                if (retval) {
 117                        err("%s: usb_submit_urb failed on urb %d",
 118                            __func__, i);
 119                        return retval;
 120                }
 121        }
 122        return 0;
 123}
 124
 125static void set_use_dec(void *data)
 126{
 127        struct ttusbir_device *ttusbir = data;
 128
 129        DPRINTK("Device closed\n");
 130
 131        ttusbir->opened = 0;
 132}
 133
 134/*** USB specific functions ***/
 135
 136/*
 137 * This mapping table is used to do a very simple filtering of the
 138 * input signal.
 139 * For a value with at least 4 bits set it returns 0xFF otherwise
 140 * 0x00.  For faster IR signals this can not be used. But for RC-5 we
 141 * still have about 14 samples per pulse/space, i.e. we sample with 14
 142 * times higher frequency than the signal frequency
 143 */
 144const unsigned char map_table[] = {
 145        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 146        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 147        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 148        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
 149        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 150        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
 151        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
 152        0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF,
 153        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 154        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
 155        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
 156        0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF,
 157        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
 158        0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF,
 159        0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF,
 160        0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
 161        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 162        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
 163        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
 164        0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF,
 165        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
 166        0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF,
 167        0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF,
 168        0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
 169        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
 170        0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF,
 171        0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF,
 172        0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
 173        0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF,
 174        0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
 175        0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
 176        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
 177};
 178
 179static void urb_complete(struct urb *urb)
 180{
 181        struct ttusbir_device *ttusbir;
 182        unsigned char *buf;
 183        int i;
 184        int l;
 185
 186        ttusbir = urb->context;
 187
 188        if (!ttusbir->opened)
 189                return;
 190
 191        buf = (unsigned char *)urb->transfer_buffer;
 192
 193        for (i = 0; i < 128; i++) {
 194                /* Here we do the filtering and some kind of down sampling */
 195                buf[i] = ~map_table[buf[i]];
 196                if (ttusbir->last_pulse == buf[i]) {
 197                        if (ttusbir->last_num < PULSE_MASK/63)
 198                                ttusbir->last_num++;
 199                /*
 200                 * else we are in a idle period and do not need to
 201                 * increment any longer
 202                 */
 203                } else {
 204                        l = ttusbir->last_num * 62; /* about 62 = us/byte */
 205                        if (ttusbir->last_pulse) /* pulse or space? */
 206                                l |= PULSE_BIT;
 207                        if (!lirc_buffer_full(&ttusbir->rbuf)) {
 208                                lirc_buffer_write(&ttusbir->rbuf, (void *)&l);
 209                                wake_up_interruptible(&ttusbir->rbuf.wait_poll);
 210                        }
 211                        ttusbir->last_num = 0;
 212                        ttusbir->last_pulse = buf[i];
 213                }
 214        }
 215        usb_submit_urb(urb, GFP_ATOMIC); /* keep data rolling :-) */
 216}
 217
 218/*
 219 * Called whenever the USB subsystem thinks we could be the right driver
 220 * to handle this device
 221 */
 222static int probe(struct usb_interface *intf, const struct usb_device_id *id)
 223{
 224        int alt_set, endp;
 225        int found = 0;
 226        int i, j;
 227        int struct_size;
 228        struct usb_host_interface *host_interf;
 229        struct usb_interface_descriptor *interf_desc;
 230        struct usb_host_endpoint *host_endpoint;
 231        struct ttusbir_device *ttusbir;
 232
 233        DPRINTK("Module ttusbir probe\n");
 234
 235        /* To reduce memory fragmentation we use only one allocation */
 236        struct_size =  sizeof(struct ttusbir_device) +
 237                (sizeof(struct urb *) * num_urbs) +
 238                (sizeof(char *) * num_urbs) +
 239                (num_urbs * 128);
 240        ttusbir = kzalloc(struct_size, GFP_KERNEL);
 241        if (!ttusbir)
 242                return -ENOMEM;
 243
 244        ttusbir->urb = (struct urb **)((char *)ttusbir +
 245                                      sizeof(struct ttusbir_device));
 246        ttusbir->buffer = (char **)((char *)ttusbir->urb +
 247                                   (sizeof(struct urb *) * num_urbs));
 248        for (i = 0; i < num_urbs; i++)
 249                ttusbir->buffer[i] = (char *)ttusbir->buffer +
 250                        (sizeof(char *)*num_urbs) + (i * 128);
 251
 252        ttusbir->usb_driver = &usb_driver;
 253        ttusbir->alt_setting = -1;
 254        /* @TODO check if error can be returned */
 255        ttusbir->udev = usb_get_dev(interface_to_usbdev(intf));
 256        ttusbir->interf = intf;
 257        ttusbir->last_pulse = 0x00;
 258        ttusbir->last_num = 0;
 259
 260        /*
 261         * Now look for interface setting we can handle
 262         * We are searching for the alt setting where end point
 263         * 0x82 has max packet size 16
 264         */
 265        for (alt_set = 0; alt_set < intf->num_altsetting && !found; alt_set++) {
 266                host_interf = &intf->altsetting[alt_set];
 267                interf_desc = &host_interf->desc;
 268                for (endp = 0; endp < interf_desc->bNumEndpoints; endp++) {
 269                        host_endpoint = &host_interf->endpoint[endp];
 270                        if ((host_endpoint->desc.bEndpointAddress == 0x82) &&
 271                            (host_endpoint->desc.wMaxPacketSize == 0x10)) {
 272                                ttusbir->alt_setting = alt_set;
 273                                ttusbir->endpoint = endp;
 274                                found = 1;
 275                                break;
 276                        }
 277                }
 278        }
 279        if (ttusbir->alt_setting != -1)
 280                DPRINTK("alt setting: %d\n", ttusbir->alt_setting);
 281        else {
 282                err("Could not find alternate setting\n");
 283                kfree(ttusbir);
 284                return -EINVAL;
 285        }
 286
 287        /* OK lets setup this interface setting */
 288        usb_set_interface(ttusbir->udev, 0, ttusbir->alt_setting);
 289
 290        /* Store device info in interface structure */
 291        usb_set_intfdata(intf, ttusbir);
 292
 293        /* Register as a LIRC driver */
 294        if (lirc_buffer_init(&ttusbir->rbuf, sizeof(int), 256) < 0) {
 295                err("Could not get memory for LIRC data buffer\n");
 296                usb_set_intfdata(intf, NULL);
 297                kfree(ttusbir);
 298                return -ENOMEM;
 299        }
 300        strcpy(ttusbir->driver.name, "TTUSBIR");
 301        ttusbir->driver.minor = -1;
 302        ttusbir->driver.code_length = 1;
 303        ttusbir->driver.sample_rate = 0;
 304        ttusbir->driver.data = ttusbir;
 305        ttusbir->driver.add_to_buf = NULL;
 306        ttusbir->driver.rbuf = &ttusbir->rbuf;
 307        ttusbir->driver.set_use_inc = set_use_inc;
 308        ttusbir->driver.set_use_dec = set_use_dec;
 309        ttusbir->driver.dev = &intf->dev;
 310        ttusbir->driver.owner = THIS_MODULE;
 311        ttusbir->driver.features = LIRC_CAN_REC_MODE2;
 312        ttusbir->minor = lirc_register_driver(&ttusbir->driver);
 313        if (ttusbir->minor < 0) {
 314                err("Error registering as LIRC driver\n");
 315                usb_set_intfdata(intf, NULL);
 316                lirc_buffer_free(&ttusbir->rbuf);
 317                kfree(ttusbir);
 318                return -EIO;
 319        }
 320
 321        /* Allocate and setup the URB that we will use to talk to the device */
 322        for (i = 0; i < num_urbs; i++) {
 323                ttusbir->urb[i] = usb_alloc_urb(8, GFP_KERNEL);
 324                if (!ttusbir->urb[i]) {
 325                        err("Could not allocate memory for the URB\n");
 326                        for (j = i - 1; j >= 0; j--)
 327                                kfree(ttusbir->urb[j]);
 328                        lirc_buffer_free(&ttusbir->rbuf);
 329                        lirc_unregister_driver(ttusbir->minor);
 330                        kfree(ttusbir);
 331                        usb_set_intfdata(intf, NULL);
 332                        return -ENOMEM;
 333                }
 334                ttusbir->urb[i]->dev = ttusbir->udev;
 335                ttusbir->urb[i]->context = ttusbir;
 336                ttusbir->urb[i]->pipe = usb_rcvisocpipe(ttusbir->udev,
 337                                                        ttusbir->endpoint);
 338                ttusbir->urb[i]->interval = 1;
 339                ttusbir->urb[i]->transfer_flags = URB_ISO_ASAP;
 340                ttusbir->urb[i]->transfer_buffer = &ttusbir->buffer[i][0];
 341                ttusbir->urb[i]->complete = urb_complete;
 342                ttusbir->urb[i]->number_of_packets = 8;
 343                ttusbir->urb[i]->transfer_buffer_length = 128;
 344                for (j = 0; j < 8; j++) {
 345                        ttusbir->urb[i]->iso_frame_desc[j].offset = j*16;
 346                        ttusbir->urb[i]->iso_frame_desc[j].length = 16;
 347                }
 348        }
 349        return 0;
 350}
 351
 352/**
 353 * Called when the driver is unloaded or the device is unplugged
 354 */
 355static void disconnect(struct usb_interface *intf)
 356{
 357        int i;
 358        struct ttusbir_device *ttusbir;
 359
 360        DPRINTK("Module ttusbir disconnect\n");
 361
 362        ttusbir = (struct ttusbir_device *) usb_get_intfdata(intf);
 363        usb_set_intfdata(intf, NULL);
 364        lirc_unregister_driver(ttusbir->minor);
 365        DPRINTK("unregistered\n");
 366
 367        for (i = 0; i < num_urbs; i++) {
 368                usb_kill_urb(ttusbir->urb[i]);
 369                usb_free_urb(ttusbir->urb[i]);
 370        }
 371        DPRINTK("URBs killed\n");
 372        lirc_buffer_free(&ttusbir->rbuf);
 373        kfree(ttusbir);
 374}
 375
 376static int ttusbir_init_module(void)
 377{
 378        int result;
 379
 380        DPRINTK(KERN_DEBUG "Module ttusbir init\n");
 381
 382        /* register this driver with the USB subsystem */
 383        result = usb_register(&usb_driver);
 384        if (result)
 385                err("usb_register failed. Error number %d", result);
 386        return result;
 387}
 388
 389static void ttusbir_exit_module(void)
 390{
 391        printk(KERN_DEBUG "Module ttusbir exit\n");
 392        usb_deregister(&usb_driver);
 393}
 394
 395module_init(ttusbir_init_module);
 396module_exit(ttusbir_exit_module);
 397