aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/serial/ch341.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/serial/ch341.c')
-rw-r--r--drivers/usb/serial/ch341.c15
1 files changed, 13 insertions, 2 deletions
diff --git a/drivers/usb/serial/ch341.c b/drivers/usb/serial/ch341.c
index f06a09e59d8b..f37bde88eb5d 100644
--- a/drivers/usb/serial/ch341.c
+++ b/drivers/usb/serial/ch341.c
@@ -96,7 +96,9 @@ struct ch341_private {
u8 mcr;
u8 msr;
u8 lcr;
+
unsigned long quirks;
+ u8 version;
};
static void ch341_set_termios(struct tty_struct *tty,
@@ -175,13 +177,20 @@ static int ch341_set_baudrate_lcr(struct usb_device *dev,
/*
* CH341A buffers data until a full endpoint-size packet (32 bytes)
* has been received unless bit 7 is set.
+ *
+ * At least one device with version 0x27 appears to have this bit
+ * inverted.
*/
- a |= BIT(7);
+ if (priv->version > 0x27)
+ a |= BIT(7);
r = ch341_control_out(dev, CH341_REQ_WRITE_REG, 0x1312, a);
if (r)
return r;
+ if (priv->version < 0x30)
+ return 0;
+
r = ch341_control_out(dev, CH341_REQ_WRITE_REG, 0x2518, lcr);
if (r)
return r;
@@ -233,7 +242,9 @@ static int ch341_configure(struct usb_device *dev, struct ch341_private *priv)
r = ch341_control_in(dev, CH341_REQ_READ_VERSION, 0, 0, buffer, size);
if (r < 0)
goto out;
- dev_dbg(&dev->dev, "Chip version: 0x%02x\n", buffer[0]);
+
+ priv->version = buffer[0];
+ dev_dbg(&dev->dev, "Chip version: 0x%02x\n", priv->version);
r = ch341_control_out(dev, CH341_REQ_SERIAL_INIT, 0, 0);
if (r < 0)