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/* One mode2 pulse/space has 4 bytes. */
  64#define CODE_LENGTH          sizeof(int)
  65
  66/* Igor's firmware cannot record bursts longer than 36. */
  67#define DEVICE_BUFLEN      36
  68
  69/*
  70 * Header at the beginning of the device's buffer:
  71 *      unsigned char data_length
  72 *      unsigned char data_start    (!=0 means ring-buffer overrun)
  73 *      unsigned char counter       (incremented by each burst)
  74 */
  75#define DEVICE_HEADERLEN        3
  76
  77/* This is for the gap */
  78#define ADDITIONAL_LIRC_BYTES   2
  79
  80/* times to poll per second */
  81#define SAMPLE_RATE          100
  82static int sample_rate = SAMPLE_RATE;
  83
  84
  85/**** Igor's USB Request Codes */
  86
  87#define SET_INFRABUFFER_EMPTY   1
  88/**
  89 * Params: none
  90 * Answer: empty
  91 */
  92
  93#define GET_INFRACODE      2
  94/**
  95 * Params:
  96 *   wValue: offset to begin reading infra buffer
  97 *
  98 * Answer: infra data
  99 */
 100
 101#define SET_DATAPORT_DIRECTION  3
 102/**
 103 * Params:
 104 *   wValue: (byte) 1 bit for each data port pin (0=in, 1=out)
 105 *
 106 * Answer: empty
 107 */
 108
 109#define GET_DATAPORT_DIRECTION  4
 110/**
 111 * Params: none
 112 *
 113 * Answer: (byte) 1 bit for each data port pin (0=in, 1=out)
 114 */
 115
 116#define SET_OUT_DATAPORT        5
 117/**
 118 * Params:
 119 *   wValue: byte to write to output data port
 120 *
 121 * Answer: empty
 122 */
 123
 124#define GET_OUT_DATAPORT        6
 125/**
 126 * Params: none
 127 *
 128 * Answer: least significant 3 bits read from output data port
 129 */
 130
 131#define GET_IN_DATAPORT  7
 132/**
 133 * Params: none
 134 *
 135 * Answer: least significant 3 bits read from input data port
 136 */
 137
 138#define READ_EEPROM          8
 139/**
 140 * Params:
 141 *   wValue: offset to begin reading EEPROM
 142 *
 143 * Answer: EEPROM bytes
 144 */
 145
 146#define WRITE_EEPROM        9
 147/**
 148 * Params:
 149 *   wValue: offset to EEPROM byte
 150 *   wIndex: byte to write
 151 *
 152 * Answer: empty
 153 */
 154
 155#define SEND_RS232            10
 156/**
 157 * Params:
 158 *   wValue: byte to send
 159 *
 160 * Answer: empty
 161 */
 162
 163#define RECV_RS232            11
 164/**
 165 * Params: none
 166 *
 167 * Answer: byte received
 168 */
 169
 170#define SET_RS232_BAUD    12
 171/**
 172 * Params:
 173 *   wValue: byte to write to UART bit rate register (UBRR)
 174 *
 175 * Answer: empty
 176 */
 177
 178#define GET_RS232_BAUD    13
 179/**
 180 * Params: none
 181 *
 182 * Answer: byte read from UART bit rate register (UBRR)
 183 */
 184
 185
 186/* data structure for each usb remote */
 187struct igorplug {
 188
 189        /* usb */
 190        struct usb_device *usbdev;
 191        int devnum;
 192
 193        unsigned char *buf_in;
 194        unsigned int len_in;
 195        int in_space;
 196        struct timeval last_time;
 197
 198        dma_addr_t dma_in;
 199
 200        /* lirc */
 201        struct lirc_driver *d;
 202
 203        /* handle sending (init strings) */
 204        int send_flags;
 205};
 206
 207static int unregister_from_lirc(struct igorplug *ir)
 208{
 209        struct lirc_driver *d;
 210        int devnum;
 211
 212        if (!ir) {
 213                dev_err(&ir->usbdev->dev,
 214                        "%s: called with NULL device struct!\n", __func__);
 215                return -EINVAL;
 216        }
 217
 218        devnum = ir->devnum;
 219        d = ir->d;
 220
 221        if (!d) {
 222                dev_err(&ir->usbdev->dev,
 223                        "%s: called with NULL lirc driver struct!\n", __func__);
 224                return -EINVAL;
 225        }
 226
 227        dev_dbg(&ir->usbdev->dev, "calling lirc_unregister_driver\n");
 228        lirc_unregister_driver(d->minor);
 229
 230        return devnum;
 231}
 232
 233static int set_use_inc(void *data)
 234{
 235        struct igorplug *ir = data;
 236
 237        if (!ir) {
 238                printk(DRIVER_NAME "[?]: set_use_inc called with no context\n");
 239                return -EIO;
 240        }
 241
 242        dev_dbg(&ir->usbdev->dev, "set use inc\n");
 243
 244        if (!ir->usbdev)
 245                return -ENODEV;
 246
 247        return 0;
 248}
 249
 250static void set_use_dec(void *data)
 251{
 252        struct igorplug *ir = data;
 253
 254        if (!ir) {
 255                printk(DRIVER_NAME "[?]: set_use_dec called with no context\n");
 256                return;
 257        }
 258
 259        dev_dbg(&ir->usbdev->dev, "set use dec\n");
 260}
 261
 262static void send_fragment(struct igorplug *ir, struct lirc_buffer *buf,
 263                           int i, int max)
 264{
 265        int code;
 266
 267        /* MODE2: pulse/space (PULSE_BIT) in 1us units */
 268        while (i < max) {
 269                /* 1 Igor-tick = 85.333333 us */
 270                code = (unsigned int)ir->buf_in[i] * 85 +
 271                        (unsigned int)ir->buf_in[i] / 3;
 272                ir->last_time.tv_usec += code;
 273                if (ir->in_space)
 274                        code |= PULSE_BIT;
 275                lirc_buffer_write(buf, (unsigned char *)&code);
 276                /* 1 chunk = CODE_LENGTH bytes */
 277                ir->in_space ^= 1;
 278                ++i;
 279        }
 280}
 281
 282/**
 283 * Called in user context.
 284 * return 0 if data was added to the buffer and
 285 * -ENODATA if none was available. This should add some number of bits
 286 * evenly divisible by code_length to the buffer
 287 */
 288static int igorplugusb_remote_poll(void *data, struct lirc_buffer *buf)
 289{
 290        int ret;
 291        struct igorplug *ir = (struct igorplug *)data;
 292
 293        if (!ir || !ir->usbdev)  /* Has the device been removed? */
 294                return -ENODEV;
 295
 296        memset(ir->buf_in, 0, ir->len_in);
 297
 298        ret = usb_control_msg(ir->usbdev, usb_rcvctrlpipe(ir->usbdev, 0),
 299                              GET_INFRACODE, USB_TYPE_VENDOR | USB_DIR_IN,
 300                              0/* offset */, /*unused*/0,
 301                              ir->buf_in, ir->len_in,
 302                              /*timeout*/HZ * USB_CTRL_GET_TIMEOUT);
 303        if (ret > 0) {
 304                int code, timediff;
 305                struct timeval now;
 306
 307                /* ACK packet has 1 byte --> ignore */
 308                if (ret < DEVICE_HEADERLEN)
 309                        return -ENODATA;
 310
 311                dev_dbg(&ir->usbdev->dev, "Got %d bytes. Header: %*ph\n",
 312                        ret, 3, ir->buf_in);
 313
 314                do_gettimeofday(&now);
 315                timediff = now.tv_sec - ir->last_time.tv_sec;
 316                if (timediff + 1 > PULSE_MASK / 1000000)
 317                        timediff = PULSE_MASK;
 318                else {
 319                        timediff *= 1000000;
 320                        timediff += now.tv_usec - ir->last_time.tv_usec;
 321                }
 322                ir->last_time.tv_sec = now.tv_sec;
 323                ir->last_time.tv_usec = now.tv_usec;
 324
 325                /* create leading gap  */
 326                code = timediff;
 327                lirc_buffer_write(buf, (unsigned char *)&code);
 328                ir->in_space = 1;   /* next comes a pulse */
 329
 330                if (ir->buf_in[2] == 0)
 331                        send_fragment(ir, buf, DEVICE_HEADERLEN, ret);
 332                else {
 333                        dev_warn(&ir->usbdev->dev,
 334                                 "[%d]: Device buffer overrun.\n", ir->devnum);
 335                        /* HHHNNNNNNNNNNNOOOOOOOO H = header
 336                              <---[2]--->         N = newer
 337                           <---------ret--------> O = older */
 338                        ir->buf_in[2] %= ret - DEVICE_HEADERLEN; /* sanitize */
 339                        /* keep even-ness to not desync pulse/pause */
 340                        send_fragment(ir, buf, DEVICE_HEADERLEN +
 341                                      ir->buf_in[2] - (ir->buf_in[2] & 1), ret);
 342                        send_fragment(ir, buf, DEVICE_HEADERLEN,
 343                                      DEVICE_HEADERLEN + ir->buf_in[2]);
 344                }
 345
 346                ret = usb_control_msg(
 347                      ir->usbdev, usb_rcvctrlpipe(ir->usbdev, 0),
 348                      SET_INFRABUFFER_EMPTY, USB_TYPE_VENDOR|USB_DIR_IN,
 349                      /*unused*/0, /*unused*/0,
 350                      /*dummy*/ir->buf_in, /*dummy*/ir->len_in,
 351                      /*timeout*/HZ * USB_CTRL_GET_TIMEOUT);
 352                if (ret < 0)
 353                        printk(DRIVER_NAME "[%d]: SET_INFRABUFFER_EMPTY: error %d\n",
 354                               ir->devnum, ret);
 355                return 0;
 356        } else if (ret < 0)
 357                printk(DRIVER_NAME "[%d]: GET_INFRACODE: error %d\n",
 358                        ir->devnum, ret);
 359
 360        return -ENODATA;
 361}
 362
 363static int igorplugusb_remote_probe(struct usb_interface *intf,
 364                                    const struct usb_device_id *id)
 365{
 366        struct usb_device *dev;
 367        struct usb_host_interface *idesc = NULL;
 368        struct usb_endpoint_descriptor *ep;
 369        struct igorplug *ir = NULL;
 370        struct lirc_driver *driver = NULL;
 371        int devnum, pipe, maxp;
 372        char buf[63], name[128] = "";
 373        int ret;
 374
 375        dev_dbg(&intf->dev, "%s: usb probe called.\n", __func__);
 376
 377        dev = interface_to_usbdev(intf);
 378
 379        idesc = intf->cur_altsetting;
 380
 381        if (idesc->desc.bNumEndpoints != 1)
 382                return -ENODEV;
 383
 384        ep = &idesc->endpoint->desc;
 385        if (((ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK)
 386            != USB_DIR_IN)
 387            || (ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
 388            != USB_ENDPOINT_XFER_CONTROL)
 389                return -ENODEV;
 390
 391        pipe = usb_rcvctrlpipe(dev, ep->bEndpointAddress);
 392        devnum = dev->devnum;
 393        maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe));
 394
 395        dev_dbg(&intf->dev, "%s: bytes_in_key=%zu maxp=%d\n",
 396                __func__, CODE_LENGTH, maxp);
 397
 398        ir = devm_kzalloc(&intf->dev, sizeof(*ir), GFP_KERNEL);
 399        if (!ir)
 400                return -ENOMEM;
 401
 402        driver = devm_kzalloc(&intf->dev, sizeof(*driver), GFP_KERNEL);
 403        if (!driver)
 404                return -ENOMEM;
 405
 406        ir->buf_in = usb_alloc_coherent(dev, DEVICE_BUFLEN + DEVICE_HEADERLEN,
 407                                        GFP_ATOMIC, &ir->dma_in);
 408        if (!ir->buf_in)
 409                return -ENOMEM;
 410
 411        strcpy(driver->name, DRIVER_NAME " ");
 412        driver->minor = -1;
 413        driver->code_length = CODE_LENGTH * 8; /* in bits */
 414        driver->features = LIRC_CAN_REC_MODE2;
 415        driver->data = ir;
 416        driver->chunk_size = CODE_LENGTH;
 417        driver->buffer_size = DEVICE_BUFLEN + ADDITIONAL_LIRC_BYTES;
 418        driver->set_use_inc = &set_use_inc;
 419        driver->set_use_dec = &set_use_dec;
 420        driver->sample_rate = sample_rate;    /* per second */
 421        driver->add_to_buf = &igorplugusb_remote_poll;
 422        driver->dev = &intf->dev;
 423        driver->owner = THIS_MODULE;
 424
 425        ret = lirc_register_driver(driver);
 426        if (ret < 0) {
 427                usb_free_coherent(dev, DEVICE_BUFLEN + DEVICE_HEADERLEN,
 428                        ir->buf_in, ir->dma_in);
 429                return ret;
 430        }
 431
 432        driver->minor = ret;
 433        ir->d = driver;
 434        ir->devnum = devnum;
 435        ir->usbdev = dev;
 436        ir->len_in = DEVICE_BUFLEN + DEVICE_HEADERLEN;
 437        ir->in_space = 1; /* First mode2 event is a space. */
 438        do_gettimeofday(&ir->last_time);
 439
 440        if (dev->descriptor.iManufacturer
 441            && usb_string(dev, dev->descriptor.iManufacturer,
 442                          buf, sizeof(buf)) > 0)
 443                strlcpy(name, buf, sizeof(name));
 444        if (dev->descriptor.iProduct
 445            && usb_string(dev, dev->descriptor.iProduct, buf, sizeof(buf)) > 0)
 446                snprintf(name + strlen(name), sizeof(name) - strlen(name),
 447                         " %s", buf);
 448        printk(DRIVER_NAME "[%d]: %s on usb%d:%d\n", devnum, name,
 449               dev->bus->busnum, devnum);
 450
 451        /* clear device buffer */
 452        ret = usb_control_msg(ir->usbdev, usb_rcvctrlpipe(ir->usbdev, 0),
 453                SET_INFRABUFFER_EMPTY, USB_TYPE_VENDOR|USB_DIR_IN,
 454                /*unused*/0, /*unused*/0,
 455                /*dummy*/ir->buf_in, /*dummy*/ir->len_in,
 456                /*timeout*/HZ * USB_CTRL_GET_TIMEOUT);
 457        if (ret < 0)
 458                printk(DRIVER_NAME "[%d]: SET_INFRABUFFER_EMPTY: error %d\n",
 459                        devnum, ret);
 460
 461        usb_set_intfdata(intf, ir);
 462        return 0;
 463}
 464
 465static void igorplugusb_remote_disconnect(struct usb_interface *intf)
 466{
 467        struct usb_device *usbdev = interface_to_usbdev(intf);
 468        struct igorplug *ir = usb_get_intfdata(intf);
 469        struct device *dev = &intf->dev;
 470        int devnum;
 471
 472        usb_set_intfdata(intf, NULL);
 473
 474        if (!ir || !ir->d)
 475                return;
 476
 477        ir->usbdev = NULL;
 478
 479        usb_free_coherent(usbdev, ir->len_in, ir->buf_in, ir->dma_in);
 480
 481        devnum = unregister_from_lirc(ir);
 482
 483        dev_info(dev, DRIVER_NAME "[%d]: %s done\n", devnum, __func__);
 484}
 485
 486static struct usb_device_id igorplugusb_remote_id_table[] = {
 487        /* Igor Plug USB (Atmel's Manufact. ID) */
 488        { USB_DEVICE(0x03eb, 0x0002) },
 489        /* Fit PC2 Infrared Adapter */
 490        { USB_DEVICE(0x03eb, 0x21fe) },
 491
 492        /* Terminating entry */
 493        { }
 494};
 495
 496static struct usb_driver igorplugusb_remote_driver = {
 497        .name =         DRIVER_NAME,
 498        .probe =        igorplugusb_remote_probe,
 499        .disconnect =   igorplugusb_remote_disconnect,
 500        .id_table =     igorplugusb_remote_id_table
 501};
 502
 503module_usb_driver(igorplugusb_remote_driver);
 504
 505#include <linux/vermagic.h>
 506MODULE_INFO(vermagic, VERMAGIC_STRING);
 507
 508MODULE_DESCRIPTION(DRIVER_DESC);
 509MODULE_AUTHOR(DRIVER_AUTHOR);
 510MODULE_LICENSE("GPL");
 511MODULE_DEVICE_TABLE(usb, igorplugusb_remote_id_table);
 512
 513module_param(sample_rate, int, S_IRUGO | S_IWUSR);
 514MODULE_PARM_DESC(sample_rate, "Sampling rate in Hz (default: 100)");
 515