diff options
author | Craig Shelley <craig@microtron.org.uk> | 2009-02-26 17:19:22 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2009-03-24 19:20:44 -0400 |
commit | ef8b6bcb39559d956f897acf7ebe600d5105d479 (patch) | |
tree | 2d5f13e77ac265aa98d510173aa70695184c6fb3 /drivers/usb | |
parent | 31dbb803464d75b96212cce9052dfeaeac0819de (diff) |
USB: CP2101 Support AN205 baud rates
This patch adds support for the extended range of baud rates supported
by CP2102 and CP2103 devices described in SiLabs AN205. An additional
function cp2101_quantise_baudrate rounds the baud rate as per AN205
Table 1. A modification to the baud rate calculation removes a rounding
error, allowing the full range of baud rates to be used.
Signed-off-by: Craig Shelley <craig@microtron.org.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb')
-rw-r--r-- | drivers/usb/serial/cp2101.c | 92 |
1 files changed, 52 insertions, 40 deletions
diff --git a/drivers/usb/serial/cp2101.c b/drivers/usb/serial/cp2101.c index 9b4082b58c5b..9b56e35aee4d 100644 --- a/drivers/usb/serial/cp2101.c +++ b/drivers/usb/serial/cp2101.c | |||
@@ -31,7 +31,7 @@ | |||
31 | /* | 31 | /* |
32 | * Version Information | 32 | * Version Information |
33 | */ | 33 | */ |
34 | #define DRIVER_VERSION "v0.07" | 34 | #define DRIVER_VERSION "v0.08" |
35 | #define DRIVER_DESC "Silicon Labs CP2101/CP2102 RS232 serial adaptor driver" | 35 | #define DRIVER_DESC "Silicon Labs CP2101/CP2102 RS232 serial adaptor driver" |
36 | 36 | ||
37 | /* | 37 | /* |
@@ -301,6 +301,47 @@ static inline int cp2101_set_config_single(struct usb_serial_port *port, | |||
301 | return cp2101_set_config(port, request, &data, 2); | 301 | return cp2101_set_config(port, request, &data, 2); |
302 | } | 302 | } |
303 | 303 | ||
304 | /* | ||
305 | * cp2101_quantise_baudrate | ||
306 | * Quantises the baud rate as per AN205 Table 1 | ||
307 | */ | ||
308 | static unsigned int cp2101_quantise_baudrate(unsigned int baud) { | ||
309 | if (baud <= 56) baud = 0; | ||
310 | else if (baud <= 300) baud = 300; | ||
311 | else if (baud <= 600) baud = 600; | ||
312 | else if (baud <= 1200) baud = 1200; | ||
313 | else if (baud <= 1800) baud = 1800; | ||
314 | else if (baud <= 2400) baud = 2400; | ||
315 | else if (baud <= 4000) baud = 4000; | ||
316 | else if (baud <= 4803) baud = 4800; | ||
317 | else if (baud <= 7207) baud = 7200; | ||
318 | else if (baud <= 9612) baud = 9600; | ||
319 | else if (baud <= 14428) baud = 14400; | ||
320 | else if (baud <= 16062) baud = 16000; | ||
321 | else if (baud <= 19250) baud = 19200; | ||
322 | else if (baud <= 28912) baud = 28800; | ||
323 | else if (baud <= 38601) baud = 38400; | ||
324 | else if (baud <= 51558) baud = 51200; | ||
325 | else if (baud <= 56280) baud = 56000; | ||
326 | else if (baud <= 58053) baud = 57600; | ||
327 | else if (baud <= 64111) baud = 64000; | ||
328 | else if (baud <= 77608) baud = 76800; | ||
329 | else if (baud <= 117028) baud = 115200; | ||
330 | else if (baud <= 129347) baud = 128000; | ||
331 | else if (baud <= 156868) baud = 153600; | ||
332 | else if (baud <= 237832) baud = 230400; | ||
333 | else if (baud <= 254234) baud = 250000; | ||
334 | else if (baud <= 273066) baud = 256000; | ||
335 | else if (baud <= 491520) baud = 460800; | ||
336 | else if (baud <= 567138) baud = 500000; | ||
337 | else if (baud <= 670254) baud = 576000; | ||
338 | else if (baud <= 1053257) baud = 921600; | ||
339 | else if (baud <= 1474560) baud = 1228800; | ||
340 | else if (baud <= 2457600) baud = 1843200; | ||
341 | else baud = 3686400; | ||
342 | return baud; | ||
343 | } | ||
344 | |||
304 | static int cp2101_open(struct tty_struct *tty, struct usb_serial_port *port, | 345 | static int cp2101_open(struct tty_struct *tty, struct usb_serial_port *port, |
305 | struct file *filp) | 346 | struct file *filp) |
306 | { | 347 | { |
@@ -388,7 +429,7 @@ static void cp2101_get_termios (struct tty_struct *tty) | |||
388 | cp2101_get_config(port, CP2101_BAUDRATE, &baud, 2); | 429 | cp2101_get_config(port, CP2101_BAUDRATE, &baud, 2); |
389 | /* Convert to baudrate */ | 430 | /* Convert to baudrate */ |
390 | if (baud) | 431 | if (baud) |
391 | baud = BAUD_RATE_GEN_FREQ / baud; | 432 | baud = cp2101_quantise_baudrate((BAUD_RATE_GEN_FREQ + baud/2)/ baud); |
392 | 433 | ||
393 | dbg("%s - baud rate = %d", __func__, baud); | 434 | dbg("%s - baud rate = %d", __func__, baud); |
394 | 435 | ||
@@ -517,46 +558,17 @@ static void cp2101_set_termios(struct tty_struct *tty, | |||
517 | tty->termios->c_cflag &= ~CMSPAR; | 558 | tty->termios->c_cflag &= ~CMSPAR; |
518 | cflag = tty->termios->c_cflag; | 559 | cflag = tty->termios->c_cflag; |
519 | old_cflag = old_termios->c_cflag; | 560 | old_cflag = old_termios->c_cflag; |
520 | baud = tty_get_baud_rate(tty); | 561 | baud = cp2101_quantise_baudrate(tty_get_baud_rate(tty)); |
521 | 562 | ||
522 | /* If the baud rate is to be updated*/ | 563 | /* If the baud rate is to be updated*/ |
523 | if (baud != tty_termios_baud_rate(old_termios)) { | 564 | if (baud != tty_termios_baud_rate(old_termios) && baud != 0) { |
524 | switch (baud) { | 565 | dbg("%s - Setting baud rate to %d baud", __func__, |
525 | case 0: | 566 | baud); |
526 | case 600: | 567 | if (cp2101_set_config_single(port, CP2101_BAUDRATE, |
527 | case 1200: | 568 | ((BAUD_RATE_GEN_FREQ + baud/2) / baud))) { |
528 | case 1800: | 569 | dev_err(&port->dev, "Baud rate requested not " |
529 | case 2400: | 570 | "supported by device\n"); |
530 | case 4800: | 571 | baud = tty_termios_baud_rate(old_termios); |
531 | case 7200: | ||
532 | case 9600: | ||
533 | case 14400: | ||
534 | case 19200: | ||
535 | case 28800: | ||
536 | case 38400: | ||
537 | case 55854: | ||
538 | case 57600: | ||
539 | case 115200: | ||
540 | case 127117: | ||
541 | case 230400: | ||
542 | case 460800: | ||
543 | case 921600: | ||
544 | case 3686400: | ||
545 | break; | ||
546 | default: | ||
547 | baud = 9600; | ||
548 | break; | ||
549 | } | ||
550 | |||
551 | if (baud) { | ||
552 | dbg("%s - Setting baud rate to %d baud", __func__, | ||
553 | baud); | ||
554 | if (cp2101_set_config_single(port, CP2101_BAUDRATE, | ||
555 | (BAUD_RATE_GEN_FREQ / baud))) { | ||
556 | dev_err(&port->dev, "Baud rate requested not " | ||
557 | "supported by device\n"); | ||
558 | baud = tty_termios_baud_rate(old_termios); | ||
559 | } | ||
560 | } | 572 | } |
561 | } | 573 | } |
562 | /* Report back the resulting baud rate */ | 574 | /* Report back the resulting baud rate */ |