linux/drivers/usb/serial/cp210x.c
<<
>>
Prefs
   1/*
   2 * Silicon Laboratories CP210x USB to RS232 serial adaptor driver
   3 *
   4 * Copyright (C) 2005 Craig Shelley (craig@microtron.org.uk)
   5 *
   6 *      This program is free software; you can redistribute it and/or
   7 *      modify it under the terms of the GNU General Public License version
   8 *      2 as published by the Free Software Foundation.
   9 *
  10 * Support to set flow control line levels using TIOCMGET and TIOCMSET
  11 * thanks to Karl Hiramoto karl@hiramoto.org. RTSCTS hardware flow
  12 * control thanks to Munir Nassar nassarmu@real-time.com
  13 *
  14 */
  15
  16#include <linux/kernel.h>
  17#include <linux/errno.h>
  18#include <linux/slab.h>
  19#include <linux/tty.h>
  20#include <linux/tty_flip.h>
  21#include <linux/module.h>
  22#include <linux/moduleparam.h>
  23#include <linux/usb.h>
  24#include <linux/uaccess.h>
  25#include <linux/usb/serial.h>
  26
  27/*
  28 * Version Information
  29 */
  30#define DRIVER_VERSION "v0.09"
  31#define DRIVER_DESC "Silicon Labs CP210x RS232 serial adaptor driver"
  32
  33/*
  34 * Function Prototypes
  35 */
  36static int cp210x_open(struct tty_struct *tty, struct usb_serial_port *);
  37static void cp210x_cleanup(struct usb_serial_port *);
  38static void cp210x_close(struct usb_serial_port *);
  39static void cp210x_get_termios(struct tty_struct *,
  40        struct usb_serial_port *port);
  41static void cp210x_get_termios_port(struct usb_serial_port *port,
  42        unsigned int *cflagp, unsigned int *baudp);
  43static void cp210x_set_termios(struct tty_struct *, struct usb_serial_port *,
  44                                                        struct ktermios*);
  45static int cp210x_tiocmget(struct tty_struct *, struct file *);
  46static int cp210x_tiocmset(struct tty_struct *, struct file *,
  47                unsigned int, unsigned int);
  48static int cp210x_tiocmset_port(struct usb_serial_port *port, struct file *,
  49                unsigned int, unsigned int);
  50static void cp210x_break_ctl(struct tty_struct *, int);
  51static int cp210x_startup(struct usb_serial *);
  52static void cp210x_disconnect(struct usb_serial *);
  53static void cp210x_dtr_rts(struct usb_serial_port *p, int on);
  54static int cp210x_carrier_raised(struct usb_serial_port *p);
  55
  56static int debug;
  57
  58static struct usb_device_id id_table [] = {
  59        { USB_DEVICE(0x0471, 0x066A) }, /* AKTAKOM ACE-1001 cable */
  60        { USB_DEVICE(0x0489, 0xE000) }, /* Pirelli Broadband S.p.A, DP-L10 SIP/GSM Mobile */
  61        { USB_DEVICE(0x0745, 0x1000) }, /* CipherLab USB CCD Barcode Scanner 1000 */
  62        { USB_DEVICE(0x08e6, 0x5501) }, /* Gemalto Prox-PU/CU contactless smartcard reader */
  63        { USB_DEVICE(0x08FD, 0x000A) }, /* Digianswer A/S , ZigBee/802.15.4 MAC Device */
  64        { USB_DEVICE(0x0FCF, 0x1003) }, /* Dynastream ANT development board */
  65        { USB_DEVICE(0x0FCF, 0x1004) }, /* Dynastream ANT2USB */
  66        { USB_DEVICE(0x0FCF, 0x1006) }, /* Dynastream ANT development board */
  67        { USB_DEVICE(0x10A6, 0xAA26) }, /* Knock-off DCU-11 cable */
  68        { USB_DEVICE(0x10AB, 0x10C5) }, /* Siemens MC60 Cable */
  69        { USB_DEVICE(0x10B5, 0xAC70) }, /* Nokia CA-42 USB */
  70        { USB_DEVICE(0x10C4, 0x0F91) }, /* Vstabi */
  71        { USB_DEVICE(0x10C4, 0x1101) }, /* Arkham Technology DS101 Bus Monitor */
  72        { USB_DEVICE(0x10C4, 0x1601) }, /* Arkham Technology DS101 Adapter */
  73        { USB_DEVICE(0x10C4, 0x800A) }, /* SPORTident BSM7-D-USB main station */
  74        { USB_DEVICE(0x10C4, 0x803B) }, /* Pololu USB-serial converter */
  75        { USB_DEVICE(0x10C4, 0x8053) }, /* Enfora EDG1228 */
  76        { USB_DEVICE(0x10C4, 0x8054) }, /* Enfora GSM2228 */
  77        { USB_DEVICE(0x10C4, 0x8066) }, /* Argussoft In-System Programmer */
  78        { USB_DEVICE(0x10C4, 0x807A) }, /* Crumb128 board */
  79        { USB_DEVICE(0x10C4, 0x80CA) }, /* Degree Controls Inc */
  80        { USB_DEVICE(0x10C4, 0x80DD) }, /* Tracient RFID */
  81        { USB_DEVICE(0x10C4, 0x80F6) }, /* Suunto sports instrument */
  82        { USB_DEVICE(0x10C4, 0x8115) }, /* Arygon NFC/Mifare Reader */
  83        { USB_DEVICE(0x10C4, 0x813D) }, /* Burnside Telecom Deskmobile */
  84        { USB_DEVICE(0x10C4, 0x813F) }, /* Tams Master Easy Control */
  85        { USB_DEVICE(0x10C4, 0x814A) }, /* West Mountain Radio RIGblaster P&P */
  86        { USB_DEVICE(0x10C4, 0x814B) }, /* West Mountain Radio RIGtalk */
  87        { USB_DEVICE(0x10C4, 0x815E) }, /* Helicomm IP-Link 1220-DVM */
  88        { USB_DEVICE(0x10C4, 0x819F) }, /* MJS USB Toslink Switcher */
  89        { USB_DEVICE(0x10C4, 0x81A6) }, /* ThinkOptics WavIt */
  90        { USB_DEVICE(0x10C4, 0x81AC) }, /* MSD Dash Hawk */
  91        { USB_DEVICE(0x10C4, 0x81C8) }, /* Lipowsky Industrie Elektronik GmbH, Baby-JTAG */
  92        { USB_DEVICE(0x10C4, 0x81E2) }, /* Lipowsky Industrie Elektronik GmbH, Baby-LIN */
  93        { USB_DEVICE(0x10C4, 0x81E7) }, /* Aerocomm Radio */
  94        { USB_DEVICE(0x10C4, 0x81F2) }, /* C1007 HF band RFID controller */
  95        { USB_DEVICE(0x10C4, 0x8218) }, /* Lipowsky Industrie Elektronik GmbH, HARP-1 */
  96        { USB_DEVICE(0x10C4, 0x822B) }, /* Modem EDGE(GSM) Comander 2 */
  97        { USB_DEVICE(0x10C4, 0x826B) }, /* Cygnal Integrated Products, Inc., Fasttrax GPS demostration module */
  98        { USB_DEVICE(0x10c4, 0x8293) }, /* Telegesys ETRX2USB */
  99        { USB_DEVICE(0x10C4, 0x82F9) }, /* Procyon AVS */
 100        { USB_DEVICE(0x10C4, 0x8341) }, /* Siemens MC35PU GPRS Modem */
 101        { USB_DEVICE(0x10C4, 0x8382) }, /* Cygnal Integrated Products, Inc. */
 102        { USB_DEVICE(0x10C4, 0x83A8) }, /* Amber Wireless AMB2560 */
 103        { USB_DEVICE(0x10C4, 0x8411) }, /* Kyocera GPS Module */
 104        { USB_DEVICE(0x10C4, 0x846E) }, /* BEI USB Sensor Interface (VCP) */
 105        { USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */
 106        { USB_DEVICE(0x10C4, 0xEA61) }, /* Silicon Labs factory default */
 107        { USB_DEVICE(0x10C4, 0xF001) }, /* Elan Digital Systems USBscope50 */
 108        { USB_DEVICE(0x10C4, 0xF002) }, /* Elan Digital Systems USBwave12 */
 109        { USB_DEVICE(0x10C4, 0xF003) }, /* Elan Digital Systems USBpulse100 */
 110        { USB_DEVICE(0x10C4, 0xF004) }, /* Elan Digital Systems USBcount50 */
 111        { USB_DEVICE(0x10C5, 0xEA61) }, /* Silicon Labs MobiData GPRS USB Modem */
 112        { USB_DEVICE(0x10CE, 0xEA6A) }, /* Silicon Labs MobiData GPRS USB Modem 100EU */
 113        { USB_DEVICE(0x13AD, 0x9999) }, /* Baltech card reader */
 114        { USB_DEVICE(0x1555, 0x0004) }, /* Owen AC4 USB-RS485 Converter */
 115        { USB_DEVICE(0x166A, 0x0303) }, /* Clipsal 5500PCU C-Bus USB interface */
 116        { USB_DEVICE(0x16D6, 0x0001) }, /* Jablotron serial interface */
 117        { USB_DEVICE(0x18EF, 0xE00F) }, /* ELV USB-I2C-Interface */
 118        { USB_DEVICE(0x413C, 0x9500) }, /* DW700 GPS USB interface */
 119        { } /* Terminating Entry */
 120};
 121
 122MODULE_DEVICE_TABLE(usb, id_table);
 123
 124static struct usb_driver cp210x_driver = {
 125        .name           = "cp210x",
 126        .probe          = usb_serial_probe,
 127        .disconnect     = usb_serial_disconnect,
 128        .id_table       = id_table,
 129        .no_dynamic_id  =       1,
 130};
 131
 132static struct usb_serial_driver cp210x_device = {
 133        .driver = {
 134                .owner =        THIS_MODULE,
 135                .name =         "cp210x",
 136        },
 137        .usb_driver             = &cp210x_driver,
 138        .id_table               = id_table,
 139        .num_ports              = 1,
 140        .open                   = cp210x_open,
 141        .close                  = cp210x_close,
 142        .break_ctl              = cp210x_break_ctl,
 143        .set_termios            = cp210x_set_termios,
 144        .tiocmget               = cp210x_tiocmget,
 145        .tiocmset               = cp210x_tiocmset,
 146        .attach                 = cp210x_startup,
 147        .disconnect             = cp210x_disconnect,
 148        .dtr_rts                = cp210x_dtr_rts,
 149        .carrier_raised         = cp210x_carrier_raised
 150};
 151
 152/* Config request types */
 153#define REQTYPE_HOST_TO_DEVICE  0x41
 154#define REQTYPE_DEVICE_TO_HOST  0xc1
 155
 156/* Config request codes */
 157#define CP210X_IFC_ENABLE       0x00
 158#define CP210X_SET_BAUDDIV      0x01
 159#define CP210X_GET_BAUDDIV      0x02
 160#define CP210X_SET_LINE_CTL     0x03
 161#define CP210X_GET_LINE_CTL     0x04
 162#define CP210X_SET_BREAK        0x05
 163#define CP210X_IMM_CHAR         0x06
 164#define CP210X_SET_MHS          0x07
 165#define CP210X_GET_MDMSTS       0x08
 166#define CP210X_SET_XON          0x09
 167#define CP210X_SET_XOFF         0x0A
 168#define CP210X_SET_EVENTMASK    0x0B
 169#define CP210X_GET_EVENTMASK    0x0C
 170#define CP210X_SET_CHAR         0x0D
 171#define CP210X_GET_CHARS        0x0E
 172#define CP210X_GET_PROPS        0x0F
 173#define CP210X_GET_COMM_STATUS  0x10
 174#define CP210X_RESET            0x11
 175#define CP210X_PURGE            0x12
 176#define CP210X_SET_FLOW         0x13
 177#define CP210X_GET_FLOW         0x14
 178#define CP210X_EMBED_EVENTS     0x15
 179#define CP210X_GET_EVENTSTATE   0x16
 180#define CP210X_SET_CHARS        0x19
 181
 182/* CP210X_IFC_ENABLE */
 183#define UART_ENABLE             0x0001
 184#define UART_DISABLE            0x0000
 185
 186/* CP210X_(SET|GET)_BAUDDIV */
 187#define BAUD_RATE_GEN_FREQ      0x384000
 188
 189/* CP210X_(SET|GET)_LINE_CTL */
 190#define BITS_DATA_MASK          0X0f00
 191#define BITS_DATA_5             0X0500
 192#define BITS_DATA_6             0X0600
 193#define BITS_DATA_7             0X0700
 194#define BITS_DATA_8             0X0800
 195#define BITS_DATA_9             0X0900
 196
 197#define BITS_PARITY_MASK        0x00f0
 198#define BITS_PARITY_NONE        0x0000
 199#define BITS_PARITY_ODD         0x0010
 200#define BITS_PARITY_EVEN        0x0020
 201#define BITS_PARITY_MARK        0x0030
 202#define BITS_PARITY_SPACE       0x0040
 203
 204#define BITS_STOP_MASK          0x000f
 205#define BITS_STOP_1             0x0000
 206#define BITS_STOP_1_5           0x0001
 207#define BITS_STOP_2             0x0002
 208
 209/* CP210X_SET_BREAK */
 210#define BREAK_ON                0x0000
 211#define BREAK_OFF               0x0001
 212
 213/* CP210X_(SET_MHS|GET_MDMSTS) */
 214#define CONTROL_DTR             0x0001
 215#define CONTROL_RTS             0x0002
 216#define CONTROL_CTS             0x0010
 217#define CONTROL_DSR             0x0020
 218#define CONTROL_RING            0x0040
 219#define CONTROL_DCD             0x0080
 220#define CONTROL_WRITE_DTR       0x0100
 221#define CONTROL_WRITE_RTS       0x0200
 222
 223/*
 224 * cp210x_get_config
 225 * Reads from the CP210x configuration registers
 226 * 'size' is specified in bytes.
 227 * 'data' is a pointer to a pre-allocated array of integers large
 228 * enough to hold 'size' bytes (with 4 bytes to each integer)
 229 */
 230static int cp210x_get_config(struct usb_serial_port *port, u8 request,
 231                unsigned int *data, int size)
 232{
 233        struct usb_serial *serial = port->serial;
 234        __le32 *buf;
 235        int result, i, length;
 236
 237        /* Number of integers required to contain the array */
 238        length = (((size - 1) | 3) + 1)/4;
 239
 240        buf = kcalloc(length, sizeof(__le32), GFP_KERNEL);
 241        if (!buf) {
 242                dev_err(&port->dev, "%s - out of memory.\n", __func__);
 243                return -ENOMEM;
 244        }
 245
 246        /* Issue the request, attempting to read 'size' bytes */
 247        result = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
 248                                request, REQTYPE_DEVICE_TO_HOST, 0x0000,
 249                                0, buf, size, 300);
 250
 251        /* Convert data into an array of integers */
 252        for (i = 0; i < length; i++)
 253                data[i] = le32_to_cpu(buf[i]);
 254
 255        kfree(buf);
 256
 257        if (result != size) {
 258                dbg("%s - Unable to send config request, "
 259                                "request=0x%x size=%d result=%d\n",
 260                                __func__, request, size, result);
 261                return -EPROTO;
 262        }
 263
 264        return 0;
 265}
 266
 267/*
 268 * cp210x_set_config
 269 * Writes to the CP210x configuration registers
 270 * Values less than 16 bits wide are sent directly
 271 * 'size' is specified in bytes.
 272 */
 273static int cp210x_set_config(struct usb_serial_port *port, u8 request,
 274                unsigned int *data, int size)
 275{
 276        struct usb_serial *serial = port->serial;
 277        __le32 *buf;
 278        int result, i, length;
 279
 280        /* Number of integers required to contain the array */
 281        length = (((size - 1) | 3) + 1)/4;
 282
 283        buf = kmalloc(length * sizeof(__le32), GFP_KERNEL);
 284        if (!buf) {
 285                dev_err(&port->dev, "%s - out of memory.\n",
 286                                __func__);
 287                return -ENOMEM;
 288        }
 289
 290        /* Array of integers into bytes */
 291        for (i = 0; i < length; i++)
 292                buf[i] = cpu_to_le32(data[i]);
 293
 294        if (size > 2) {
 295                result = usb_control_msg(serial->dev,
 296                                usb_sndctrlpipe(serial->dev, 0),
 297                                request, REQTYPE_HOST_TO_DEVICE, 0x0000,
 298                                0, buf, size, 300);
 299        } else {
 300                result = usb_control_msg(serial->dev,
 301                                usb_sndctrlpipe(serial->dev, 0),
 302                                request, REQTYPE_HOST_TO_DEVICE, data[0],
 303                                0, NULL, 0, 300);
 304        }
 305
 306        kfree(buf);
 307
 308        if ((size > 2 && result != size) || result < 0) {
 309                dbg("%s - Unable to send request, "
 310                                "request=0x%x size=%d result=%d\n",
 311                                __func__, request, size, result);
 312                return -EPROTO;
 313        }
 314
 315        /* Single data value */
 316        result = usb_control_msg(serial->dev,
 317                        usb_sndctrlpipe(serial->dev, 0),
 318                        request, REQTYPE_HOST_TO_DEVICE, data[0],
 319                        0, NULL, 0, 300);
 320        return 0;
 321}
 322
 323/*
 324 * cp210x_set_config_single
 325 * Convenience function for calling cp210x_set_config on single data values
 326 * without requiring an integer pointer
 327 */
 328static inline int cp210x_set_config_single(struct usb_serial_port *port,
 329                u8 request, unsigned int data)
 330{
 331        return cp210x_set_config(port, request, &data, 2);
 332}
 333
 334/*
 335 * cp210x_quantise_baudrate
 336 * Quantises the baud rate as per AN205 Table 1
 337 */
 338static unsigned int cp210x_quantise_baudrate(unsigned int baud) {
 339        if      (baud <= 56)       baud = 0;
 340        else if (baud <= 300)      baud = 300;
 341        else if (baud <= 600)      baud = 600;
 342        else if (baud <= 1200)     baud = 1200;
 343        else if (baud <= 1800)     baud = 1800;
 344        else if (baud <= 2400)     baud = 2400;
 345        else if (baud <= 4000)     baud = 4000;
 346        else if (baud <= 4803)     baud = 4800;
 347        else if (baud <= 7207)     baud = 7200;
 348        else if (baud <= 9612)     baud = 9600;
 349        else if (baud <= 14428)    baud = 14400;
 350        else if (baud <= 16062)    baud = 16000;
 351        else if (baud <= 19250)    baud = 19200;
 352        else if (baud <= 28912)    baud = 28800;
 353        else if (baud <= 38601)    baud = 38400;
 354        else if (baud <= 51558)    baud = 51200;
 355        else if (baud <= 56280)    baud = 56000;
 356        else if (baud <= 58053)    baud = 57600;
 357        else if (baud <= 64111)    baud = 64000;
 358        else if (baud <= 77608)    baud = 76800;
 359        else if (baud <= 117028)   baud = 115200;
 360        else if (baud <= 129347)   baud = 128000;
 361        else if (baud <= 156868)   baud = 153600;
 362        else if (baud <= 237832)   baud = 230400;
 363        else if (baud <= 254234)   baud = 250000;
 364        else if (baud <= 273066)   baud = 256000;
 365        else if (baud <= 491520)   baud = 460800;
 366        else if (baud <= 567138)   baud = 500000;
 367        else if (baud <= 670254)   baud = 576000;
 368        else if (baud <= 1053257)  baud = 921600;
 369        else if (baud <= 1474560)  baud = 1228800;
 370        else if (baud <= 2457600)  baud = 1843200;
 371        else                       baud = 3686400;
 372        return baud;
 373}
 374
 375static int cp210x_open(struct tty_struct *tty, struct usb_serial_port *port)
 376{
 377        struct usb_serial *serial = port->serial;
 378        int result;
 379
 380        dbg("%s - port %d", __func__, port->number);
 381
 382        if (cp210x_set_config_single(port, CP210X_IFC_ENABLE, UART_ENABLE)) {
 383                dev_err(&port->dev, "%s - Unable to enable UART\n",
 384                                __func__);
 385                return -EPROTO;
 386        }
 387
 388        /* Start reading from the device */
 389        usb_fill_bulk_urb(port->read_urb, serial->dev,
 390                        usb_rcvbulkpipe(serial->dev,
 391                        port->bulk_in_endpointAddress),
 392                        port->read_urb->transfer_buffer,
 393                        port->read_urb->transfer_buffer_length,
 394                        serial->type->read_bulk_callback,
 395                        port);
 396        result = usb_submit_urb(port->read_urb, GFP_KERNEL);
 397        if (result) {
 398                dev_err(&port->dev, "%s - failed resubmitting read urb, "
 399                                "error %d\n", __func__, result);
 400                return result;
 401        }
 402
 403        /* Configure the termios structure */
 404        cp210x_get_termios(tty, port);
 405        return 0;
 406}
 407
 408static void cp210x_cleanup(struct usb_serial_port *port)
 409{
 410        struct usb_serial *serial = port->serial;
 411
 412        dbg("%s - port %d", __func__, port->number);
 413
 414        if (serial->dev) {
 415                /* shutdown any bulk reads that might be going on */
 416                if (serial->num_bulk_out)
 417                        usb_kill_urb(port->write_urb);
 418                if (serial->num_bulk_in)
 419                        usb_kill_urb(port->read_urb);
 420        }
 421}
 422
 423static void cp210x_close(struct usb_serial_port *port)
 424{
 425        dbg("%s - port %d", __func__, port->number);
 426
 427        /* shutdown our urbs */
 428        dbg("%s - shutting down urbs", __func__);
 429        usb_kill_urb(port->write_urb);
 430        usb_kill_urb(port->read_urb);
 431
 432        mutex_lock(&port->serial->disc_mutex);
 433        if (!port->serial->disconnected)
 434                cp210x_set_config_single(port, CP210X_IFC_ENABLE, UART_DISABLE);
 435        mutex_unlock(&port->serial->disc_mutex);
 436}
 437
 438/*
 439 * cp210x_get_termios
 440 * Reads the baud rate, data bits, parity, stop bits and flow control mode
 441 * from the device, corrects any unsupported values, and configures the
 442 * termios structure to reflect the state of the device
 443 */
 444static void cp210x_get_termios(struct tty_struct *tty,
 445        struct usb_serial_port *port)
 446{
 447        unsigned int baud;
 448
 449        if (tty) {
 450                cp210x_get_termios_port(tty->driver_data,
 451                        &tty->termios->c_cflag, &baud);
 452                tty_encode_baud_rate(tty, baud, baud);
 453        }
 454
 455        else {
 456                unsigned int cflag;
 457                cflag = 0;
 458                cp210x_get_termios_port(port, &cflag, &baud);
 459        }
 460}
 461
 462/*
 463 * cp210x_get_termios_port
 464 * This is the heart of cp210x_get_termios which always uses a &usb_serial_port.
 465 */
 466static void cp210x_get_termios_port(struct usb_serial_port *port,
 467        unsigned int *cflagp, unsigned int *baudp)
 468{
 469        unsigned int cflag, modem_ctl[4];
 470        unsigned int baud;
 471        unsigned int bits;
 472
 473        dbg("%s - port %d", __func__, port->number);
 474
 475        cp210x_get_config(port, CP210X_GET_BAUDDIV, &baud, 2);
 476        /* Convert to baudrate */
 477        if (baud)
 478                baud = cp210x_quantise_baudrate((BAUD_RATE_GEN_FREQ + baud/2)/ baud);
 479
 480        dbg("%s - baud rate = %d", __func__, baud);
 481        *baudp = baud;
 482
 483        cflag = *cflagp;
 484
 485        cp210x_get_config(port, CP210X_GET_LINE_CTL, &bits, 2);
 486        cflag &= ~CSIZE;
 487        switch (bits & BITS_DATA_MASK) {
 488        case BITS_DATA_5:
 489                dbg("%s - data bits = 5", __func__);
 490                cflag |= CS5;
 491                break;
 492        case BITS_DATA_6:
 493                dbg("%s - data bits = 6", __func__);
 494                cflag |= CS6;
 495                break;
 496        case BITS_DATA_7:
 497                dbg("%s - data bits = 7", __func__);
 498                cflag |= CS7;
 499                break;
 500        case BITS_DATA_8:
 501                dbg("%s - data bits = 8", __func__);
 502                cflag |= CS8;
 503                break;
 504        case BITS_DATA_9:
 505                dbg("%s - data bits = 9 (not supported, using 8 data bits)",
 506                                                                __func__);
 507                cflag |= CS8;
 508                bits &= ~BITS_DATA_MASK;
 509                bits |= BITS_DATA_8;
 510                cp210x_set_config(port, CP210X_SET_LINE_CTL, &bits, 2);
 511                break;
 512        default:
 513                dbg("%s - Unknown number of data bits, using 8", __func__);
 514                cflag |= CS8;
 515                bits &= ~BITS_DATA_MASK;
 516                bits |= BITS_DATA_8;
 517                cp210x_set_config(port, CP210X_SET_LINE_CTL, &bits, 2);
 518                break;
 519        }
 520
 521        switch (bits & BITS_PARITY_MASK) {
 522        case BITS_PARITY_NONE:
 523                dbg("%s - parity = NONE", __func__);
 524                cflag &= ~PARENB;
 525                break;
 526        case BITS_PARITY_ODD:
 527                dbg("%s - parity = ODD", __func__);
 528                cflag |= (PARENB|PARODD);
 529                break;
 530        case BITS_PARITY_EVEN:
 531                dbg("%s - parity = EVEN", __func__);
 532                cflag &= ~PARODD;
 533                cflag |= PARENB;
 534                break;
 535        case BITS_PARITY_MARK:
 536                dbg("%s - parity = MARK (not supported, disabling parity)",
 537                                __func__);
 538                cflag &= ~PARENB;
 539                bits &= ~BITS_PARITY_MASK;
 540                cp210x_set_config(port, CP210X_SET_LINE_CTL, &bits, 2);
 541                break;
 542        case BITS_PARITY_SPACE:
 543                dbg("%s - parity = SPACE (not supported, disabling parity)",
 544                                __func__);
 545                cflag &= ~PARENB;
 546                bits &= ~BITS_PARITY_MASK;
 547                cp210x_set_config(port, CP210X_SET_LINE_CTL, &bits, 2);
 548                break;
 549        default:
 550                dbg("%s - Unknown parity mode, disabling parity", __func__);
 551                cflag &= ~PARENB;
 552                bits &= ~BITS_PARITY_MASK;
 553                cp210x_set_config(port, CP210X_SET_LINE_CTL, &bits, 2);
 554                break;
 555        }
 556
 557        cflag &= ~CSTOPB;
 558        switch (bits & BITS_STOP_MASK) {
 559        case BITS_STOP_1:
 560                dbg("%s - stop bits = 1", __func__);
 561                break;
 562        case BITS_STOP_1_5:
 563                dbg("%s - stop bits = 1.5 (not supported, using 1 stop bit)",
 564                                                                __func__);
 565                bits &= ~BITS_STOP_MASK;
 566                cp210x_set_config(port, CP210X_SET_LINE_CTL, &bits, 2);
 567                break;
 568        case BITS_STOP_2:
 569                dbg("%s - stop bits = 2", __func__);
 570                cflag |= CSTOPB;
 571                break;
 572        default:
 573                dbg("%s - Unknown number of stop bits, using 1 stop bit",
 574                                                                __func__);
 575                bits &= ~BITS_STOP_MASK;
 576                cp210x_set_config(port, CP210X_SET_LINE_CTL, &bits, 2);
 577                break;
 578        }
 579
 580        cp210x_get_config(port, CP210X_GET_FLOW, modem_ctl, 16);
 581        if (modem_ctl[0] & 0x0008) {
 582                dbg("%s - flow control = CRTSCTS", __func__);
 583                cflag |= CRTSCTS;
 584        } else {
 585                dbg("%s - flow control = NONE", __func__);
 586                cflag &= ~CRTSCTS;
 587        }
 588
 589        *cflagp = cflag;
 590}
 591
 592static void cp210x_set_termios(struct tty_struct *tty,
 593                struct usb_serial_port *port, struct ktermios *old_termios)
 594{
 595        unsigned int cflag, old_cflag;
 596        unsigned int baud = 0, bits;
 597        unsigned int modem_ctl[4];
 598
 599        dbg("%s - port %d", __func__, port->number);
 600
 601        if (!tty)
 602                return;
 603
 604        tty->termios->c_cflag &= ~CMSPAR;
 605        cflag = tty->termios->c_cflag;
 606        old_cflag = old_termios->c_cflag;
 607        baud = cp210x_quantise_baudrate(tty_get_baud_rate(tty));
 608
 609        /* If the baud rate is to be updated*/
 610        if (baud != tty_termios_baud_rate(old_termios) && baud != 0) {
 611                dbg("%s - Setting baud rate to %d baud", __func__,
 612                                baud);
 613                if (cp210x_set_config_single(port, CP210X_SET_BAUDDIV,
 614                                        ((BAUD_RATE_GEN_FREQ + baud/2) / baud))) {
 615                        dbg("Baud rate requested not supported by device\n");
 616                        baud = tty_termios_baud_rate(old_termios);
 617                }
 618        }
 619        /* Report back the resulting baud rate */
 620        tty_encode_baud_rate(tty, baud, baud);
 621
 622        /* If the number of data bits is to be updated */
 623        if ((cflag & CSIZE) != (old_cflag & CSIZE)) {
 624                cp210x_get_config(port, CP210X_GET_LINE_CTL, &bits, 2);
 625                bits &= ~BITS_DATA_MASK;
 626                switch (cflag & CSIZE) {
 627                case CS5:
 628                        bits |= BITS_DATA_5;
 629                        dbg("%s - data bits = 5", __func__);
 630                        break;
 631                case CS6:
 632                        bits |= BITS_DATA_6;
 633                        dbg("%s - data bits = 6", __func__);
 634                        break;
 635                case CS7:
 636                        bits |= BITS_DATA_7;
 637                        dbg("%s - data bits = 7", __func__);
 638                        break;
 639                case CS8:
 640                        bits |= BITS_DATA_8;
 641                        dbg("%s - data bits = 8", __func__);
 642                        break;
 643                /*case CS9:
 644                        bits |= BITS_DATA_9;
 645                        dbg("%s - data bits = 9", __func__);
 646                        break;*/
 647                default:
 648                        dbg("cp210x driver does not "
 649                                        "support the number of bits requested,"
 650                                        " using 8 bit mode\n");
 651                                bits |= BITS_DATA_8;
 652                                break;
 653                }
 654                if (cp210x_set_config(port, CP210X_SET_LINE_CTL, &bits, 2))
 655                        dbg("Number of data bits requested "
 656                                        "not supported by device\n");
 657        }
 658
 659        if ((cflag & (PARENB|PARODD)) != (old_cflag & (PARENB|PARODD))) {
 660                cp210x_get_config(port, CP210X_GET_LINE_CTL, &bits, 2);
 661                bits &= ~BITS_PARITY_MASK;
 662                if (cflag & PARENB) {
 663                        if (cflag & PARODD) {
 664                                bits |= BITS_PARITY_ODD;
 665                                dbg("%s - parity = ODD", __func__);
 666                        } else {
 667                                bits |= BITS_PARITY_EVEN;
 668                                dbg("%s - parity = EVEN", __func__);
 669                        }
 670                }
 671                if (cp210x_set_config(port, CP210X_SET_LINE_CTL, &bits, 2))
 672                        dbg("Parity mode not supported "
 673                                        "by device\n");
 674        }
 675
 676        if ((cflag & CSTOPB) != (old_cflag & CSTOPB)) {
 677                cp210x_get_config(port, CP210X_GET_LINE_CTL, &bits, 2);
 678                bits &= ~BITS_STOP_MASK;
 679                if (cflag & CSTOPB) {
 680                        bits |= BITS_STOP_2;
 681                        dbg("%s - stop bits = 2", __func__);
 682                } else {
 683                        bits |= BITS_STOP_1;
 684                        dbg("%s - stop bits = 1", __func__);
 685                }
 686                if (cp210x_set_config(port, CP210X_SET_LINE_CTL, &bits, 2))
 687                        dbg("Number of stop bits requested "
 688                                        "not supported by device\n");
 689        }
 690
 691        if ((cflag & CRTSCTS) != (old_cflag & CRTSCTS)) {
 692                cp210x_get_config(port, CP210X_GET_FLOW, modem_ctl, 16);
 693                dbg("%s - read modem controls = 0x%.4x 0x%.4x 0x%.4x 0x%.4x",
 694                                __func__, modem_ctl[0], modem_ctl[1],
 695                                modem_ctl[2], modem_ctl[3]);
 696
 697                if (cflag & CRTSCTS) {
 698                        modem_ctl[0] &= ~0x7B;
 699                        modem_ctl[0] |= 0x09;
 700                        modem_ctl[1] = 0x80;
 701                        dbg("%s - flow control = CRTSCTS", __func__);
 702                } else {
 703                        modem_ctl[0] &= ~0x7B;
 704                        modem_ctl[0] |= 0x01;
 705                        modem_ctl[1] |= 0x40;
 706                        dbg("%s - flow control = NONE", __func__);
 707                }
 708
 709                dbg("%s - write modem controls = 0x%.4x 0x%.4x 0x%.4x 0x%.4x",
 710                                __func__, modem_ctl[0], modem_ctl[1],
 711                                modem_ctl[2], modem_ctl[3]);
 712                cp210x_set_config(port, CP210X_SET_FLOW, modem_ctl, 16);
 713        }
 714
 715}
 716
 717static int cp210x_tiocmset (struct tty_struct *tty, struct file *file,
 718                unsigned int set, unsigned int clear)
 719{
 720        struct usb_serial_port *port = tty->driver_data;
 721        return cp210x_tiocmset_port(port, file, set, clear);
 722}
 723
 724static int cp210x_tiocmset_port(struct usb_serial_port *port, struct file *file,
 725                unsigned int set, unsigned int clear)
 726{
 727        unsigned int control = 0;
 728
 729        dbg("%s - port %d", __func__, port->number);
 730
 731        if (set & TIOCM_RTS) {
 732                control |= CONTROL_RTS;
 733                control |= CONTROL_WRITE_RTS;
 734        }
 735        if (set & TIOCM_DTR) {
 736                control |= CONTROL_DTR;
 737                control |= CONTROL_WRITE_DTR;
 738        }
 739        if (clear & TIOCM_RTS) {
 740                control &= ~CONTROL_RTS;
 741                control |= CONTROL_WRITE_RTS;
 742        }
 743        if (clear & TIOCM_DTR) {
 744                control &= ~CONTROL_DTR;
 745                control |= CONTROL_WRITE_DTR;
 746        }
 747
 748        dbg("%s - control = 0x%.4x", __func__, control);
 749
 750        return cp210x_set_config(port, CP210X_SET_MHS, &control, 2);
 751}
 752
 753static void cp210x_dtr_rts(struct usb_serial_port *p, int on)
 754{
 755        if (on)
 756                cp210x_tiocmset_port(p, NULL,  TIOCM_DTR|TIOCM_RTS, 0);
 757        else
 758                cp210x_tiocmset_port(p, NULL,  0, TIOCM_DTR|TIOCM_RTS);
 759}
 760
 761static int cp210x_tiocmget (struct tty_struct *tty, struct file *file)
 762{
 763        struct usb_serial_port *port = tty->driver_data;
 764        unsigned int control;
 765        int result;
 766
 767        dbg("%s - port %d", __func__, port->number);
 768
 769        cp210x_get_config(port, CP210X_GET_MDMSTS, &control, 1);
 770
 771        result = ((control & CONTROL_DTR) ? TIOCM_DTR : 0)
 772                |((control & CONTROL_RTS) ? TIOCM_RTS : 0)
 773                |((control & CONTROL_CTS) ? TIOCM_CTS : 0)
 774                |((control & CONTROL_DSR) ? TIOCM_DSR : 0)
 775                |((control & CONTROL_RING)? TIOCM_RI  : 0)
 776                |((control & CONTROL_DCD) ? TIOCM_CD  : 0);
 777
 778        dbg("%s - control = 0x%.2x", __func__, control);
 779
 780        return result;
 781}
 782
 783static int cp210x_carrier_raised(struct usb_serial_port *p)
 784{
 785        unsigned int control;
 786        cp210x_get_config(p, CP210X_GET_MDMSTS, &control, 1);
 787        if (control & CONTROL_DCD)
 788                return 1;
 789        return 0;
 790}
 791
 792static void cp210x_break_ctl (struct tty_struct *tty, int break_state)
 793{
 794        struct usb_serial_port *port = tty->driver_data;
 795        unsigned int state;
 796
 797        dbg("%s - port %d", __func__, port->number);
 798        if (break_state == 0)
 799                state = BREAK_OFF;
 800        else
 801                state = BREAK_ON;
 802        dbg("%s - turning break %s", __func__,
 803                        state == BREAK_OFF ? "off" : "on");
 804        cp210x_set_config(port, CP210X_SET_BREAK, &state, 2);
 805}
 806
 807static int cp210x_startup(struct usb_serial *serial)
 808{
 809        /* cp210x buffers behave strangely unless device is reset */
 810        usb_reset_device(serial->dev);
 811        return 0;
 812}
 813
 814static void cp210x_disconnect(struct usb_serial *serial)
 815{
 816        int i;
 817
 818        dbg("%s", __func__);
 819
 820        /* Stop reads and writes on all ports */
 821        for (i = 0; i < serial->num_ports; ++i)
 822                cp210x_cleanup(serial->port[i]);
 823}
 824
 825static int __init cp210x_init(void)
 826{
 827        int retval;
 828
 829        retval = usb_serial_register(&cp210x_device);
 830        if (retval)
 831                return retval; /* Failed to register */
 832
 833        retval = usb_register(&cp210x_driver);
 834        if (retval) {
 835                /* Failed to register */
 836                usb_serial_deregister(&cp210x_device);
 837                return retval;
 838        }
 839
 840        /* Success */
 841        printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"
 842               DRIVER_DESC "\n");
 843        return 0;
 844}
 845
 846static void __exit cp210x_exit(void)
 847{
 848        usb_deregister(&cp210x_driver);
 849        usb_serial_deregister(&cp210x_device);
 850}
 851
 852module_init(cp210x_init);
 853module_exit(cp210x_exit);
 854
 855MODULE_DESCRIPTION(DRIVER_DESC);
 856MODULE_VERSION(DRIVER_VERSION);
 857MODULE_LICENSE("GPL");
 858
 859module_param(debug, bool, S_IRUGO | S_IWUSR);
 860MODULE_PARM_DESC(debug, "Enable verbose debugging messages");
 861