From 95fd4f47c857cf887ec0f6718ffb6a6ec3b62bd6 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Wed, 18 Jul 2018 14:24:57 +0200 Subject: [PATCH] USB: serial: cp210x: make line-speed quantisation data driven Older cp210x devices only support a fixed set of line speeds to which a requested speed is mapped. Reimplement this mapping using a table instead of a long if-else construct. Reviewed-by: Greg Kroah-Hartman Signed-off-by: Johan Hovold --- drivers/usb/serial/cp210x.c | 99 +++++++++++++++++++++++++-------------------- 1 file changed, 56 insertions(+), 43 deletions(-) diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c index eb6c26c..1b38030 100644 --- a/drivers/usb/serial/cp210x.c +++ b/drivers/usb/serial/cp210x.c @@ -752,48 +752,6 @@ static int cp210x_get_line_ctl(struct usb_serial_port *port, u16 *ctl) return 0; } -/* - * cp210x_quantise_baudrate - * Quantises the baud rate as per AN205 Table 1 - */ -static unsigned int cp210x_quantise_baudrate(unsigned int baud) -{ - if (baud <= 300) - baud = 300; - else if (baud <= 600) baud = 600; - else if (baud <= 1200) baud = 1200; - else if (baud <= 1800) baud = 1800; - else if (baud <= 2400) baud = 2400; - else if (baud <= 4000) baud = 4000; - else if (baud <= 4803) baud = 4800; - else if (baud <= 7207) baud = 7200; - else if (baud <= 9612) baud = 9600; - else if (baud <= 14428) baud = 14400; - else if (baud <= 16062) baud = 16000; - else if (baud <= 19250) baud = 19200; - else if (baud <= 28912) baud = 28800; - else if (baud <= 38601) baud = 38400; - else if (baud <= 51558) baud = 51200; - else if (baud <= 56280) baud = 56000; - else if (baud <= 58053) baud = 57600; - else if (baud <= 64111) baud = 64000; - else if (baud <= 77608) baud = 76800; - else if (baud <= 117028) baud = 115200; - else if (baud <= 129347) baud = 128000; - else if (baud <= 156868) baud = 153600; - else if (baud <= 237832) baud = 230400; - else if (baud <= 254234) baud = 250000; - else if (baud <= 273066) baud = 256000; - else if (baud <= 491520) baud = 460800; - else if (baud <= 567138) baud = 500000; - else if (baud <= 670254) baud = 576000; - else if (baud < 1000000) - baud = 921600; - else if (baud > 2000000) - baud = 2000000; - return baud; -} - static int cp210x_open(struct tty_struct *tty, struct usb_serial_port *port) { int result; @@ -1013,6 +971,58 @@ static void cp210x_get_termios_port(struct usb_serial_port *port, *cflagp = cflag; } +struct cp210x_rate { + speed_t rate; + speed_t high; +}; + +static const struct cp210x_rate cp210x_an205_table1[] = { + { 300, 300 }, + { 600, 600 }, + { 1200, 1200 }, + { 1800, 1800 }, + { 2400, 2400 }, + { 4000, 4000 }, + { 4800, 4803 }, + { 7200, 7207 }, + { 9600, 9612 }, + { 14400, 14428 }, + { 16000, 16062 }, + { 19200, 19250 }, + { 28800, 28912 }, + { 38400, 38601 }, + { 51200, 51558 }, + { 56000, 56280 }, + { 57600, 58053 }, + { 64000, 64111 }, + { 76800, 77608 }, + { 115200, 117028 }, + { 128000, 129347 }, + { 153600, 156868 }, + { 230400, 237832 }, + { 250000, 254234 }, + { 256000, 273066 }, + { 460800, 491520 }, + { 500000, 567138 }, + { 576000, 670254 }, + { 921600, UINT_MAX } +}; + +/* + * Quantises the baud rate as per AN205 Table 1 + */ +static speed_t cp210x_get_an205_rate(speed_t baud) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(cp210x_an205_table1); ++i) { + if (baud <= cp210x_an205_table1[i].high) + break; + } + + return cp210x_an205_table1[i].rate; +} + /* * CP2101 supports the following baud rates: * @@ -1051,7 +1061,10 @@ static void cp210x_change_speed(struct tty_struct *tty, * * NOTE: B0 is not implemented. */ - baud = cp210x_quantise_baudrate(baud); + if (baud < 1000000) + baud = cp210x_get_an205_rate(baud); + else if (baud > 2000000) + baud = 2000000; dev_dbg(&port->dev, "%s - setting baud rate to %u\n", __func__, baud); if (cp210x_write_u32_reg(port, CP210X_SET_BAUDRATE, baud)) { -- 2.7.4