aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPreston Fick <preston.fick@silabs.com>2012-01-16 19:14:09 -0500
committerHerton Ronaldo Krzesinski <herton.krzesinski@canonical.com>2012-02-13 15:15:07 -0500
commitee6997bd23b360eccc58816b05932bedcf5382c1 (patch)
treebcdfcc8e6f890d8d9ca636cf0321147a87dd8e0a
parent7d2ff35feb3232acd89ec4cab7a0aa3bfbe18dc6 (diff)
USB: cp210x: fix CP2104 baudrate usage
BugLink: http://bugs.launchpad.net/bugs/926309 commit 7f482fc88ac47662228d6b1f05759797c8936a30 upstream. This fix changes the way baudrates are set on the CP210x devices from Silicon Labs. The CP2101/2/3 will respond to both a GET/SET_BAUDDIV command, and GET/SET_BAUDRATE command, while CP2104 and higher devices only respond to GET/SET_BAUDRATE. The current cp210x.ko driver in kernel version 3.2.0 only implements the GET/SET_BAUDDIV command. This patch implements the two new codes for the GET/SET_BAUDRATE commands. Then there is a change in the way that the baudrate is assigned or retrieved. This is done according to the CP210x USB specification in AN571. This document can be found here: http://www.silabs.com/pages/DownloadDoc.aspx?FILEURL=Support%20Documents/TechnicalDocs/AN571.pdf&src=DocumentationWebPart Sections 5.3/5.4 describe the USB packets for the old baudrate method. Sections 5.5/5.6 describe the USB packets for the new method. This patch also implements the new request scheme, and eliminates the unnecessary baudrate calculations since it uses the "actual baudrate" method. This patch solves the problem reported for the CP2104 in bug 42586, and also keeps support for all other devices (CP2101/2/3). This patchfile is also attached to the bug report on bugzilla.kernel.org. This patch has been developed and test on the 3.2.0 mainline kernel version under Ubuntu 10.11. Signed-off-by: Preston Fick <preston.fick@silabs.com> [duplicate patch also sent by Johan - gregkh] Signed-off-by: Johan Hovold <jhovold@gmail.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Signed-off-by: Tim Gardner <tim.gardner@canonical.com>
-rw-r--r--drivers/usb/serial/cp210x.c10
1 files changed, 4 insertions, 6 deletions
diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c
index cbcaddb1bf4..60993dc7eb8 100644
--- a/drivers/usb/serial/cp210x.c
+++ b/drivers/usb/serial/cp210x.c
@@ -202,6 +202,8 @@ static struct usb_serial_driver cp210x_device = {
202#define CP210X_EMBED_EVENTS 0x15 202#define CP210X_EMBED_EVENTS 0x15
203#define CP210X_GET_EVENTSTATE 0x16 203#define CP210X_GET_EVENTSTATE 0x16
204#define CP210X_SET_CHARS 0x19 204#define CP210X_SET_CHARS 0x19
205#define CP210X_GET_BAUDRATE 0x1D
206#define CP210X_SET_BAUDRATE 0x1E
205 207
206/* CP210X_IFC_ENABLE */ 208/* CP210X_IFC_ENABLE */
207#define UART_ENABLE 0x0001 209#define UART_ENABLE 0x0001
@@ -456,10 +458,7 @@ static void cp210x_get_termios_port(struct usb_serial_port *port,
456 458
457 dbg("%s - port %d", __func__, port->number); 459 dbg("%s - port %d", __func__, port->number);
458 460
459 cp210x_get_config(port, CP210X_GET_BAUDDIV, &baud, 2); 461 cp210x_get_config(port, CP210X_GET_BAUDRATE, &baud, 4);
460 /* Convert to baudrate */
461 if (baud)
462 baud = cp210x_quantise_baudrate((BAUD_RATE_GEN_FREQ + baud/2)/ baud);
463 462
464 dbg("%s - baud rate = %d", __func__, baud); 463 dbg("%s - baud rate = %d", __func__, baud);
465 *baudp = baud; 464 *baudp = baud;
@@ -594,8 +593,7 @@ static void cp210x_set_termios(struct tty_struct *tty,
594 if (baud != tty_termios_baud_rate(old_termios) && baud != 0) { 593 if (baud != tty_termios_baud_rate(old_termios) && baud != 0) {
595 dbg("%s - Setting baud rate to %d baud", __func__, 594 dbg("%s - Setting baud rate to %d baud", __func__,
596 baud); 595 baud);
597 if (cp210x_set_config_single(port, CP210X_SET_BAUDDIV, 596 if (cp210x_set_config(port, CP210X_SET_BAUDRATE, &baud, 4)) {
598 ((BAUD_RATE_GEN_FREQ + baud/2) / baud))) {
599 dbg("Baud rate requested not supported by device"); 597 dbg("Baud rate requested not supported by device");
600 baud = tty_termios_baud_rate(old_termios); 598 baud = tty_termios_baud_rate(old_termios);
601 } 599 }