summaryrefslogtreecommitdiffstats
path: root/drivers/usb/serial
diff options
context:
space:
mode:
authorJohan Hovold <johan@kernel.org>2018-07-18 14:24:57 +0200
committerJohan Hovold <johan@kernel.org>2018-07-18 21:53:31 +0200
commit95fd4f47c857cf887ec0f6718ffb6a6ec3b62bd6 (patch)
treea49ce24e3b843100421907531aa40d67a42465c6 /drivers/usb/serial
parentUSB: serial: iuu_phoenix: drop redundant input-speed re-encoding (diff)
downloadlinux-95fd4f47c857cf887ec0f6718ffb6a6ec3b62bd6.tar.xz
linux-95fd4f47c857cf887ec0f6718ffb6a6ec3b62bd6.zip
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 <gregkh@linuxfoundation.org> Signed-off-by: Johan Hovold <johan@kernel.org>
Diffstat (limited to 'drivers/usb/serial')
-rw-r--r--drivers/usb/serial/cp210x.c99
1 files changed, 56 insertions, 43 deletions
diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c
index eb6c26cbe579..1b380309f653 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)) {