aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/usb/serial/cp210x.c98
1 files changed, 56 insertions, 42 deletions
diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c
index ac4944a81521..b50f27fa11d0 100644
--- a/drivers/usb/serial/cp210x.c
+++ b/drivers/usb/serial/cp210x.c
@@ -27,7 +27,7 @@
27/* 27/*
28 * Version Information 28 * Version Information
29 */ 29 */
30#define DRIVER_VERSION "v0.08" 30#define DRIVER_VERSION "v0.09"
31#define DRIVER_DESC "Silicon Labs CP2101/CP2102 RS232 serial adaptor driver" 31#define DRIVER_DESC "Silicon Labs CP2101/CP2102 RS232 serial adaptor driver"
32 32
33/* 33/*
@@ -144,23 +144,40 @@ static struct usb_serial_driver cp2101_device = {
144#define REQTYPE_HOST_TO_DEVICE 0x41 144#define REQTYPE_HOST_TO_DEVICE 0x41
145#define REQTYPE_DEVICE_TO_HOST 0xc1 145#define REQTYPE_DEVICE_TO_HOST 0xc1
146 146
147/* Config SET requests. To GET, add 1 to the request number */ 147/* Config request codes */
148#define CP2101_UART 0x00 /* Enable / Disable */ 148#define CP210X_IFC_ENABLE 0x00
149#define CP2101_BAUDRATE 0x01 /* (BAUD_RATE_GEN_FREQ / baudrate) */ 149#define CP210X_SET_BAUDDIV 0x01
150#define CP2101_BITS 0x03 /* 0x(0)(databits)(parity)(stopbits) */ 150#define CP210X_GET_BAUDDIV 0x02
151#define CP2101_BREAK 0x05 /* On / Off */ 151#define CP210X_SET_LINE_CTL 0x03
152#define CP2101_CONTROL 0x07 /* Flow control line states */ 152#define CP210X_GET_LINE_CTL 0x04
153#define CP2101_MODEMCTL 0x13 /* Modem controls */ 153#define CP210X_SET_BREAK 0x05
154#define CP2101_CONFIG_6 0x19 /* 6 bytes of config data ??? */ 154#define CP210X_IMM_CHAR 0x06
155 155#define CP210X_SET_MHS 0x07
156/* CP2101_UART */ 156#define CP210X_GET_MDMSTS 0x08
157#define CP210X_SET_XON 0x09
158#define CP210X_SET_XOFF 0x0A
159#define CP210X_SET_EVENTMASK 0x0B
160#define CP210X_GET_EVENTMASK 0x0C
161#define CP210X_SET_CHAR 0x0D
162#define CP210X_GET_CHARS 0x0E
163#define CP210X_GET_PROPS 0x0F
164#define CP210X_GET_COMM_STATUS 0x10
165#define CP210X_RESET 0x11
166#define CP210X_PURGE 0x12
167#define CP210X_SET_FLOW 0x13
168#define CP210X_GET_FLOW 0x14
169#define CP210X_EMBED_EVENTS 0x15
170#define CP210X_GET_EVENTSTATE 0x16
171#define CP210X_SET_CHARS 0x19
172
173/* CP210X_IFC_ENABLE */
157#define UART_ENABLE 0x0001 174#define UART_ENABLE 0x0001
158#define UART_DISABLE 0x0000 175#define UART_DISABLE 0x0000
159 176
160/* CP2101_BAUDRATE */ 177/* CP210X_(SET|GET)_BAUDDIV */
161#define BAUD_RATE_GEN_FREQ 0x384000 178#define BAUD_RATE_GEN_FREQ 0x384000
162 179
163/* CP2101_BITS */ 180/* CP210X_(SET|GET)_LINE_CTL */
164#define BITS_DATA_MASK 0X0f00 181#define BITS_DATA_MASK 0X0f00
165#define BITS_DATA_5 0X0500 182#define BITS_DATA_5 0X0500
166#define BITS_DATA_6 0X0600 183#define BITS_DATA_6 0X0600
@@ -180,11 +197,11 @@ static struct usb_serial_driver cp2101_device = {
180#define BITS_STOP_1_5 0x0001 197#define BITS_STOP_1_5 0x0001
181#define BITS_STOP_2 0x0002 198#define BITS_STOP_2 0x0002
182 199
183/* CP2101_BREAK */ 200/* CP210X_SET_BREAK */
184#define BREAK_ON 0x0000 201#define BREAK_ON 0x0000
185#define BREAK_OFF 0x0001 202#define BREAK_OFF 0x0001
186 203
187/* CP2101_CONTROL */ 204/* CP210X_(SET_MHS|GET_MDMSTS) */
188#define CONTROL_DTR 0x0001 205#define CONTROL_DTR 0x0001
189#define CONTROL_RTS 0x0002 206#define CONTROL_RTS 0x0002
190#define CONTROL_CTS 0x0010 207#define CONTROL_CTS 0x0010
@@ -217,9 +234,6 @@ static int cp2101_get_config(struct usb_serial_port *port, u8 request,
217 return -ENOMEM; 234 return -ENOMEM;
218 } 235 }
219 236
220 /* For get requests, the request number must be incremented */
221 request++;
222
223 /* Issue the request, attempting to read 'size' bytes */ 237 /* Issue the request, attempting to read 'size' bytes */
224 result = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0), 238 result = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
225 request, REQTYPE_DEVICE_TO_HOST, 0x0000, 239 request, REQTYPE_DEVICE_TO_HOST, 0x0000,
@@ -357,7 +371,7 @@ static int cp2101_open(struct tty_struct *tty, struct usb_serial_port *port,
357 371
358 dbg("%s - port %d", __func__, port->number); 372 dbg("%s - port %d", __func__, port->number);
359 373
360 if (cp2101_set_config_single(port, CP2101_UART, UART_ENABLE)) { 374 if (cp2101_set_config_single(port, CP210X_IFC_ENABLE, UART_ENABLE)) {
361 dev_err(&port->dev, "%s - Unable to enable UART\n", 375 dev_err(&port->dev, "%s - Unable to enable UART\n",
362 __func__); 376 __func__);
363 return -EPROTO; 377 return -EPROTO;
@@ -415,7 +429,7 @@ static void cp2101_close(struct usb_serial_port *port)
415 429
416 mutex_lock(&port->serial->disc_mutex); 430 mutex_lock(&port->serial->disc_mutex);
417 if (!port->serial->disconnected) 431 if (!port->serial->disconnected)
418 cp2101_set_config_single(port, CP2101_UART, UART_DISABLE); 432 cp2101_set_config_single(port, CP210X_IFC_ENABLE, UART_DISABLE);
419 mutex_unlock(&port->serial->disc_mutex); 433 mutex_unlock(&port->serial->disc_mutex);
420} 434}
421 435
@@ -456,7 +470,7 @@ static void cp2101_get_termios_port(struct usb_serial_port *port,
456 470
457 dbg("%s - port %d", __func__, port->number); 471 dbg("%s - port %d", __func__, port->number);
458 472
459 cp2101_get_config(port, CP2101_BAUDRATE, &baud, 2); 473 cp2101_get_config(port, CP210X_GET_BAUDDIV, &baud, 2);
460 /* Convert to baudrate */ 474 /* Convert to baudrate */
461 if (baud) 475 if (baud)
462 baud = cp2101_quantise_baudrate((BAUD_RATE_GEN_FREQ + baud/2)/ baud); 476 baud = cp2101_quantise_baudrate((BAUD_RATE_GEN_FREQ + baud/2)/ baud);
@@ -466,7 +480,7 @@ static void cp2101_get_termios_port(struct usb_serial_port *port,
466 480
467 cflag = *cflagp; 481 cflag = *cflagp;
468 482
469 cp2101_get_config(port, CP2101_BITS, &bits, 2); 483 cp2101_get_config(port, CP210X_GET_LINE_CTL, &bits, 2);
470 cflag &= ~CSIZE; 484 cflag &= ~CSIZE;
471 switch (bits & BITS_DATA_MASK) { 485 switch (bits & BITS_DATA_MASK) {
472 case BITS_DATA_5: 486 case BITS_DATA_5:
@@ -491,14 +505,14 @@ static void cp2101_get_termios_port(struct usb_serial_port *port,
491 cflag |= CS8; 505 cflag |= CS8;
492 bits &= ~BITS_DATA_MASK; 506 bits &= ~BITS_DATA_MASK;
493 bits |= BITS_DATA_8; 507 bits |= BITS_DATA_8;
494 cp2101_set_config(port, CP2101_BITS, &bits, 2); 508 cp2101_set_config(port, CP210X_SET_LINE_CTL, &bits, 2);
495 break; 509 break;
496 default: 510 default:
497 dbg("%s - Unknown number of data bits, using 8", __func__); 511 dbg("%s - Unknown number of data bits, using 8", __func__);
498 cflag |= CS8; 512 cflag |= CS8;
499 bits &= ~BITS_DATA_MASK; 513 bits &= ~BITS_DATA_MASK;
500 bits |= BITS_DATA_8; 514 bits |= BITS_DATA_8;
501 cp2101_set_config(port, CP2101_BITS, &bits, 2); 515 cp2101_set_config(port, CP210X_SET_LINE_CTL, &bits, 2);
502 break; 516 break;
503 } 517 }
504 518
@@ -521,20 +535,20 @@ static void cp2101_get_termios_port(struct usb_serial_port *port,
521 __func__); 535 __func__);
522 cflag &= ~PARENB; 536 cflag &= ~PARENB;
523 bits &= ~BITS_PARITY_MASK; 537 bits &= ~BITS_PARITY_MASK;
524 cp2101_set_config(port, CP2101_BITS, &bits, 2); 538 cp2101_set_config(port, CP210X_SET_LINE_CTL, &bits, 2);
525 break; 539 break;
526 case BITS_PARITY_SPACE: 540 case BITS_PARITY_SPACE:
527 dbg("%s - parity = SPACE (not supported, disabling parity)", 541 dbg("%s - parity = SPACE (not supported, disabling parity)",
528 __func__); 542 __func__);
529 cflag &= ~PARENB; 543 cflag &= ~PARENB;
530 bits &= ~BITS_PARITY_MASK; 544 bits &= ~BITS_PARITY_MASK;
531 cp2101_set_config(port, CP2101_BITS, &bits, 2); 545 cp2101_set_config(port, CP210X_SET_LINE_CTL, &bits, 2);
532 break; 546 break;
533 default: 547 default:
534 dbg("%s - Unknown parity mode, disabling parity", __func__); 548 dbg("%s - Unknown parity mode, disabling parity", __func__);
535 cflag &= ~PARENB; 549 cflag &= ~PARENB;
536 bits &= ~BITS_PARITY_MASK; 550 bits &= ~BITS_PARITY_MASK;
537 cp2101_set_config(port, CP2101_BITS, &bits, 2); 551 cp2101_set_config(port, CP210X_SET_LINE_CTL, &bits, 2);
538 break; 552 break;
539 } 553 }
540 554
@@ -547,7 +561,7 @@ static void cp2101_get_termios_port(struct usb_serial_port *port,
547 dbg("%s - stop bits = 1.5 (not supported, using 1 stop bit)", 561 dbg("%s - stop bits = 1.5 (not supported, using 1 stop bit)",
548 __func__); 562 __func__);
549 bits &= ~BITS_STOP_MASK; 563 bits &= ~BITS_STOP_MASK;
550 cp2101_set_config(port, CP2101_BITS, &bits, 2); 564 cp2101_set_config(port, CP210X_SET_LINE_CTL, &bits, 2);
551 break; 565 break;
552 case BITS_STOP_2: 566 case BITS_STOP_2:
553 dbg("%s - stop bits = 2", __func__); 567 dbg("%s - stop bits = 2", __func__);
@@ -557,11 +571,11 @@ static void cp2101_get_termios_port(struct usb_serial_port *port,
557 dbg("%s - Unknown number of stop bits, using 1 stop bit", 571 dbg("%s - Unknown number of stop bits, using 1 stop bit",
558 __func__); 572 __func__);
559 bits &= ~BITS_STOP_MASK; 573 bits &= ~BITS_STOP_MASK;
560 cp2101_set_config(port, CP2101_BITS, &bits, 2); 574 cp2101_set_config(port, CP210X_SET_LINE_CTL, &bits, 2);
561 break; 575 break;
562 } 576 }
563 577
564 cp2101_get_config(port, CP2101_MODEMCTL, modem_ctl, 16); 578 cp2101_get_config(port, CP210X_GET_FLOW, modem_ctl, 16);
565 if (modem_ctl[0] & 0x0008) { 579 if (modem_ctl[0] & 0x0008) {
566 dbg("%s - flow control = CRTSCTS", __func__); 580 dbg("%s - flow control = CRTSCTS", __func__);
567 cflag |= CRTSCTS; 581 cflag |= CRTSCTS;
@@ -594,7 +608,7 @@ static void cp2101_set_termios(struct tty_struct *tty,
594 if (baud != tty_termios_baud_rate(old_termios) && baud != 0) { 608 if (baud != tty_termios_baud_rate(old_termios) && baud != 0) {
595 dbg("%s - Setting baud rate to %d baud", __func__, 609 dbg("%s - Setting baud rate to %d baud", __func__,
596 baud); 610 baud);
597 if (cp2101_set_config_single(port, CP2101_BAUDRATE, 611 if (cp2101_set_config_single(port, CP210X_SET_BAUDDIV,
598 ((BAUD_RATE_GEN_FREQ + baud/2) / baud))) { 612 ((BAUD_RATE_GEN_FREQ + baud/2) / baud))) {
599 dbg("Baud rate requested not supported by device\n"); 613 dbg("Baud rate requested not supported by device\n");
600 baud = tty_termios_baud_rate(old_termios); 614 baud = tty_termios_baud_rate(old_termios);
@@ -605,7 +619,7 @@ static void cp2101_set_termios(struct tty_struct *tty,
605 619
606 /* If the number of data bits is to be updated */ 620 /* If the number of data bits is to be updated */
607 if ((cflag & CSIZE) != (old_cflag & CSIZE)) { 621 if ((cflag & CSIZE) != (old_cflag & CSIZE)) {
608 cp2101_get_config(port, CP2101_BITS, &bits, 2); 622 cp2101_get_config(port, CP210X_GET_LINE_CTL, &bits, 2);
609 bits &= ~BITS_DATA_MASK; 623 bits &= ~BITS_DATA_MASK;
610 switch (cflag & CSIZE) { 624 switch (cflag & CSIZE) {
611 case CS5: 625 case CS5:
@@ -635,13 +649,13 @@ static void cp2101_set_termios(struct tty_struct *tty,
635 bits |= BITS_DATA_8; 649 bits |= BITS_DATA_8;
636 break; 650 break;
637 } 651 }
638 if (cp2101_set_config(port, CP2101_BITS, &bits, 2)) 652 if (cp2101_set_config(port, CP210X_SET_LINE_CTL, &bits, 2))
639 dbg("Number of data bits requested " 653 dbg("Number of data bits requested "
640 "not supported by device\n"); 654 "not supported by device\n");
641 } 655 }
642 656
643 if ((cflag & (PARENB|PARODD)) != (old_cflag & (PARENB|PARODD))) { 657 if ((cflag & (PARENB|PARODD)) != (old_cflag & (PARENB|PARODD))) {
644 cp2101_get_config(port, CP2101_BITS, &bits, 2); 658 cp2101_get_config(port, CP210X_GET_LINE_CTL, &bits, 2);
645 bits &= ~BITS_PARITY_MASK; 659 bits &= ~BITS_PARITY_MASK;
646 if (cflag & PARENB) { 660 if (cflag & PARENB) {
647 if (cflag & PARODD) { 661 if (cflag & PARODD) {
@@ -652,13 +666,13 @@ static void cp2101_set_termios(struct tty_struct *tty,
652 dbg("%s - parity = EVEN", __func__); 666 dbg("%s - parity = EVEN", __func__);
653 } 667 }
654 } 668 }
655 if (cp2101_set_config(port, CP2101_BITS, &bits, 2)) 669 if (cp2101_set_config(port, CP210X_SET_LINE_CTL, &bits, 2))
656 dbg("Parity mode not supported " 670 dbg("Parity mode not supported "
657 "by device\n"); 671 "by device\n");
658 } 672 }
659 673
660 if ((cflag & CSTOPB) != (old_cflag & CSTOPB)) { 674 if ((cflag & CSTOPB) != (old_cflag & CSTOPB)) {
661 cp2101_get_config(port, CP2101_BITS, &bits, 2); 675 cp2101_get_config(port, CP210X_GET_LINE_CTL, &bits, 2);
662 bits &= ~BITS_STOP_MASK; 676 bits &= ~BITS_STOP_MASK;
663 if (cflag & CSTOPB) { 677 if (cflag & CSTOPB) {
664 bits |= BITS_STOP_2; 678 bits |= BITS_STOP_2;
@@ -667,13 +681,13 @@ static void cp2101_set_termios(struct tty_struct *tty,
667 bits |= BITS_STOP_1; 681 bits |= BITS_STOP_1;
668 dbg("%s - stop bits = 1", __func__); 682 dbg("%s - stop bits = 1", __func__);
669 } 683 }
670 if (cp2101_set_config(port, CP2101_BITS, &bits, 2)) 684 if (cp2101_set_config(port, CP210X_SET_LINE_CTL, &bits, 2))
671 dbg("Number of stop bits requested " 685 dbg("Number of stop bits requested "
672 "not supported by device\n"); 686 "not supported by device\n");
673 } 687 }
674 688
675 if ((cflag & CRTSCTS) != (old_cflag & CRTSCTS)) { 689 if ((cflag & CRTSCTS) != (old_cflag & CRTSCTS)) {
676 cp2101_get_config(port, CP2101_MODEMCTL, modem_ctl, 16); 690 cp2101_get_config(port, CP210X_GET_FLOW, modem_ctl, 16);
677 dbg("%s - read modem controls = 0x%.4x 0x%.4x 0x%.4x 0x%.4x", 691 dbg("%s - read modem controls = 0x%.4x 0x%.4x 0x%.4x 0x%.4x",
678 __func__, modem_ctl[0], modem_ctl[1], 692 __func__, modem_ctl[0], modem_ctl[1],
679 modem_ctl[2], modem_ctl[3]); 693 modem_ctl[2], modem_ctl[3]);
@@ -693,7 +707,7 @@ static void cp2101_set_termios(struct tty_struct *tty,
693 dbg("%s - write modem controls = 0x%.4x 0x%.4x 0x%.4x 0x%.4x", 707 dbg("%s - write modem controls = 0x%.4x 0x%.4x 0x%.4x 0x%.4x",
694 __func__, modem_ctl[0], modem_ctl[1], 708 __func__, modem_ctl[0], modem_ctl[1],
695 modem_ctl[2], modem_ctl[3]); 709 modem_ctl[2], modem_ctl[3]);
696 cp2101_set_config(port, CP2101_MODEMCTL, modem_ctl, 16); 710 cp2101_set_config(port, CP210X_SET_FLOW, modem_ctl, 16);
697 } 711 }
698 712
699} 713}
@@ -731,7 +745,7 @@ static int cp2101_tiocmset_port(struct usb_serial_port *port, struct file *file,
731 745
732 dbg("%s - control = 0x%.4x", __func__, control); 746 dbg("%s - control = 0x%.4x", __func__, control);
733 747
734 return cp2101_set_config(port, CP2101_CONTROL, &control, 2); 748 return cp2101_set_config(port, CP210X_SET_MHS, &control, 2);
735} 749}
736 750
737static int cp2101_tiocmget (struct tty_struct *tty, struct file *file) 751static int cp2101_tiocmget (struct tty_struct *tty, struct file *file)
@@ -742,7 +756,7 @@ static int cp2101_tiocmget (struct tty_struct *tty, struct file *file)
742 756
743 dbg("%s - port %d", __func__, port->number); 757 dbg("%s - port %d", __func__, port->number);
744 758
745 cp2101_get_config(port, CP2101_CONTROL, &control, 1); 759 cp2101_get_config(port, CP210X_GET_MDMSTS, &control, 1);
746 760
747 result = ((control & CONTROL_DTR) ? TIOCM_DTR : 0) 761 result = ((control & CONTROL_DTR) ? TIOCM_DTR : 0)
748 |((control & CONTROL_RTS) ? TIOCM_RTS : 0) 762 |((control & CONTROL_RTS) ? TIOCM_RTS : 0)
@@ -768,7 +782,7 @@ static void cp2101_break_ctl (struct tty_struct *tty, int break_state)
768 state = BREAK_ON; 782 state = BREAK_ON;
769 dbg("%s - turning break %s", __func__, 783 dbg("%s - turning break %s", __func__,
770 state == BREAK_OFF ? "off" : "on"); 784 state == BREAK_OFF ? "off" : "on");
771 cp2101_set_config(port, CP2101_BREAK, &state, 2); 785 cp2101_set_config(port, CP210X_SET_BREAK, &state, 2);
772} 786}
773 787
774static int cp2101_startup(struct usb_serial *serial) 788static int cp2101_startup(struct usb_serial *serial)