diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/usb/serial/cp210x.c | 98 |
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 | ||
737 | static int cp2101_tiocmget (struct tty_struct *tty, struct file *file) | 751 | static 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 | ||
774 | static int cp2101_startup(struct usb_serial *serial) | 788 | static int cp2101_startup(struct usb_serial *serial) |