linux/drivers/usb/serial/ir-usb.c
<<
>>
Prefs
   1/*
   2 * USB IR Dongle driver
   3 *
   4 *      Copyright (C) 2001-2002 Greg Kroah-Hartman (greg@kroah.com)
   5 *      Copyright (C) 2002      Gary Brubaker (xavyer@ix.netcom.com)
   6 *      Copyright (C) 2010      Johan Hovold (jhovold@gmail.com)
   7 *
   8 *      This program is free software; you can redistribute it and/or modify
   9 *      it under the terms of the GNU General Public License as published by
  10 *      the Free Software Foundation; either version 2 of the License, or
  11 *      (at your option) any later version.
  12 *
  13 * This driver allows a USB IrDA device to be used as a "dumb" serial device.
  14 * This can be useful if you do not have access to a full IrDA stack on the
  15 * other side of the connection.  If you do have an IrDA stack on both devices,
  16 * please use the usb-irda driver, as it contains the proper error checking and
  17 * other goodness of a full IrDA stack.
  18 *
  19 * Portions of this driver were taken from drivers/net/irda/irda-usb.c, which
  20 * was written by Roman Weissgaerber <weissg@vienna.at>, Dag Brattli
  21 * <dag@brattli.net>, and Jean Tourrilhes <jt@hpl.hp.com>
  22 *
  23 * See Documentation/usb/usb-serial.txt for more information on using this
  24 * driver
  25 *
  26 * 2008_Jun_02  Felipe Balbi <me@felipebalbi.com>
  27 *      Introduced common header to be used also in USB Gadget Framework.
  28 *      Still needs some other style fixes.
  29 *
  30 * 2007_Jun_21  Alan Cox <alan@lxorguk.ukuu.org.uk>
  31 *      Minimal cleanups for some of the driver problens and tty layer abuse.
  32 *      Still needs fixing to allow multiple dongles.
  33 *
  34 * 2002_Mar_07  greg kh
  35 *      moved some needed structures and #define values from the
  36 *      net/irda/irda-usb.h file into our file, as we don't want to depend on
  37 *      that codebase compiling correctly :)
  38 *
  39 * 2002_Jan_14  gb
  40 *      Added module parameter to force specific number of XBOFs.
  41 *      Added ir_xbof_change().
  42 *      Reorganized read_bulk_callback error handling.
  43 *      Switched from FILL_BULK_URB() to usb_fill_bulk_urb().
  44 *
  45 * 2001_Nov_08  greg kh
  46 *      Changed the irda_usb_find_class_desc() function based on comments and
  47 *      code from Martin Diehl.
  48 *
  49 * 2001_Nov_01  greg kh
  50 *      Added support for more IrDA USB devices.
  51 *      Added support for zero packet.  Added buffer override paramater, so
  52 *      users can transfer larger packets at once if they wish.  Both patches
  53 *      came from Dag Brattli <dag@obexcode.com>.
  54 *
  55 * 2001_Oct_07  greg kh
  56 *      initial version released.
  57 */
  58
  59#include <linux/kernel.h>
  60#include <linux/errno.h>
  61#include <linux/init.h>
  62#include <linux/slab.h>
  63#include <linux/tty.h>
  64#include <linux/tty_driver.h>
  65#include <linux/tty_flip.h>
  66#include <linux/module.h>
  67#include <linux/spinlock.h>
  68#include <linux/uaccess.h>
  69#include <linux/usb.h>
  70#include <linux/usb/serial.h>
  71#include <linux/usb/irda.h>
  72
  73/*
  74 * Version Information
  75 */
  76#define DRIVER_VERSION "v0.5"
  77#define DRIVER_AUTHOR "Greg Kroah-Hartman <greg@kroah.com>, Johan Hovold <jhovold@gmail.com>"
  78#define DRIVER_DESC "USB IR Dongle driver"
  79
  80static int debug;
  81
  82/* if overridden by the user, then use their value for the size of the read and
  83 * write urbs */
  84static int buffer_size;
  85
  86/* if overridden by the user, then use the specified number of XBOFs */
  87static int xbof = -1;
  88
  89static int  ir_startup (struct usb_serial *serial);
  90static int  ir_open(struct tty_struct *tty, struct usb_serial_port *port);
  91static int ir_prepare_write_buffer(struct usb_serial_port *port,
  92                                                void *dest, size_t size);
  93static void ir_process_read_urb(struct urb *urb);
  94static void ir_set_termios(struct tty_struct *tty,
  95                struct usb_serial_port *port, struct ktermios *old_termios);
  96
  97/* Not that this lot means you can only have one per system */
  98static u8 ir_baud;
  99static u8 ir_xbof;
 100static u8 ir_add_bof;
 101
 102static const struct usb_device_id ir_id_table[] = {
 103        { USB_DEVICE(0x050f, 0x0180) },         /* KC Technology, KC-180 */
 104        { USB_DEVICE(0x08e9, 0x0100) },         /* XTNDAccess */
 105        { USB_DEVICE(0x09c4, 0x0011) },         /* ACTiSys ACT-IR2000U */
 106        { USB_INTERFACE_INFO(USB_CLASS_APP_SPEC, USB_SUBCLASS_IRDA, 0) },
 107        { }                                     /* Terminating entry */
 108};
 109
 110MODULE_DEVICE_TABLE(usb, ir_id_table);
 111
 112static struct usb_driver ir_driver = {
 113        .name           = "ir-usb",
 114        .probe          = usb_serial_probe,
 115        .disconnect     = usb_serial_disconnect,
 116        .id_table       = ir_id_table,
 117        .no_dynamic_id  = 1,
 118};
 119
 120static struct usb_serial_driver ir_device = {
 121        .driver = {
 122                .owner  = THIS_MODULE,
 123                .name   = "ir-usb",
 124        },
 125        .description            = "IR Dongle",
 126        .usb_driver             = &ir_driver,
 127        .id_table               = ir_id_table,
 128        .num_ports              = 1,
 129        .set_termios            = ir_set_termios,
 130        .attach                 = ir_startup,
 131        .open                   = ir_open,
 132        .prepare_write_buffer   = ir_prepare_write_buffer,
 133        .process_read_urb       = ir_process_read_urb,
 134};
 135
 136static inline void irda_usb_dump_class_desc(struct usb_irda_cs_descriptor *desc)
 137{
 138        dbg("bLength=%x", desc->bLength);
 139        dbg("bDescriptorType=%x", desc->bDescriptorType);
 140        dbg("bcdSpecRevision=%x", __le16_to_cpu(desc->bcdSpecRevision));
 141        dbg("bmDataSize=%x", desc->bmDataSize);
 142        dbg("bmWindowSize=%x", desc->bmWindowSize);
 143        dbg("bmMinTurnaroundTime=%d", desc->bmMinTurnaroundTime);
 144        dbg("wBaudRate=%x", __le16_to_cpu(desc->wBaudRate));
 145        dbg("bmAdditionalBOFs=%x", desc->bmAdditionalBOFs);
 146        dbg("bIrdaRateSniff=%x", desc->bIrdaRateSniff);
 147        dbg("bMaxUnicastList=%x", desc->bMaxUnicastList);
 148}
 149
 150/*------------------------------------------------------------------*/
 151/*
 152 * Function irda_usb_find_class_desc(dev, ifnum)
 153 *
 154 *    Returns instance of IrDA class descriptor, or NULL if not found
 155 *
 156 * The class descriptor is some extra info that IrDA USB devices will
 157 * offer to us, describing their IrDA characteristics. We will use that in
 158 * irda_usb_init_qos()
 159 *
 160 * Based on the same function in drivers/net/irda/irda-usb.c
 161 */
 162static struct usb_irda_cs_descriptor *
 163irda_usb_find_class_desc(struct usb_device *dev, unsigned int ifnum)
 164{
 165        struct usb_irda_cs_descriptor *desc;
 166        int ret;
 167
 168        desc = kzalloc(sizeof(*desc), GFP_KERNEL);
 169        if (!desc)
 170                return NULL;
 171
 172        ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
 173                        USB_REQ_CS_IRDA_GET_CLASS_DESC,
 174                        USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
 175                        0, ifnum, desc, sizeof(*desc), 1000);
 176
 177        dbg("%s -  ret=%d", __func__, ret);
 178        if (ret < sizeof(*desc)) {
 179                dbg("%s - class descriptor read %s (%d)",
 180                                __func__,
 181                                (ret < 0) ? "failed" : "too short",
 182                                ret);
 183                goto error;
 184        }
 185        if (desc->bDescriptorType != USB_DT_CS_IRDA) {
 186                dbg("%s - bad class descriptor type", __func__);
 187                goto error;
 188        }
 189
 190        irda_usb_dump_class_desc(desc);
 191        return desc;
 192
 193error:
 194        kfree(desc);
 195        return NULL;
 196}
 197
 198static u8 ir_xbof_change(u8 xbof)
 199{
 200        u8 result;
 201
 202        /* reference irda-usb.c */
 203        switch (xbof) {
 204        case 48:
 205                result = 0x10;
 206                break;
 207        case 28:
 208        case 24:
 209                result = 0x20;
 210                break;
 211        default:
 212        case 12:
 213                result = 0x30;
 214                break;
 215        case  5:
 216        case  6:
 217                result = 0x40;
 218                break;
 219        case  3:
 220                result = 0x50;
 221                break;
 222        case  2:
 223                result = 0x60;
 224                break;
 225        case  1:
 226                result = 0x70;
 227                break;
 228        case  0:
 229                result = 0x80;
 230                break;
 231        }
 232
 233        return(result);
 234}
 235
 236static int ir_startup(struct usb_serial *serial)
 237{
 238        struct usb_irda_cs_descriptor *irda_desc;
 239
 240        irda_desc = irda_usb_find_class_desc(serial->dev, 0);
 241        if (!irda_desc) {
 242                dev_err(&serial->dev->dev,
 243                        "IRDA class descriptor not found, device not bound\n");
 244                return -ENODEV;
 245        }
 246
 247        dbg("%s - Baud rates supported:%s%s%s%s%s%s%s%s%s",
 248                __func__,
 249                (irda_desc->wBaudRate & USB_IRDA_BR_2400) ? " 2400" : "",
 250                (irda_desc->wBaudRate & USB_IRDA_BR_9600) ? " 9600" : "",
 251                (irda_desc->wBaudRate & USB_IRDA_BR_19200) ? " 19200" : "",
 252                (irda_desc->wBaudRate & USB_IRDA_BR_38400) ? " 38400" : "",
 253                (irda_desc->wBaudRate & USB_IRDA_BR_57600) ? " 57600" : "",
 254                (irda_desc->wBaudRate & USB_IRDA_BR_115200) ? " 115200" : "",
 255                (irda_desc->wBaudRate & USB_IRDA_BR_576000) ? " 576000" : "",
 256                (irda_desc->wBaudRate & USB_IRDA_BR_1152000) ? " 1152000" : "",
 257                (irda_desc->wBaudRate & USB_IRDA_BR_4000000) ? " 4000000" : "");
 258
 259        switch (irda_desc->bmAdditionalBOFs) {
 260        case USB_IRDA_AB_48:
 261                ir_add_bof = 48;
 262                break;
 263        case USB_IRDA_AB_24:
 264                ir_add_bof = 24;
 265                break;
 266        case USB_IRDA_AB_12:
 267                ir_add_bof = 12;
 268                break;
 269        case USB_IRDA_AB_6:
 270                ir_add_bof = 6;
 271                break;
 272        case USB_IRDA_AB_3:
 273                ir_add_bof = 3;
 274                break;
 275        case USB_IRDA_AB_2:
 276                ir_add_bof = 2;
 277                break;
 278        case USB_IRDA_AB_1:
 279                ir_add_bof = 1;
 280                break;
 281        case USB_IRDA_AB_0:
 282                ir_add_bof = 0;
 283                break;
 284        default:
 285                break;
 286        }
 287
 288        kfree(irda_desc);
 289
 290        return 0;
 291}
 292
 293static int ir_open(struct tty_struct *tty, struct usb_serial_port *port)
 294{
 295        int i;
 296
 297        dbg("%s - port %d", __func__, port->number);
 298
 299        for (i = 0; i < ARRAY_SIZE(port->write_urbs); ++i)
 300                port->write_urbs[i]->transfer_flags = URB_ZERO_PACKET;
 301
 302        /* Start reading from the device */
 303        return usb_serial_generic_open(tty, port);
 304}
 305
 306static int ir_prepare_write_buffer(struct usb_serial_port *port,
 307                                                void *dest, size_t size)
 308{
 309        unsigned char *buf = dest;
 310        int count;
 311
 312        /*
 313         * The first byte of the packet we send to the device contains an
 314         * inbound header which indicates an additional number of BOFs and
 315         * a baud rate change.
 316         *
 317         * See section 5.4.2.2 of the USB IrDA spec.
 318         */
 319        *buf = ir_xbof | ir_baud;
 320
 321        count = kfifo_out_locked(&port->write_fifo, buf + 1, size - 1,
 322                                                                &port->lock);
 323        return count + 1;
 324}
 325
 326static void ir_process_read_urb(struct urb *urb)
 327{
 328        struct usb_serial_port *port = urb->context;
 329        unsigned char *data = urb->transfer_buffer;
 330        struct tty_struct *tty;
 331
 332        if (!urb->actual_length)
 333                return;
 334        /*
 335         * The first byte of the packet we get from the device
 336         * contains a busy indicator and baud rate change.
 337         * See section 5.4.1.2 of the USB IrDA spec.
 338         */
 339        if (*data & 0x0f)
 340                ir_baud = *data & 0x0f;
 341
 342        if (urb->actual_length == 1)
 343                return;
 344
 345        tty = tty_port_tty_get(&port->port);
 346        if (!tty)
 347                return;
 348        tty_insert_flip_string(tty, data + 1, urb->actual_length - 1);
 349        tty_flip_buffer_push(tty);
 350        tty_kref_put(tty);
 351}
 352
 353static void ir_set_termios_callback(struct urb *urb)
 354{
 355        struct usb_serial_port *port = urb->context;
 356        int status = urb->status;
 357
 358        dbg("%s - port %d", __func__, port->number);
 359
 360        kfree(urb->transfer_buffer);
 361
 362        if (status)
 363                dbg("%s - non-zero urb status: %d", __func__, status);
 364}
 365
 366static void ir_set_termios(struct tty_struct *tty,
 367                struct usb_serial_port *port, struct ktermios *old_termios)
 368{
 369        struct urb *urb;
 370        unsigned char *transfer_buffer;
 371        int result;
 372        speed_t baud;
 373        int ir_baud;
 374
 375        dbg("%s - port %d", __func__, port->number);
 376
 377        baud = tty_get_baud_rate(tty);
 378
 379        /*
 380         * FIXME, we should compare the baud request against the
 381         * capability stated in the IR header that we got in the
 382         * startup function.
 383         */
 384
 385        switch (baud) {
 386        case 2400:
 387                ir_baud = USB_IRDA_BR_2400;
 388                break;
 389        case 9600:
 390                ir_baud = USB_IRDA_BR_9600;
 391                break;
 392        case 19200:
 393                ir_baud = USB_IRDA_BR_19200;
 394                break;
 395        case 38400:
 396                ir_baud = USB_IRDA_BR_38400;
 397                break;
 398        case 57600:
 399                ir_baud = USB_IRDA_BR_57600;
 400                break;
 401        case 115200:
 402                ir_baud = USB_IRDA_BR_115200;
 403                break;
 404        case 576000:
 405                ir_baud = USB_IRDA_BR_576000;
 406                break;
 407        case 1152000:
 408                ir_baud = USB_IRDA_BR_1152000;
 409                break;
 410        case 4000000:
 411                ir_baud = USB_IRDA_BR_4000000;
 412                break;
 413        default:
 414                ir_baud = USB_IRDA_BR_9600;
 415                baud = 9600;
 416        }
 417
 418        if (xbof == -1)
 419                ir_xbof = ir_xbof_change(ir_add_bof);
 420        else
 421                ir_xbof = ir_xbof_change(xbof) ;
 422
 423        /* Only speed changes are supported */
 424        tty_termios_copy_hw(tty->termios, old_termios);
 425        tty_encode_baud_rate(tty, baud, baud);
 426
 427        /*
 428         * send the baud change out on an "empty" data packet
 429         */
 430        urb = usb_alloc_urb(0, GFP_KERNEL);
 431        if (!urb) {
 432                dev_err(&port->dev, "%s - no more urbs\n", __func__);
 433                return;
 434        }
 435        transfer_buffer = kmalloc(1, GFP_KERNEL);
 436        if (!transfer_buffer) {
 437                dev_err(&port->dev, "%s - out of memory\n", __func__);
 438                goto err_buf;
 439        }
 440
 441        *transfer_buffer = ir_xbof | ir_baud;
 442
 443        usb_fill_bulk_urb(
 444                urb,
 445                port->serial->dev,
 446                usb_sndbulkpipe(port->serial->dev,
 447                        port->bulk_out_endpointAddress),
 448                transfer_buffer,
 449                1,
 450                ir_set_termios_callback,
 451                port);
 452
 453        urb->transfer_flags = URB_ZERO_PACKET;
 454
 455        result = usb_submit_urb(urb, GFP_KERNEL);
 456        if (result) {
 457                dev_err(&port->dev, "%s - failed to submit urb: %d\n",
 458                                                        __func__, result);
 459                goto err_subm;
 460        }
 461
 462        usb_free_urb(urb);
 463
 464        return;
 465err_subm:
 466        kfree(transfer_buffer);
 467err_buf:
 468        usb_free_urb(urb);
 469}
 470
 471static int __init ir_init(void)
 472{
 473        int retval;
 474
 475        if (buffer_size) {
 476                ir_device.bulk_in_size = buffer_size;
 477                ir_device.bulk_out_size = buffer_size;
 478        }
 479
 480        retval = usb_serial_register(&ir_device);
 481        if (retval)
 482                goto failed_usb_serial_register;
 483
 484        retval = usb_register(&ir_driver);
 485        if (retval)
 486                goto failed_usb_register;
 487
 488        printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"
 489               DRIVER_DESC "\n");
 490
 491        return 0;
 492
 493failed_usb_register:
 494        usb_serial_deregister(&ir_device);
 495
 496failed_usb_serial_register:
 497        return retval;
 498}
 499
 500static void __exit ir_exit(void)
 501{
 502        usb_deregister(&ir_driver);
 503        usb_serial_deregister(&ir_device);
 504}
 505
 506
 507module_init(ir_init);
 508module_exit(ir_exit);
 509
 510MODULE_AUTHOR(DRIVER_AUTHOR);
 511MODULE_DESCRIPTION(DRIVER_DESC);
 512MODULE_LICENSE("GPL");
 513
 514module_param(debug, bool, S_IRUGO | S_IWUSR);
 515MODULE_PARM_DESC(debug, "Debug enabled or not");
 516module_param(xbof, int, 0);
 517MODULE_PARM_DESC(xbof, "Force specific number of XBOFs");
 518module_param(buffer_size, int, 0);
 519MODULE_PARM_DESC(buffer_size, "Size of the transfer buffers");
 520
 521
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.