[PATCH] USB: CP2101 Add support for flow control

Added support to get/set flow control line levels using TIOCMGET and
TIOCMSET.
Added support for RTSCTS hardware flow control.
cp2101_get_config and cp2101_set_config modified to support long request
strings, required for configuring flow control.

Signed-off-by: Craig Shelley craig@microtron.org.uk
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

authored by Craig Shelley and committed by Greg KH 39a66b8d 719df469

+283 -96
+283 -96
drivers/usb/serial/cp2101.c
··· 7 * modify it under the terms of the GNU General Public License version 8 * 2 as published by the Free Software Foundation. 9 * 10 */ 11 12 #include <linux/config.h> ··· 32 /* 33 * Version Information 34 */ 35 - #define DRIVER_VERSION "v0.03" 36 #define DRIVER_DESC "Silicon Labs CP2101/CP2102 RS232 serial adaptor driver" 37 38 /* ··· 43 static void cp2101_close(struct usb_serial_port*, struct file*); 44 static void cp2101_get_termios(struct usb_serial_port*); 45 static void cp2101_set_termios(struct usb_serial_port*, struct termios*); 46 static void cp2101_break_ctl(struct usb_serial_port*, int); 47 static int cp2101_startup (struct usb_serial *); 48 static void cp2101_shutdown(struct usb_serial*); ··· 54 static int debug; 55 56 static struct usb_device_id id_table [] = { 57 - {USB_DEVICE(0x10c4, 0xea60) }, /*Silicon labs factory default*/ 58 - {USB_DEVICE(0x10ab, 0x10c5) }, /*Siemens MC60 Cable*/ 59 - { } /* Terminating Entry*/ 60 }; 61 62 MODULE_DEVICE_TABLE (usb, id_table); ··· 82 .close = cp2101_close, 83 .break_ctl = cp2101_break_ctl, 84 .set_termios = cp2101_set_termios, 85 .attach = cp2101_startup, 86 .shutdown = cp2101_shutdown, 87 }; 88 89 - /*Config request types*/ 90 #define REQTYPE_HOST_TO_DEVICE 0x41 91 #define REQTYPE_DEVICE_TO_HOST 0xc1 92 93 - /*Config SET requests. To GET, add 1 to the request number*/ 94 - #define CP2101_UART 0x00 /*Enable / Disable*/ 95 - #define CP2101_BAUDRATE 0x01 /*(BAUD_RATE_GEN_FREQ / baudrate)*/ 96 - #define CP2101_BITS 0x03 /*0x(0)(data bits)(parity)(stop bits)*/ 97 - #define CP2101_BREAK 0x05 /*On / Off*/ 98 - #define CP2101_DTRRTS 0x07 /*101 / 202 ???*/ 99 - #define CP2101_CONFIG_16 0x13 /*16 bytes of config data ???*/ 100 - #define CP2101_CONFIG_6 0x19 /*6 bytes of config data ???*/ 101 102 - /*CP2101_UART*/ 103 #define UART_ENABLE 0x0001 104 #define UART_DISABLE 0x0000 105 106 - /*CP2101_BAUDRATE*/ 107 #define BAUD_RATE_GEN_FREQ 0x384000 108 109 - /*CP2101_BITS*/ 110 #define BITS_DATA_MASK 0X0f00 111 #define BITS_DATA_6 0X0600 112 #define BITS_DATA_7 0X0700 113 #define BITS_DATA_8 0X0800 ··· 127 #define BITS_STOP_1 0x0000 128 #define BITS_STOP_1_5 0x0001 129 #define BITS_STOP_2 0x0002 130 #define BREAK_ON 0x0000 131 #define BREAK_OFF 0x0001 132 133 134 - static int cp2101_get_config(struct usb_serial_port* port, u8 request) 135 { 136 struct usb_serial *serial = port->serial; 137 - unsigned char buf[4]; 138 - unsigned int value; 139 - int result, i; 140 141 - /*For get requests, the request number must be incremented*/ 142 request++; 143 144 - /*Issue the request, attempting to read 4 bytes*/ 145 result = usb_control_msg (serial->dev,usb_rcvctrlpipe (serial->dev, 0), 146 request, REQTYPE_DEVICE_TO_HOST, 0x0000, 147 - 0, buf, 4, 300); 148 149 - if (result < 0) { 150 dev_err(&port->dev, "%s - Unable to send config request, " 151 - "request=0x%x result=%d\n", 152 - __FUNCTION__, request, result); 153 - return result; 154 } 155 - 156 - /*Assemble each byte read into an integer value*/ 157 - value = 0; 158 - for (i=0; i<4 && i<result; i++) 159 - value |= (buf[i] << (i * 8)); 160 - 161 - dbg( " %s - request=0x%x result=%d value=0x%x", 162 - __FUNCTION__, request, result, value); 163 - 164 - return value; 165 - } 166 - 167 - static int cp2101_set_config(struct usb_serial_port* port, u8 request, u16 value) 168 - { 169 - struct usb_serial *serial = port->serial; 170 - int result; 171 - result = usb_control_msg (serial->dev, usb_sndctrlpipe(serial->dev, 0), 172 - request, REQTYPE_HOST_TO_DEVICE, value, 173 - 0, NULL, 0, 300); 174 - 175 - if (result <0) { 176 - dev_err(&port->dev, "%s - Unable to send config request, " 177 - "request=0x%x value=0x%x result=%d\n", 178 - __FUNCTION__, request, value, result); 179 - return result; 180 - } 181 - 182 - dbg(" %s - request=0x%x value=0x%x result=%d", 183 - __FUNCTION__, request, value, result); 184 185 return 0; 186 } 187 188 static int cp2101_open (struct usb_serial_port *port, struct file *filp) ··· 265 266 dbg("%s - port %d", __FUNCTION__, port->number); 267 268 - if (cp2101_set_config(port, CP2101_UART, UART_ENABLE)) { 269 dev_err(&port->dev, "%s - Unable to enable UART\n", 270 __FUNCTION__); 271 return -EPROTO; ··· 286 return result; 287 } 288 289 - /*Configure the termios structure*/ 290 cp2101_get_termios(port); 291 292 return 0; 293 } ··· 319 usb_kill_urb(port->write_urb); 320 usb_kill_urb(port->read_urb); 321 322 - cp2101_set_config(port, CP2101_UART, UART_DISABLE); 323 } 324 325 - /* cp2101_get_termios*/ 326 - /* Reads the baud rate, data bits, parity and stop bits from the device*/ 327 - /* Corrects any unsupported values*/ 328 - /* Configures the termios structure to reflect the state of the device*/ 329 static void cp2101_get_termios (struct usb_serial_port *port) 330 { 331 - unsigned int cflag; 332 int baud; 333 int bits; 334 ··· 342 } 343 cflag = port->tty->termios->c_cflag; 344 345 - baud = cp2101_get_config(port, CP2101_BAUDRATE); 346 - /*Convert to baudrate*/ 347 if (baud) 348 baud = BAUD_RATE_GEN_FREQ / baud; 349 350 dbg("%s - baud rate = %d", __FUNCTION__, baud); 351 cflag &= ~CBAUD; 352 switch (baud) { 353 - /* The baud rates which are commented out below 354 * appear to be supported by the device 355 * but are non-standard 356 */ ··· 378 dbg("%s - Baud rate is not supported, " 379 "using 9600 baud", __FUNCTION__); 380 cflag |= B9600; 381 - cp2101_set_config(port, CP2101_BAUDRATE, 382 (BAUD_RATE_GEN_FREQ/9600)); 383 break; 384 } 385 386 - bits = cp2101_get_config(port, CP2101_BITS); 387 cflag &= ~CSIZE; 388 switch(bits & BITS_DATA_MASK) { 389 case BITS_DATA_6: 390 dbg("%s - data bits = 6", __FUNCTION__); 391 cflag |= CS6; ··· 408 cflag |= CS8; 409 bits &= ~BITS_DATA_MASK; 410 bits |= BITS_DATA_8; 411 - cp2101_set_config(port, CP2101_BITS, bits); 412 break; 413 default: 414 dbg("%s - Unknown number of data bits, " ··· 416 cflag |= CS8; 417 bits &= ~BITS_DATA_MASK; 418 bits |= BITS_DATA_8; 419 - cp2101_set_config(port, CP2101_BITS, bits); 420 break; 421 } 422 ··· 439 "disabling parity)", __FUNCTION__); 440 cflag &= ~PARENB; 441 bits &= ~BITS_PARITY_MASK; 442 - cp2101_set_config(port, CP2101_BITS, bits); 443 break; 444 case BITS_PARITY_SPACE: 445 dbg("%s - parity = SPACE (not supported, " 446 "disabling parity)", __FUNCTION__); 447 cflag &= ~PARENB; 448 bits &= ~BITS_PARITY_MASK; 449 - cp2101_set_config(port, CP2101_BITS, bits); 450 break; 451 default: 452 dbg("%s - Unknown parity mode, " 453 "disabling parity", __FUNCTION__); 454 cflag &= ~PARENB; 455 bits &= ~BITS_PARITY_MASK; 456 - cp2101_set_config(port, CP2101_BITS, bits); 457 break; 458 } 459 ··· 464 break; 465 case BITS_STOP_1_5: 466 dbg("%s - stop bits = 1.5 (not supported, " 467 - "using 1 stop bit", __FUNCTION__); 468 bits &= ~BITS_STOP_MASK; 469 - cp2101_set_config(port, CP2101_BITS, bits); 470 break; 471 case BITS_STOP_2: 472 dbg("%s - stop bits = 2", __FUNCTION__); ··· 476 dbg("%s - Unknown number of stop bits, " 477 "using 1 stop bit", __FUNCTION__); 478 bits &= ~BITS_STOP_MASK; 479 - cp2101_set_config(port, CP2101_BITS, bits); 480 break; 481 } 482 483 port->tty->termios->c_cflag = cflag; ··· 496 struct termios *old_termios) 497 { 498 unsigned int cflag, old_cflag=0; 499 - int baud=0; 500 - int bits; 501 502 dbg("%s - port %d", __FUNCTION__, port->number); 503 ··· 507 } 508 cflag = port->tty->termios->c_cflag; 509 510 - /* check that they really want us to change something */ 511 if (old_termios) { 512 if ((cflag == old_termios->c_cflag) && 513 (RELEVANT_IFLAG(port->tty->termios->c_iflag) ··· 522 /* If the baud rate is to be updated*/ 523 if ((cflag & CBAUD) != (old_cflag & CBAUD)) { 524 switch (cflag & CBAUD) { 525 - /* The baud rates which are commented out below 526 * appear to be supported by the device 527 * but are non-standard 528 */ ··· 556 if (baud) { 557 dbg("%s - Setting baud rate to %d baud", __FUNCTION__, 558 baud); 559 - if (cp2101_set_config(port, CP2101_BAUDRATE, 560 (BAUD_RATE_GEN_FREQ / baud))) 561 dev_err(&port->dev, "Baud rate requested not " 562 "supported by device\n"); 563 } 564 } 565 566 - /*If the number of data bits is to be updated*/ 567 if ((cflag & CSIZE) != (old_cflag & CSIZE)) { 568 - bits = cp2101_get_config(port, CP2101_BITS); 569 bits &= ~BITS_DATA_MASK; 570 switch (cflag & CSIZE) { 571 case CS6: 572 bits |= BITS_DATA_6; 573 dbg("%s - data bits = 6", __FUNCTION__); ··· 595 bits |= BITS_DATA_8; 596 break; 597 } 598 - if (cp2101_set_config(port, CP2101_BITS, bits)) 599 dev_err(&port->dev, "Number of data bits requested " 600 "not supported by device\n"); 601 } 602 603 if ((cflag & (PARENB|PARODD)) != (old_cflag & (PARENB|PARODD))) { 604 - bits = cp2101_get_config(port, CP2101_BITS); 605 bits &= ~BITS_PARITY_MASK; 606 if (cflag & PARENB) { 607 if (cflag & PARODD) { ··· 612 dbg("%s - parity = EVEN", __FUNCTION__); 613 } 614 } 615 - if (cp2101_set_config(port, CP2101_BITS, bits)) 616 dev_err(&port->dev, "Parity mode not supported " 617 "by device\n"); 618 } 619 620 if ((cflag & CSTOPB) != (old_cflag & CSTOPB)) { 621 - bits = cp2101_get_config(port, CP2101_BITS); 622 bits &= ~BITS_STOP_MASK; 623 if (cflag & CSTOPB) { 624 bits |= BITS_STOP_2; ··· 627 bits |= BITS_STOP_1; 628 dbg("%s - stop bits = 1", __FUNCTION__); 629 } 630 - if (cp2101_set_config(port, CP2101_BITS, bits)) 631 dev_err(&port->dev, "Number of stop bits requested " 632 "not supported by device\n"); 633 } 634 } 635 636 static void cp2101_break_ctl (struct usb_serial_port *port, int break_state) 637 { 638 - u16 state; 639 640 dbg("%s - port %d", __FUNCTION__, port->number); 641 if (break_state == 0) ··· 719 state = BREAK_ON; 720 dbg("%s - turning break %s", __FUNCTION__, 721 state==BREAK_OFF ? "off" : "on"); 722 - cp2101_set_config(port, CP2101_BREAK, state); 723 } 724 725 static int cp2101_startup (struct usb_serial *serial) 726 { 727 - /*CP2101 buffers behave strangely unless device is reset*/ 728 usb_reset_device(serial->dev); 729 return 0; 730 } ··· 735 736 dbg("%s", __FUNCTION__); 737 738 - /* stop reads and writes on all ports */ 739 for (i=0; i < serial->num_ports; ++i) { 740 cp2101_cleanup(serial->port[i]); 741 } ··· 747 748 retval = usb_serial_register(&cp2101_device); 749 if (retval) 750 - return retval; /*Failed to register*/ 751 752 retval = usb_register(&cp2101_driver); 753 if (retval) { 754 - /*Failed to register*/ 755 usb_serial_deregister(&cp2101_device); 756 return retval; 757 } 758 759 - /*Success*/ 760 info(DRIVER_DESC " " DRIVER_VERSION); 761 return 0; 762 }
··· 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 + * Outstanding Issues: 15 + * Buffers are not flushed when the port is opened. 16 + * Multiple calls to write() may fail with "Resource temporarily unavailable" 17 + * 18 */ 19 20 #include <linux/config.h> ··· 24 /* 25 * Version Information 26 */ 27 + #define DRIVER_VERSION "v0.04" 28 #define DRIVER_DESC "Silicon Labs CP2101/CP2102 RS232 serial adaptor driver" 29 30 /* ··· 35 static void cp2101_close(struct usb_serial_port*, struct file*); 36 static void cp2101_get_termios(struct usb_serial_port*); 37 static void cp2101_set_termios(struct usb_serial_port*, struct termios*); 38 + static int cp2101_tiocmget (struct usb_serial_port *, struct file *); 39 + static int cp2101_tiocmset (struct usb_serial_port *, struct file *, 40 + unsigned int, unsigned int); 41 static void cp2101_break_ctl(struct usb_serial_port*, int); 42 static int cp2101_startup (struct usb_serial *); 43 static void cp2101_shutdown(struct usb_serial*); ··· 43 static int debug; 44 45 static struct usb_device_id id_table [] = { 46 + { USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */ 47 + { USB_DEVICE(0x10C4, 0x80CA) }, /* Degree Controls Inc */ 48 + { USB_DEVICE(0x10AB, 0x10C5) }, /* Siemens MC60 Cable */ 49 + { } /* Terminating Entry */ 50 }; 51 52 MODULE_DEVICE_TABLE (usb, id_table); ··· 70 .close = cp2101_close, 71 .break_ctl = cp2101_break_ctl, 72 .set_termios = cp2101_set_termios, 73 + .tiocmget = cp2101_tiocmget, 74 + .tiocmset = cp2101_tiocmset, 75 .attach = cp2101_startup, 76 .shutdown = cp2101_shutdown, 77 }; 78 79 + /* Config request types */ 80 #define REQTYPE_HOST_TO_DEVICE 0x41 81 #define REQTYPE_DEVICE_TO_HOST 0xc1 82 83 + /* Config SET requests. To GET, add 1 to the request number */ 84 + #define CP2101_UART 0x00 /* Enable / Disable */ 85 + #define CP2101_BAUDRATE 0x01 /* (BAUD_RATE_GEN_FREQ / baudrate) */ 86 + #define CP2101_BITS 0x03 /* 0x(0)(databits)(parity)(stopbits) */ 87 + #define CP2101_BREAK 0x05 /* On / Off */ 88 + #define CP2101_CONTROL 0x07 /* Flow control line states */ 89 + #define CP2101_MODEMCTL 0x13 /* Modem controls */ 90 + #define CP2101_CONFIG_6 0x19 /* 6 bytes of config data ??? */ 91 92 + /* CP2101_UART */ 93 #define UART_ENABLE 0x0001 94 #define UART_DISABLE 0x0000 95 96 + /* CP2101_BAUDRATE */ 97 #define BAUD_RATE_GEN_FREQ 0x384000 98 99 + /* CP2101_BITS */ 100 #define BITS_DATA_MASK 0X0f00 101 + #define BITS_DATA_5 0X0500 102 #define BITS_DATA_6 0X0600 103 #define BITS_DATA_7 0X0700 104 #define BITS_DATA_8 0X0800 ··· 112 #define BITS_STOP_1 0x0000 113 #define BITS_STOP_1_5 0x0001 114 #define BITS_STOP_2 0x0002 115 + 116 + /* CP2101_BREAK */ 117 #define BREAK_ON 0x0000 118 #define BREAK_OFF 0x0001 119 120 + /* CP2101_CONTROL */ 121 + #define CONTROL_DTR 0x0001 122 + #define CONTROL_RTS 0x0002 123 + #define CONTROL_CTS 0x0010 124 + #define CONTROL_DSR 0x0020 125 + #define CONTROL_RING 0x0040 126 + #define CONTROL_DCD 0x0080 127 + #define CONTROL_WRITE_DTR 0x0100 128 + #define CONTROL_WRITE_RTS 0x0200 129 130 + /* 131 + * cp2101_get_config 132 + * Reads from the CP2101 configuration registers 133 + * 'size' is specified in bytes. 134 + * 'data' is a pointer to a pre-allocated array of integers large 135 + * enough to hold 'size' bytes (with 4 bytes to each integer) 136 + */ 137 + static int cp2101_get_config(struct usb_serial_port* port, u8 request, 138 + unsigned int *data, int size) 139 { 140 struct usb_serial *serial = port->serial; 141 + u32 *buf; 142 + int result, i, length; 143 144 + /* Number of integers required to contain the array */ 145 + length = (((size - 1) | 3) + 1)/4; 146 + 147 + buf = kmalloc (length * sizeof(u32), GFP_KERNEL); 148 + memset(buf, 0, length * sizeof(u32)); 149 + 150 + if (!buf) { 151 + dev_err(&port->dev, "%s - out of memory.\n", __FUNCTION__); 152 + return -ENOMEM; 153 + } 154 + 155 + /* For get requests, the request number must be incremented */ 156 request++; 157 158 + /* Issue the request, attempting to read 'size' bytes */ 159 result = usb_control_msg (serial->dev,usb_rcvctrlpipe (serial->dev, 0), 160 request, REQTYPE_DEVICE_TO_HOST, 0x0000, 161 + 0, buf, size, 300); 162 163 + /* Convert data into an array of integers */ 164 + for (i=0; i<length; i++) 165 + data[i] = le32_to_cpu(buf[i]); 166 + 167 + kfree(buf); 168 + 169 + if (result != size) { 170 dev_err(&port->dev, "%s - Unable to send config request, " 171 + "request=0x%x size=%d result=%d\n", 172 + __FUNCTION__, request, size, result); 173 + return -EPROTO; 174 } 175 176 return 0; 177 + } 178 + 179 + /* 180 + * cp2101_set_config 181 + * Writes to the CP2101 configuration registers 182 + * Values less than 16 bits wide are sent directly 183 + * 'size' is specified in bytes. 184 + */ 185 + static int cp2101_set_config(struct usb_serial_port* port, u8 request, 186 + unsigned int *data, int size) 187 + { 188 + struct usb_serial *serial = port->serial; 189 + u32 *buf; 190 + int result, i, length; 191 + 192 + /* Number of integers required to contain the array */ 193 + length = (((size - 1) | 3) + 1)/4; 194 + 195 + buf = kmalloc(length * sizeof(u32), GFP_KERNEL); 196 + if (!buf) { 197 + dev_err(&port->dev, "%s - out of memory.\n", 198 + __FUNCTION__); 199 + return -ENOMEM; 200 + } 201 + 202 + /* Array of integers into bytes */ 203 + for (i = 0; i < length; i++) 204 + buf[i] = cpu_to_le32(data[i]); 205 + 206 + if (size > 2) { 207 + result = usb_control_msg (serial->dev, 208 + usb_sndctrlpipe(serial->dev, 0), 209 + request, REQTYPE_HOST_TO_DEVICE, 0x0000, 210 + 0, buf, size, 300); 211 + } else { 212 + result = usb_control_msg (serial->dev, 213 + usb_sndctrlpipe(serial->dev, 0), 214 + request, REQTYPE_HOST_TO_DEVICE, data[0], 215 + 0, NULL, 0, 300); 216 + } 217 + 218 + kfree(buf); 219 + 220 + if ((size > 2 && result != size) || result < 0) { 221 + dev_err(&port->dev, "%s - Unable to send request, " 222 + "request=0x%x size=%d result=%d\n", 223 + __FUNCTION__, request, size, result); 224 + return -EPROTO; 225 + } 226 + 227 + /* Single data value */ 228 + result = usb_control_msg (serial->dev, 229 + usb_sndctrlpipe(serial->dev, 0), 230 + request, REQTYPE_HOST_TO_DEVICE, data[0], 231 + 0, NULL, 0, 300); 232 + return 0; 233 + } 234 + 235 + /* 236 + * cp2101_set_config_single 237 + * Convenience function for calling cp2101_set_config on single data values 238 + * without requiring an integer pointer 239 + */ 240 + static inline int cp2101_set_config_single(struct usb_serial_port* port, 241 + u8 request, unsigned int data) 242 + { 243 + return cp2101_set_config(port, request, &data, 2); 244 } 245 246 static int cp2101_open (struct usb_serial_port *port, struct file *filp) ··· 177 178 dbg("%s - port %d", __FUNCTION__, port->number); 179 180 + if (cp2101_set_config_single(port, CP2101_UART, UART_ENABLE)) { 181 dev_err(&port->dev, "%s - Unable to enable UART\n", 182 __FUNCTION__); 183 return -EPROTO; ··· 198 return result; 199 } 200 201 + /* Configure the termios structure */ 202 cp2101_get_termios(port); 203 + 204 + /* Set the DTR and RTS pins low */ 205 + cp2101_tiocmset(port, NULL, TIOCM_DTR | TIOCM_RTS, 0); 206 207 return 0; 208 } ··· 228 usb_kill_urb(port->write_urb); 229 usb_kill_urb(port->read_urb); 230 231 + cp2101_set_config_single(port, CP2101_UART, UART_DISABLE); 232 } 233 234 + /* 235 + * cp2101_get_termios 236 + * Reads the baud rate, data bits, parity, stop bits and flow control mode 237 + * from the device, corrects any unsupported values, and configures the 238 + * termios structure to reflect the state of the device 239 + */ 240 static void cp2101_get_termios (struct usb_serial_port *port) 241 { 242 + unsigned int cflag, modem_ctl[4]; 243 int baud; 244 int bits; 245 ··· 249 } 250 cflag = port->tty->termios->c_cflag; 251 252 + cp2101_get_config(port, CP2101_BAUDRATE, &baud, 2); 253 + /* Convert to baudrate */ 254 if (baud) 255 baud = BAUD_RATE_GEN_FREQ / baud; 256 257 dbg("%s - baud rate = %d", __FUNCTION__, baud); 258 cflag &= ~CBAUD; 259 switch (baud) { 260 + /* 261 + * The baud rates which are commented out below 262 * appear to be supported by the device 263 * but are non-standard 264 */ ··· 284 dbg("%s - Baud rate is not supported, " 285 "using 9600 baud", __FUNCTION__); 286 cflag |= B9600; 287 + cp2101_set_config_single(port, CP2101_BAUDRATE, 288 (BAUD_RATE_GEN_FREQ/9600)); 289 break; 290 } 291 292 + cp2101_get_config(port, CP2101_BITS, &bits, 2); 293 cflag &= ~CSIZE; 294 switch(bits & BITS_DATA_MASK) { 295 + case BITS_DATA_5: 296 + dbg("%s - data bits = 5", __FUNCTION__); 297 + cflag |= CS5; 298 + break; 299 case BITS_DATA_6: 300 dbg("%s - data bits = 6", __FUNCTION__); 301 cflag |= CS6; ··· 310 cflag |= CS8; 311 bits &= ~BITS_DATA_MASK; 312 bits |= BITS_DATA_8; 313 + cp2101_set_config(port, CP2101_BITS, &bits, 2); 314 break; 315 default: 316 dbg("%s - Unknown number of data bits, " ··· 318 cflag |= CS8; 319 bits &= ~BITS_DATA_MASK; 320 bits |= BITS_DATA_8; 321 + cp2101_set_config(port, CP2101_BITS, &bits, 2); 322 break; 323 } 324 ··· 341 "disabling parity)", __FUNCTION__); 342 cflag &= ~PARENB; 343 bits &= ~BITS_PARITY_MASK; 344 + cp2101_set_config(port, CP2101_BITS, &bits, 2); 345 break; 346 case BITS_PARITY_SPACE: 347 dbg("%s - parity = SPACE (not supported, " 348 "disabling parity)", __FUNCTION__); 349 cflag &= ~PARENB; 350 bits &= ~BITS_PARITY_MASK; 351 + cp2101_set_config(port, CP2101_BITS, &bits, 2); 352 break; 353 default: 354 dbg("%s - Unknown parity mode, " 355 "disabling parity", __FUNCTION__); 356 cflag &= ~PARENB; 357 bits &= ~BITS_PARITY_MASK; 358 + cp2101_set_config(port, CP2101_BITS, &bits, 2); 359 break; 360 } 361 ··· 366 break; 367 case BITS_STOP_1_5: 368 dbg("%s - stop bits = 1.5 (not supported, " 369 + "using 1 stop bit)", __FUNCTION__); 370 bits &= ~BITS_STOP_MASK; 371 + cp2101_set_config(port, CP2101_BITS, &bits, 2); 372 break; 373 case BITS_STOP_2: 374 dbg("%s - stop bits = 2", __FUNCTION__); ··· 378 dbg("%s - Unknown number of stop bits, " 379 "using 1 stop bit", __FUNCTION__); 380 bits &= ~BITS_STOP_MASK; 381 + cp2101_set_config(port, CP2101_BITS, &bits, 2); 382 break; 383 + } 384 + 385 + cp2101_get_config(port, CP2101_MODEMCTL, modem_ctl, 16); 386 + if (modem_ctl[0] & 0x0008) { 387 + dbg("%s - flow control = CRTSCTS", __FUNCTION__); 388 + cflag |= CRTSCTS; 389 + } else { 390 + dbg("%s - flow control = NONE", __FUNCTION__); 391 + cflag &= ~CRTSCTS; 392 } 393 394 port->tty->termios->c_cflag = cflag; ··· 389 struct termios *old_termios) 390 { 391 unsigned int cflag, old_cflag=0; 392 + int baud=0, bits; 393 + unsigned int modem_ctl[4]; 394 395 dbg("%s - port %d", __FUNCTION__, port->number); 396 ··· 400 } 401 cflag = port->tty->termios->c_cflag; 402 403 + /* Check that they really want us to change something */ 404 if (old_termios) { 405 if ((cflag == old_termios->c_cflag) && 406 (RELEVANT_IFLAG(port->tty->termios->c_iflag) ··· 415 /* If the baud rate is to be updated*/ 416 if ((cflag & CBAUD) != (old_cflag & CBAUD)) { 417 switch (cflag & CBAUD) { 418 + /* 419 + * The baud rates which are commented out below 420 * appear to be supported by the device 421 * but are non-standard 422 */ ··· 448 if (baud) { 449 dbg("%s - Setting baud rate to %d baud", __FUNCTION__, 450 baud); 451 + if (cp2101_set_config_single(port, CP2101_BAUDRATE, 452 (BAUD_RATE_GEN_FREQ / baud))) 453 dev_err(&port->dev, "Baud rate requested not " 454 "supported by device\n"); 455 } 456 } 457 458 + /* If the number of data bits is to be updated */ 459 if ((cflag & CSIZE) != (old_cflag & CSIZE)) { 460 + cp2101_get_config(port, CP2101_BITS, &bits, 2); 461 bits &= ~BITS_DATA_MASK; 462 switch (cflag & CSIZE) { 463 + case CS5: 464 + bits |= BITS_DATA_5; 465 + dbg("%s - data bits = 5", __FUNCTION__); 466 + break; 467 case CS6: 468 bits |= BITS_DATA_6; 469 dbg("%s - data bits = 6", __FUNCTION__); ··· 483 bits |= BITS_DATA_8; 484 break; 485 } 486 + if (cp2101_set_config(port, CP2101_BITS, &bits, 2)) 487 dev_err(&port->dev, "Number of data bits requested " 488 "not supported by device\n"); 489 } 490 491 if ((cflag & (PARENB|PARODD)) != (old_cflag & (PARENB|PARODD))) { 492 + cp2101_get_config(port, CP2101_BITS, &bits, 2); 493 bits &= ~BITS_PARITY_MASK; 494 if (cflag & PARENB) { 495 if (cflag & PARODD) { ··· 500 dbg("%s - parity = EVEN", __FUNCTION__); 501 } 502 } 503 + if (cp2101_set_config(port, CP2101_BITS, &bits, 2)) 504 dev_err(&port->dev, "Parity mode not supported " 505 "by device\n"); 506 } 507 508 if ((cflag & CSTOPB) != (old_cflag & CSTOPB)) { 509 + cp2101_get_config(port, CP2101_BITS, &bits, 2); 510 bits &= ~BITS_STOP_MASK; 511 if (cflag & CSTOPB) { 512 bits |= BITS_STOP_2; ··· 515 bits |= BITS_STOP_1; 516 dbg("%s - stop bits = 1", __FUNCTION__); 517 } 518 + if (cp2101_set_config(port, CP2101_BITS, &bits, 2)) 519 dev_err(&port->dev, "Number of stop bits requested " 520 "not supported by device\n"); 521 } 522 + 523 + if ((cflag & CRTSCTS) != (old_cflag & CRTSCTS)) { 524 + cp2101_get_config(port, CP2101_MODEMCTL, modem_ctl, 16); 525 + dbg("%s - read modem controls = 0x%.4x 0x%.4x 0x%.4x 0x%.4x", 526 + __FUNCTION__, modem_ctl[0], modem_ctl[1], 527 + modem_ctl[2], modem_ctl[3]); 528 + 529 + if (cflag & CRTSCTS) { 530 + modem_ctl[0] &= ~0x7B; 531 + modem_ctl[0] |= 0x09; 532 + modem_ctl[1] = 0x80; 533 + dbg("%s - flow control = CRTSCTS", __FUNCTION__); 534 + } else { 535 + modem_ctl[0] &= ~0x7B; 536 + modem_ctl[0] |= 0x01; 537 + modem_ctl[1] |= 0x40; 538 + dbg("%s - flow control = NONE", __FUNCTION__); 539 + } 540 + 541 + dbg("%s - write modem controls = 0x%.4x 0x%.4x 0x%.4x 0x%.4x", 542 + __FUNCTION__, modem_ctl[0], modem_ctl[1], 543 + modem_ctl[2], modem_ctl[3]); 544 + cp2101_set_config(port, CP2101_MODEMCTL, modem_ctl, 16); 545 + } 546 + 547 + } 548 + 549 + static int cp2101_tiocmset (struct usb_serial_port *port, struct file *file, 550 + unsigned int set, unsigned int clear) 551 + { 552 + int control = 0; 553 + 554 + dbg("%s - port %d", __FUNCTION__, port->number); 555 + 556 + if (set & TIOCM_RTS) { 557 + control |= CONTROL_RTS; 558 + control |= CONTROL_WRITE_RTS; 559 + } 560 + if (set & TIOCM_DTR) { 561 + control |= CONTROL_DTR; 562 + control |= CONTROL_WRITE_DTR; 563 + } 564 + if (clear & TIOCM_RTS) { 565 + control &= ~CONTROL_RTS; 566 + control |= CONTROL_WRITE_RTS; 567 + } 568 + if (clear & TIOCM_DTR) { 569 + control &= ~CONTROL_DTR; 570 + control |= CONTROL_WRITE_DTR; 571 + } 572 + 573 + dbg("%s - control = 0x%.4x", __FUNCTION__, control); 574 + 575 + return cp2101_set_config(port, CP2101_CONTROL, &control, 2); 576 + 577 + } 578 + 579 + static int cp2101_tiocmget (struct usb_serial_port *port, struct file *file) 580 + { 581 + int control, result; 582 + 583 + dbg("%s - port %d", __FUNCTION__, port->number); 584 + 585 + cp2101_get_config(port, CP2101_CONTROL, &control, 1); 586 + 587 + result = ((control & CONTROL_DTR) ? TIOCM_DTR : 0) 588 + |((control & CONTROL_RTS) ? TIOCM_RTS : 0) 589 + |((control & CONTROL_CTS) ? TIOCM_CTS : 0) 590 + |((control & CONTROL_DSR) ? TIOCM_DSR : 0) 591 + |((control & CONTROL_RING)? TIOCM_RI : 0) 592 + |((control & CONTROL_DCD) ? TIOCM_CD : 0); 593 + 594 + dbg("%s - control = 0x%.2x", __FUNCTION__, control); 595 + 596 + return result; 597 } 598 599 static void cp2101_break_ctl (struct usb_serial_port *port, int break_state) 600 { 601 + int state; 602 603 dbg("%s - port %d", __FUNCTION__, port->number); 604 if (break_state == 0) ··· 532 state = BREAK_ON; 533 dbg("%s - turning break %s", __FUNCTION__, 534 state==BREAK_OFF ? "off" : "on"); 535 + cp2101_set_config(port, CP2101_BREAK, &state, 2); 536 } 537 538 static int cp2101_startup (struct usb_serial *serial) 539 { 540 + /* CP2101 buffers behave strangely unless device is reset */ 541 usb_reset_device(serial->dev); 542 return 0; 543 } ··· 548 549 dbg("%s", __FUNCTION__); 550 551 + /* Stop reads and writes on all ports */ 552 for (i=0; i < serial->num_ports; ++i) { 553 cp2101_cleanup(serial->port[i]); 554 } ··· 560 561 retval = usb_serial_register(&cp2101_device); 562 if (retval) 563 + return retval; /* Failed to register */ 564 565 retval = usb_register(&cp2101_driver); 566 if (retval) { 567 + /* Failed to register */ 568 usb_serial_deregister(&cp2101_device); 569 return retval; 570 } 571 572 + /* Success */ 573 info(DRIVER_DESC " " DRIVER_VERSION); 574 return 0; 575 }