Skip to content

Commit 35478bc

Browse files
Lode Willemsjhovold
authored andcommitted
USB: serial: ch341: add hardware flow control RTS/CTS
This adds support for enabling and disabling RTS/CTS hardware flow control. Tested using CH341A and CH340E. Fixes part of the following bug report: Link: https://bugzilla.kernel.org/show_bug.cgi?id=197109 Signed-off-by: Lode Willems <[email protected]> [ johan: prepare index argument once, drop casts ] Signed-off-by: Johan Hovold <[email protected]>
1 parent 4bbf902 commit 35478bc

File tree

1 file changed

+28
-0
lines changed

1 file changed

+28
-0
lines changed

drivers/usb/serial/ch341.c

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@
6363
#define CH341_REG_DIVISOR 0x13
6464
#define CH341_REG_LCR 0x18
6565
#define CH341_REG_LCR2 0x25
66+
#define CH341_REG_FLOW_CTL 0x27
6667

6768
#define CH341_NBREAK_BITS 0x01
6869

@@ -77,6 +78,9 @@
7778
#define CH341_LCR_CS6 0x01
7879
#define CH341_LCR_CS5 0x00
7980

81+
#define CH341_FLOW_CTL_NONE 0x00
82+
#define CH341_FLOW_CTL_RTSCTS 0x01
83+
8084
#define CH341_QUIRK_LIMITED_PRESCALER BIT(0)
8185
#define CH341_QUIRK_SIMULATE_BREAK BIT(1)
8286

@@ -478,6 +482,28 @@ static int ch341_open(struct tty_struct *tty, struct usb_serial_port *port)
478482
return r;
479483
}
480484

485+
static void ch341_set_flow_control(struct tty_struct *tty,
486+
struct usb_serial_port *port,
487+
const struct ktermios *old_termios)
488+
{
489+
u16 flow_ctl;
490+
int r;
491+
492+
if (C_CRTSCTS(tty))
493+
flow_ctl = CH341_FLOW_CTL_RTSCTS;
494+
else
495+
flow_ctl = CH341_FLOW_CTL_NONE;
496+
497+
r = ch341_control_out(port->serial->dev,
498+
CH341_REQ_WRITE_REG,
499+
(CH341_REG_FLOW_CTL << 8) | CH341_REG_FLOW_CTL,
500+
(flow_ctl << 8) | flow_ctl);
501+
if (r < 0 && old_termios) {
502+
tty->termios.c_cflag &= ~CRTSCTS;
503+
tty->termios.c_cflag |= (old_termios->c_cflag & CRTSCTS);
504+
}
505+
}
506+
481507
/* Old_termios contains the original termios settings and
482508
* tty->termios contains the new setting to be used.
483509
*/
@@ -546,6 +572,8 @@ static void ch341_set_termios(struct tty_struct *tty,
546572
spin_unlock_irqrestore(&priv->lock, flags);
547573

548574
ch341_set_handshake(port->serial->dev, priv->mcr);
575+
576+
ch341_set_flow_control(tty, port, old_termios);
549577
}
550578

551579
/*

0 commit comments

Comments
 (0)