aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/serial/cp210x.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/serial/cp210x.c')
-rw-r--r--drivers/usb/serial/cp210x.c41
1 files changed, 38 insertions, 3 deletions
diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c
index 1b380309f653..4281f2bfe0e1 100644
--- a/drivers/usb/serial/cp210x.c
+++ b/drivers/usb/serial/cp210x.c
@@ -229,6 +229,7 @@ struct cp210x_serial_private {
bool gpio_registered;
#endif
u8 partnum;
+ speed_t max_speed;
};
struct cp210x_port_private {
@@ -1052,19 +1053,20 @@ static speed_t cp210x_get_an205_rate(speed_t baud)
static void cp210x_change_speed(struct tty_struct *tty,
struct usb_serial_port *port, struct ktermios *old_termios)
{
+ struct cp210x_serial_private *priv = usb_get_serial_data(port->serial);
u32 baud;
baud = tty->termios.c_ospeed;
/* This maps the requested rate to a rate valid on cp2102 or cp2103,
- * or to an arbitrary rate in [1M,2M].
+ * or to an arbitrary rate in [1M, max_speed]
*
* NOTE: B0 is not implemented.
*/
if (baud < 1000000)
baud = cp210x_get_an205_rate(baud);
- else if (baud > 2000000)
- baud = 2000000;
+ else if (baud > priv->max_speed)
+ baud = priv->max_speed;
dev_dbg(&port->dev, "%s - setting baud rate to %u\n", __func__, baud);
if (cp210x_write_u32_reg(port, CP210X_SET_BAUDRATE, baud)) {
@@ -1495,6 +1497,37 @@ static int cp210x_port_remove(struct usb_serial_port *port)
return 0;
}
+static void cp210x_init_max_speed(struct usb_serial *serial)
+{
+ struct cp210x_serial_private *priv = usb_get_serial_data(serial);
+ speed_t max;
+
+ switch (priv->partnum) {
+ case CP210X_PARTNUM_CP2101:
+ max = 921600;
+ break;
+ case CP210X_PARTNUM_CP2102:
+ case CP210X_PARTNUM_CP2103:
+ max = 1000000;
+ break;
+ case CP210X_PARTNUM_CP2104:
+ case CP210X_PARTNUM_CP2108:
+ max = 2000000;
+ break;
+ case CP210X_PARTNUM_CP2105:
+ if (cp210x_interface_num(serial) == 0)
+ max = 2000000; /* ECI */
+ else
+ max = 921600; /* SCI */
+ break;
+ default:
+ max = 2000000;
+ break;
+ }
+
+ priv->max_speed = max;
+}
+
static int cp210x_attach(struct usb_serial *serial)
{
int result;
@@ -1515,6 +1548,8 @@ static int cp210x_attach(struct usb_serial *serial)
usb_set_serial_data(serial, priv);
+ cp210x_init_max_speed(serial);
+
if (priv->partnum == CP210X_PARTNUM_CP2105) {
result = cp2105_shared_gpio_init(serial);
if (result < 0) {