aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/serial
diff options
context:
space:
mode:
authorCraig Shelley <craig@microtron.org.uk>2009-06-11 08:53:30 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-06-11 11:51:05 -0400
commit93ef1f1fbce37f14666e4856ff933d4a1b735d02 (patch)
tree531852178ffbfd2b3a6756778c8624ee0334364a /drivers/usb/serial
parentb7c7cbc898e8a97829f33ad3bcd1b5e91690d8f4 (diff)
USB: CP210X Use official request code definitions
The CP210X driver was developed without official device specifications. This has lead to an incorrect assumption that all GET request codes are equal to the corresponding SET request code +1. This patch removes this incorrect assumption, and uses request code definitions based on the updated GPL driver from SiLabs. This modification is needed before extended functionality such as GPIO on CP2103 can be supported. Signed-off-by: Craig Shelley <craig@microtron.org.uk> Signed-off-by: Alan Cox <alan@linux.intel.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/usb/serial')
-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)