linux/drivers/staging/media/lirc/lirc_igorplugusb.c
<<
>>
Prefs
   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                dev_err(&ir->usbdev->dev,
 227                        "%s: called with NULL device struct!\n", __func__);
 228                return -EINVAL;
 229        }
 230
 231        devnum = ir->devnum;
 232        d = ir->d;
 233
 234        if (!d) {
 235                dev_err(&ir->usbdev->dev,
 236                        "%s: called with NULL lirc driver struct!\n", __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: %*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 {
 350                        dev_warn(&ir->usbdev->dev,
 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