Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1370015 > unrolled thread
| Started by | Grigori Goronzy <greg@chown.ath.cx> |
|---|---|
| First post | 2016-04-02 19:20 +0200 |
| Last post | 2016-04-06 14:10 +0200 |
| Articles | 10 — 4 participants |
Back to article view | Back to linux.kernel
Major improvements to the ch341 driver Grigori Goronzy <greg@chown.ath.cx> - 2016-04-02 19:20 +0200
[PATCH v2 04/14] USB: ch341: add definitions for modem control Grigori Goronzy <greg@chown.ath.cx> - 2016-04-02 19:30 +0200
[PATCH v2 13/14] USB: ch341: get rid of default configuration Grigori Goronzy <greg@chown.ath.cx> - 2016-04-02 19:30 +0200
[PATCH v2 09/14] USB: ch341: add support for RTS/CTS flow control Grigori Goronzy <greg@chown.ath.cx> - 2016-04-02 19:30 +0200
[PATCH v2 05/14] USB: ch341: fix USB buffer allocations Grigori Goronzy <greg@chown.ath.cx> - 2016-04-02 19:30 +0200
Re: [PATCH v2 05/14] USB: ch341: fix USB buffer allocations Oliver Neukum <oneukum@suse.com> - 2016-04-04 09:20 +0200
[PATCH v2 03/14] USB: ch341: add LCR register definitions Grigori Goronzy <greg@chown.ath.cx> - 2016-04-02 19:30 +0200
[PATCH v2 07/14] USB: ch341: add support for parity, frame length, stop bits Grigori Goronzy <greg@chown.ath.cx> - 2016-04-02 19:30 +0200
Re: [PATCH v2 07/14] USB: ch341: add support for parity, frame length, stop bits Karl Palsson <karlp@tweak.net.au> - 2016-04-03 18:00 +0200
Re: [PATCH v2 07/14] USB: ch341: add support for parity, frame length, stop bits One Thousand Gnomes <gnomes@lxorguk.ukuu.org.uk> - 2016-04-06 14:10 +0200
| From | Grigori Goronzy <greg@chown.ath.cx> |
|---|---|
| Date | 2016-04-02 19:20 +0200 |
| Subject | Major improvements to the ch341 driver |
| Message-ID | <rjxnk-74U-3@gated-at.bofh.it> |
Hi, this patchset consists of several improvements and cleanups to the ch341 driver, which has been mostly unmaintained for the last few years, despite major shortcomings. For instance, there is no support at all for parity, which is an often used feature. Other settings are missing too, as is hardware flow control. Here's a summary of changes: - Restructured initialization and configuration, which makes CH341A hardware work for the first time and is the basis for some following additions. - Support for the different parity modes, including mark/space - Support for two stop bits - Support for 5, 6 and 7 bit transfers - Support for RTS/CTS hardware flow control - Improved handling of B0 and DTR/RTS lines - Added tx_empty callback - Extracted magic numbers into definitions - Cleaned up code style and debug/error messages This has been tested on several different CH340G dongles and a CH341A adapter which is designed for EEPROM programming (but still supports UART). Functionality of the different configurations has been verified with a logic analyzer. In addition I did some quick interoperability tests with a CP2102 UART. My original motivation for this work was parity support which I needed for stcgal [1], and it works fine with that software too, of course. Please review. I would also appreciate to get some more testing done. In particular, I would like to make the sure the restructured initialization does not break anything. If you wonder, this is v2 because I initially sent it to the wrong list. Best regards Grigori [1] https://github.com/grigorig/stcgal
[toc] | [next] | [standalone]
| From | Grigori Goronzy <greg@chown.ath.cx> |
|---|---|
| Date | 2016-04-02 19:30 +0200 |
| Subject | [PATCH v2 04/14] USB: ch341: add definitions for modem control |
| Message-ID | <rjxx0-78K-3@gated-at.bofh.it> |
| In reply to | #1370015 |
Signed-off-by: Grigori Goronzy <greg@chown.ath.cx>
---
drivers/usb/serial/ch341.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/usb/serial/ch341.c b/drivers/usb/serial/ch341.c
index 788c75a..25c5d8d 100644
--- a/drivers/usb/serial/ch341.c
+++ b/drivers/usb/serial/ch341.c
@@ -62,6 +62,7 @@
* the Net/FreeBSD uchcom.c driver by Takanori Watanabe. Domo arigato.
*/
+#define CH341_MODEM_CTRL 0xA4
#define CH341_REQ_WRITE_REG 0x9A
#define CH341_REQ_READ_REG 0x95
#define CH341_REG_BREAK1 0x05
@@ -163,7 +164,7 @@ static int ch341_set_baudrate(struct usb_device *dev,
static int ch341_set_handshake(struct usb_device *dev, u8 control)
{
- return ch341_control_out(dev, 0xa4, ~control, 0);
+ return ch341_control_out(dev, CH341_MODEM_CTRL, ~control, 0);
}
static int ch341_get_status(struct usb_device *dev, struct ch341_private *priv)
--
1.9.1
[toc] | [prev] | [next] | [standalone]
| From | Grigori Goronzy <greg@chown.ath.cx> |
|---|---|
| Date | 2016-04-02 19:30 +0200 |
| Subject | [PATCH v2 13/14] USB: ch341: get rid of default configuration |
| Message-ID | <rjxx0-78K-5@gated-at.bofh.it> |
| In reply to | #1370015 |
If the serial port hasn't been opened yet, no baud rate should be set and RTS/DTR need to be deasserted. Signed-off-by: Grigori Goronzy <greg@chown.ath.cx> --- drivers/usb/serial/ch341.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/drivers/usb/serial/ch341.c b/drivers/usb/serial/ch341.c index 3b9a43d..6981e2ad 100644 --- a/drivers/usb/serial/ch341.c +++ b/drivers/usb/serial/ch341.c @@ -25,7 +25,6 @@ #include <linux/serial.h> #include <asm/unaligned.h> -#define DEFAULT_BAUD_RATE 9600 #define DEFAULT_TIMEOUT 1000 /* flags for IO-Bits */ @@ -235,10 +234,6 @@ static int ch341_configure(struct usb_device *dev, struct ch341_private *priv) if (r < 0) goto out; - r = ch341_init_set_baudrate(dev, priv, 0); - if (r < 0) - goto out; - r = ch341_set_handshake(dev, priv->line_control); if (r < 0) goto out; @@ -261,8 +256,6 @@ static int ch341_port_probe(struct usb_serial_port *port) return -ENOMEM; spin_lock_init(&priv->lock); - priv->baud_rate = DEFAULT_BAUD_RATE; - priv->line_control = CH341_BIT_RTS | CH341_BIT_DTR; r = ch341_configure(port->serial->dev, priv); if (r < 0) -- 1.9.1
[toc] | [prev] | [next] | [standalone]
| From | Grigori Goronzy <greg@chown.ath.cx> |
|---|---|
| Date | 2016-04-02 19:30 +0200 |
| Subject | [PATCH v2 09/14] USB: ch341: add support for RTS/CTS flow control |
| Message-ID | <rjxx0-78K-7@gated-at.bofh.it> |
| In reply to | #1370015 |
v2: use correct flag variable
Signed-off-by: Grigori Goronzy <greg@chown.ath.cx>
---
drivers/usb/serial/ch341.c | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/drivers/usb/serial/ch341.c b/drivers/usb/serial/ch341.c
index 58309d1..d956f75 100644
--- a/drivers/usb/serial/ch341.c
+++ b/drivers/usb/serial/ch341.c
@@ -69,6 +69,7 @@
#define CH341_REQ_READ_REG 0x95
#define CH341_REG_BREAK1 0x05
#define CH341_REG_LCR 0x18
+#define CH341_REG_RTSCTS 0x27
#define CH341_NBREAK_BITS_REG1 0x01
#define CH341_LCR_ENABLE_RX 0x80
@@ -403,6 +404,16 @@ static void ch341_set_termios(struct tty_struct *tty,
ch341_set_handshake(port->serial->dev, priv->line_control);
+ if (cflag & CRTSCTS) {
+ r = ch341_control_out(port->serial->dev, CH341_REQ_WRITE_REG,
+ CH341_REG_RTSCTS | ((uint16_t)CH341_REG_RTSCTS << 8),
+ 0x0101);
+ if (r < 0) {
+ dev_err(&port->dev, "%s - USB control write error (%d)\n",
+ __func__, r);
+ tty->termios.c_cflag &= ~CRTSCTS;
+ }
+ }
}
static void ch341_break_ctl(struct tty_struct *tty, int break_state)
--
1.9.1
[toc] | [prev] | [next] | [standalone]
| From | Grigori Goronzy <greg@chown.ath.cx> |
|---|---|
| Date | 2016-04-02 19:30 +0200 |
| Subject | [PATCH v2 05/14] USB: ch341: fix USB buffer allocations |
| Message-ID | <rjxx0-78K-13@gated-at.bofh.it> |
| In reply to | #1370015 |
Use the correct types and sizes.
Signed-off-by: Grigori Goronzy <greg@chown.ath.cx>
---
drivers/usb/serial/ch341.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/usb/serial/ch341.c b/drivers/usb/serial/ch341.c
index 25c5d8d..6781911 100644
--- a/drivers/usb/serial/ch341.c
+++ b/drivers/usb/serial/ch341.c
@@ -116,7 +116,7 @@ static int ch341_control_out(struct usb_device *dev, u8 request,
static int ch341_control_in(struct usb_device *dev,
u8 request, u16 value, u16 index,
- char *buf, unsigned bufsize)
+ unsigned char *buf, unsigned bufsize)
{
int r;
@@ -169,9 +169,9 @@ static int ch341_set_handshake(struct usb_device *dev, u8 control)
static int ch341_get_status(struct usb_device *dev, struct ch341_private *priv)
{
- char *buffer;
+ unsigned char *buffer;
int r;
- const unsigned size = 8;
+ const unsigned size = 2;
unsigned long flags;
buffer = kmalloc(size, GFP_KERNEL);
@@ -199,9 +199,9 @@ out: kfree(buffer);
static int ch341_configure(struct usb_device *dev, struct ch341_private *priv)
{
- char *buffer;
+ unsigned char *buffer;
int r;
- const unsigned size = 8;
+ const unsigned size = 2;
buffer = kmalloc(size, GFP_KERNEL);
if (!buffer)
--
1.9.1
[toc] | [prev] | [next] | [standalone]
| From | Oliver Neukum <oneukum@suse.com> |
|---|---|
| Date | 2016-04-04 09:20 +0200 |
| Subject | Re: [PATCH v2 05/14] USB: ch341: fix USB buffer allocations |
| Message-ID | <rk6XM-82e-7@gated-at.bofh.it> |
| In reply to | #1370019 |
On Sat, 2016-04-02 at 19:07 +0200, Grigori Goronzy wrote:
> Use the correct types and sizes.
>
> Signed-off-by: Grigori Goronzy <greg@chown.ath.cx>
> ---
> drivers/usb/serial/ch341.c | 10 +++++-----
> 1 file changed, 5 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/usb/serial/ch341.c b/drivers/usb/serial/ch341.c
> index 25c5d8d..6781911 100644
> --- a/drivers/usb/serial/ch341.c
> +++ b/drivers/usb/serial/ch341.c
> @@ -116,7 +116,7 @@ static int ch341_control_out(struct usb_device *dev, u8 request,
>
> static int ch341_control_in(struct usb_device *dev,
> u8 request, u16 value, u16 index,
> - char *buf, unsigned bufsize)
> + unsigned char *buf, unsigned bufsize)
If you do that, you can just use u8 *
> {
> int r;
>
> @@ -169,9 +169,9 @@ static int ch341_set_handshake(struct usb_device *dev, u8 control)
>
> static int ch341_get_status(struct usb_device *dev, struct ch341_private *priv)
> {
> - char *buffer;
> + unsigned char *buffer;
> int r;
> - const unsigned size = 8;
> + const unsigned size = 2;
> unsigned long flags;
>
> buffer = kmalloc(size, GFP_KERNEL);
> @@ -199,9 +199,9 @@ out: kfree(buffer);
>
> static int ch341_configure(struct usb_device *dev, struct ch341_private *priv)
> {
> - char *buffer;
> + unsigned char *buffer;
> int r;
> - const unsigned size = 8;
> + const unsigned size = 2;
Are you sure only 2 are used?
For the amount of space needed it makes no difference.
Regards
Oliver
[toc] | [prev] | [next] | [standalone]
| From | Grigori Goronzy <greg@chown.ath.cx> |
|---|---|
| Date | 2016-04-02 19:30 +0200 |
| Subject | [PATCH v2 03/14] USB: ch341: add LCR register definitions |
| Message-ID | <rjxx0-78K-9@gated-at.bofh.it> |
| In reply to | #1370015 |
BREAK2 seems to be a misnomer, the register configures various aspects
of the UART configuration.
Signed-off-by: Grigori Goronzy <greg@chown.ath.cx>
---
drivers/usb/serial/ch341.c | 19 ++++++++++++++-----
1 file changed, 14 insertions(+), 5 deletions(-)
diff --git a/drivers/usb/serial/ch341.c b/drivers/usb/serial/ch341.c
index 9fb9089..788c75a 100644
--- a/drivers/usb/serial/ch341.c
+++ b/drivers/usb/serial/ch341.c
@@ -65,10 +65,19 @@
#define CH341_REQ_WRITE_REG 0x9A
#define CH341_REQ_READ_REG 0x95
#define CH341_REG_BREAK1 0x05
-#define CH341_REG_BREAK2 0x18
+#define CH341_REG_LCR 0x18
#define CH341_NBREAK_BITS_REG1 0x01
-#define CH341_NBREAK_BITS_REG2 0x40
+#define CH341_LCR_ENABLE_RX 0x80
+#define CH341_LCR_ENABLE_TX 0x40
+#define CH341_LCR_MARK_SPACE 0x20
+#define CH341_LCR_PAR_EVEN 0x10
+#define CH341_LCR_ENABLE_PAR 0x08
+#define CH341_LCR_STOP_BITS_2 0x04
+#define CH341_LCR_CS8 0x03
+#define CH341_LCR_CS7 0x02
+#define CH341_LCR_CS6 0x01
+#define CH341_LCR_CS5 0x00
static const struct usb_device_id id_table[] = {
{ USB_DEVICE(0x4348, 0x5523) },
@@ -371,7 +380,7 @@ static void ch341_set_termios(struct tty_struct *tty,
static void ch341_break_ctl(struct tty_struct *tty, int break_state)
{
const uint16_t ch341_break_reg =
- CH341_REG_BREAK1 | ((uint16_t) CH341_REG_BREAK2 << 8);
+ CH341_REG_BREAK1 | ((uint16_t) CH341_REG_LCR << 8);
struct usb_serial_port *port = tty->driver_data;
int r;
uint16_t reg_contents;
@@ -393,11 +402,11 @@ static void ch341_break_ctl(struct tty_struct *tty, int break_state)
if (break_state != 0) {
dev_dbg(&port->dev, "%s - Enter break state requested\n", __func__);
break_reg[0] &= ~CH341_NBREAK_BITS_REG1;
- break_reg[1] &= ~CH341_NBREAK_BITS_REG2;
+ break_reg[1] &= ~CH341_LCR_ENABLE_TX;
} else {
dev_dbg(&port->dev, "%s - Leave break state requested\n", __func__);
break_reg[0] |= CH341_NBREAK_BITS_REG1;
- break_reg[1] |= CH341_NBREAK_BITS_REG2;
+ break_reg[1] |= CH341_LCR_ENABLE_TX;
}
dev_dbg(&port->dev, "%s - New ch341 break register contents - reg1: %x, reg2: %x\n",
__func__, break_reg[0], break_reg[1]);
--
1.9.1
[toc] | [prev] | [next] | [standalone]
| From | Grigori Goronzy <greg@chown.ath.cx> |
|---|---|
| Date | 2016-04-02 19:30 +0200 |
| Subject | [PATCH v2 07/14] USB: ch341: add support for parity, frame length, stop bits |
| Message-ID | <rjxx1-78K-17@gated-at.bofh.it> |
| In reply to | #1370015 |
With the new reinitialization method, configuring parity, different
frame lengths and different stop bit settings work as expected on
both CH340G and CH341A. This has been extensively tested with a
logic analyzer.
Tested-by: Ryan Barber <rfb@skyscraper.nu>
Signed-off-by: Grigori Goronzy <greg@chown.ath.cx>
---
drivers/usb/serial/ch341.c | 36 ++++++++++++++++++++++++++++++------
1 file changed, 30 insertions(+), 6 deletions(-)
diff --git a/drivers/usb/serial/ch341.c b/drivers/usb/serial/ch341.c
index c001773..4d66f0f 100644
--- a/drivers/usb/serial/ch341.c
+++ b/drivers/usb/serial/ch341.c
@@ -346,6 +346,7 @@ static void ch341_set_termios(struct tty_struct *tty,
unsigned baud_rate;
unsigned long flags;
unsigned char ctrl;
+ unsigned cflag = tty->termios.c_cflag;
int r;
/* redundant changes may cause the chip to lose bytes */
@@ -356,7 +357,35 @@ static void ch341_set_termios(struct tty_struct *tty,
priv->baud_rate = baud_rate;
- ctrl = CH341_LCR_ENABLE_RX | CH341_LCR_ENABLE_TX | CH341_LCR_CS8;
+ ctrl = CH341_LCR_ENABLE_RX | CH341_LCR_ENABLE_TX;
+
+ switch (cflag & CSIZE) {
+ case CS5:
+ ctrl |= CH341_LCR_CS5;
+ break;
+ case CS6:
+ ctrl |= CH341_LCR_CS6;
+ break;
+ case CS7:
+ ctrl |= CH341_LCR_CS7;
+ break;
+ case CS8:
+ default:
+ ctrl |= CH341_LCR_CS8;
+ break;
+ }
+
+ if (cflag & PARENB) {
+ ctrl |= CH341_LCR_ENABLE_PAR;
+ if ((cflag & PARODD) == 0)
+ ctrl |= CH341_LCR_PAR_EVEN;
+ }
+
+ if (cflag & CMSPAR)
+ ctrl |= CH341_LCR_MARK_SPACE;
+
+ if (cflag & CSTOPB)
+ ctrl |= CH341_LCR_STOP_BITS_2;
if (baud_rate) {
spin_lock_irqsave(&priv->lock, flags);
@@ -373,11 +402,6 @@ static void ch341_set_termios(struct tty_struct *tty,
ch341_set_handshake(port->serial->dev, priv->line_control);
- /* Unimplemented:
- * (cflag & CSIZE) : data bits [5, 8]
- * (cflag & PARENB) : parity {NONE, EVEN, ODD}
- * (cflag & CSTOPB) : stop bits [1, 2]
- */
}
static void ch341_break_ctl(struct tty_struct *tty, int break_state)
--
1.9.1
[toc] | [prev] | [next] | [standalone]
| From | Karl Palsson <karlp@tweak.net.au> |
|---|---|
| Date | 2016-04-03 18:00 +0200 |
| Subject | Re: [PATCH v2 07/14] USB: ch341: add support for parity, frame length, stop bits |
| Message-ID | <rjSBs-5EU-27@gated-at.bofh.it> |
| In reply to | #1370021 |
[Multipart message — attachments visible in raw view] — view raw
Grigori Goronzy <greg@chown.ath.cx> wrote:
> With the new reinitialization method, configuring parity,
> different frame lengths and different stop bit settings work as
> expected on both CH340G and CH341A. This has been extensively
> tested with a logic analyzer.
>
> Tested-by: Ryan Barber <rfb@skyscraper.nu>
> Signed-off-by: Grigori Goronzy <greg@chown.ath.cx>
> ---
> drivers/usb/serial/ch341.c | 36 ++++++++++++++++++++++++++++++------
> 1 file changed, 30 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/usb/serial/ch341.c
> b/drivers/usb/serial/ch341.c index c001773..4d66f0f 100644
> --- a/drivers/usb/serial/ch341.c
> +++ b/drivers/usb/serial/ch341.c
> @@ -346,6 +346,7 @@ static void ch341_set_termios(struct tty_struct *tty,
> unsigned baud_rate;
> unsigned long flags;
> unsigned char ctrl;
> + unsigned cflag = tty->termios.c_cflag;
> int r;
>
> /* redundant changes may cause the chip to lose bytes */
> @@ -356,7 +357,35 @@ static void ch341_set_termios(struct tty_struct *tty,
>
> priv->baud_rate = baud_rate;
>
> - ctrl = CH341_LCR_ENABLE_RX | CH341_LCR_ENABLE_TX | CH341_LCR_CS8;
> + ctrl = CH341_LCR_ENABLE_RX | CH341_LCR_ENABLE_TX;
> +
> + switch (cflag & CSIZE) {
> + case CS5:
> + ctrl |= CH341_LCR_CS5;
> + break;
> + case CS6:
> + ctrl |= CH341_LCR_CS6;
> + break;
> + case CS7:
> + ctrl |= CH341_LCR_CS7;
> + break;
> + case CS8:
> + default:
> + ctrl |= CH341_LCR_CS8;
> + break;
> + }
> +
> + if (cflag & PARENB) {
> + ctrl |= CH341_LCR_ENABLE_PAR;
> + if ((cflag & PARODD) == 0)
> + ctrl |= CH341_LCR_PAR_EVEN;
> + }
> +
> + if (cflag & CMSPAR)
> + ctrl |= CH341_LCR_MARK_SPACE;
> +
> + if (cflag & CSTOPB)
> + ctrl |= CH341_LCR_STOP_BITS_2;
>
I think this should be moved up to the PARENB check, at least,
when I was working on this. Also there's macros for some of the
flag checks: (From some code I was working on, but you can see
the mark/space is differently handled, this matched the windows
driver I was reversing usb captures from.)
if (C_PARENB(tty)) {
*lcr |= CH341_LCR_PARITY;
if (C_CMSPAR(tty)) {
*lcr |= CH341_LCR_SPAR;
if (C_PARODD(tty)) {
dev_dbg(&port->dev, "parity = mark\n");
*lcr &= ~CH341_LCR_EPAR;
} else {
dev_dbg(&port->dev, "parity = space\n");
*lcr |= CH341_LCR_EPAR;
}
} else {
*lcr &= ~CH341_LCR_SPAR;
if (C_PARODD(tty)) {
dev_dbg(&port->dev, "parity = odd\n");
*lcr &= ~CH341_LCR_EPAR;
} else {
dev_dbg(&port->dev, "parity = even\n");
*lcr |= CH341_LCR_EPAR;
}
}
} else {
*lcr &= ~(CH341_LCR_PARITY | CH341_LCR_SPAR | CH341_LCR_EPAR);
dev_dbg(&port->dev, "parity = none\n");
}
> if (baud_rate) {
> spin_lock_irqsave(&priv->lock, flags);
> @@ -373,11 +402,6 @@ static void ch341_set_termios(struct tty_struct *tty,
>
> ch341_set_handshake(port->serial->dev, priv->line_control);
>
> - /* Unimplemented:
> - * (cflag & CSIZE) : data bits [5, 8]
> - * (cflag & PARENB) : parity {NONE, EVEN, ODD}
> - * (cflag & CSTOPB) : stop bits [1, 2]
> - */
> }
>
> static void ch341_break_ctl(struct tty_struct *tty, int break_state)
> --
> 1.9.1
>
> --
> To unsubscribe from this list: send the line "unsubscribe
> linux-usb" in the body of a message to
> majordomo@vger.kernel.org More majordomo info at
> http://vger.kernel.org/majordomo-info.html
[toc] | [prev] | [next] | [standalone]
| From | One Thousand Gnomes <gnomes@lxorguk.ukuu.org.uk> |
|---|---|
| Date | 2016-04-06 14:10 +0200 |
| Subject | Re: [PATCH v2 07/14] USB: ch341: add support for parity, frame length, stop bits |
| Message-ID | <rkUrx-3zX-15@gated-at.bofh.it> |
| In reply to | #1370021 |
On Sat, 2 Apr 2016 19:07:16 +0200
Grigori Goronzy <greg@chown.ath.cx> wrote:
> With the new reinitialization method, configuring parity, different
> frame lengths and different stop bit settings work as expected on
> both CH340G and CH341A. This has been extensively tested with a
> logic analyzer.
>
> Tested-by: Ryan Barber <rfb@skyscraper.nu>
> Signed-off-by: Grigori Goronzy <greg@chown.ath.cx>
> ---
> drivers/usb/serial/ch341.c | 36 ++++++++++++++++++++++++++++++------
> 1 file changed, 30 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/usb/serial/ch341.c b/drivers/usb/serial/ch341.c
> index c001773..4d66f0f 100644
> --- a/drivers/usb/serial/ch341.c
> +++ b/drivers/usb/serial/ch341.c
> @@ -346,6 +346,7 @@ static void ch341_set_termios(struct tty_struct *tty,
> unsigned baud_rate;
> unsigned long flags;
> unsigned char ctrl;
> + unsigned cflag = tty->termios.c_cflag;
> int r;
>
> /* redundant changes may cause the chip to lose bytes */
> @@ -356,7 +357,35 @@ static void ch341_set_termios(struct tty_struct *tty,
>
> priv->baud_rate = baud_rate;
>
> - ctrl = CH341_LCR_ENABLE_RX | CH341_LCR_ENABLE_TX | CH341_LCR_CS8;
> + ctrl = CH341_LCR_ENABLE_RX | CH341_LCR_ENABLE_TX;
> +
> + switch (cflag & CSIZE) {
> + case CS5:
> + ctrl |= CH341_LCR_CS5;
> + break;
> + case CS6:
> + ctrl |= CH341_LCR_CS6;
> + break;
> + case CS7:
> + ctrl |= CH341_LCR_CS7;
> + break;
> + case CS8:
> + default:
> + ctrl |= CH341_LCR_CS8;
In the default case tty-.termios.c_cflag should also be updated to show
CS8
Alan
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web