comparison 4.14.202/0003-USB-serial-ftdi_sio-add-support-for-FreeCalypso-DUAR.patch @ 12:6c347929a458

4.14.202: add for completeness
author Mychaela Falconia <falcon@freecalypso.org>
date Sat, 20 Jan 2024 02:19:26 +0000
parents
children
comparison
equal deleted inserted replaced
11:298c838f12c0 12:6c347929a458
1 From a3aab542c53b3236a1a7315d201496c837793fa9 Mon Sep 17 00:00:00 2001
2 From: "Mychaela N. Falconia" <falcon@freecalypso.org>
3 Date: Fri, 2 Oct 2020 18:01:12 +0000
4 Subject: [PATCH 3/3] USB: serial: ftdi_sio: add support for FreeCalypso
5 DUART28C adapter
6
7 FreeCalypso DUART28C is an FT2232D-based USB to dual UART adapter
8 with a special quirk: Channel B RTS and DTR outputs (BDBUS2 and BDBUS4
9 on the chip) have been repurposed to drive PWON and RESET controls
10 on Calypso targets. The circuit is wired such that BDBUS[24] high
11 (RTS/DTR inactive) is the normal state with Iota VRPC controls
12 NOT activated, whereas BDBUS[24] low (RTS or DTR active) turn ON
13 the corresponding open drain control signal drivers.
14
15 A special ftdi_sio driver quirk is needed in order to suppress
16 automatic assertion of DTR & RTS on device open: this device's
17 special PWON and RESET control drivers MUST NOT be activated
18 when the port is ordinarily opened for plain serial communication,
19 instead they must only be activated when a special userspace
20 application explicitly requests such activation with a TIOCMBIS ioctl.
21 These special userspace applications are responsible for making the
22 needed pulse with a TIOCMBIS, delay, TIOCMBIC sequence.
23
24 The special quirk is conditionalized on the DUART28C adapter's custom
25 USB ID, and is further limited to FT2232D Channel B only: Channel A
26 is wired normally, with the chip's ADBUS2 and ADBUS4 outputs
27 actually being RTS and DTR rather than something else.
28
29 Signed-off-by: Mychaela N. Falconia <falcon@freecalypso.org>
30 ---
31 drivers/usb/serial/ftdi_sio.c | 61 +++++++++++++++++++++++++++++++++++----
32 drivers/usb/serial/ftdi_sio_ids.h | 1 +
33 2 files changed, 57 insertions(+), 5 deletions(-)
34
35 diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
36 index 137688e9a86a..88ef223b72c9 100644
37 --- a/drivers/usb/serial/ftdi_sio.c
38 +++ b/drivers/usb/serial/ftdi_sio.c
39 @@ -73,6 +73,8 @@ struct ftdi_private {
40 this value */
41 int force_rtscts; /* if non-zero, force RTS-CTS to always
42 be enabled */
43 + int no_auto_dtr_rts; /* if non-zero, suppress automatic assertion
44 + of DTR & RTS on device open */
45
46 unsigned int latency; /* latency setting in use */
47 unsigned short max_packet_size;
48 @@ -92,6 +94,7 @@ static int ftdi_stmclite_probe(struct usb_serial *serial);
49 static int ftdi_8u2232c_probe(struct usb_serial *serial);
50 static void ftdi_USB_UIRT_setup(struct usb_serial_port *port);
51 static void ftdi_HE_TIRA1_setup(struct usb_serial_port *port);
52 +static void ftdi_duart28c_setup(struct usb_serial_port *port);
53
54 static const struct ftdi_sio_quirk ftdi_jtag_quirk = {
55 .probe = ftdi_jtag_probe,
56 @@ -117,6 +120,10 @@ static const struct ftdi_sio_quirk ftdi_8u2232c_quirk = {
57 .probe = ftdi_8u2232c_probe,
58 };
59
60 +static const struct ftdi_sio_quirk ftdi_duart28c_quirk = {
61 + .port_probe = ftdi_duart28c_setup,
62 +};
63 +
64 /*
65 * The 8U232AM has the same API as the sio except for:
66 * - it can support MUCH higher baudrates; up to:
67 @@ -1037,6 +1044,8 @@ static const struct usb_device_id id_table_combined[] = {
68 .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
69 { USB_DEVICE(FTDI_VID, FTDI_FALCONIA_JTAG_UNBUF_PID),
70 .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
71 + { USB_DEVICE(FTDI_VID, FTDI_FALCONIA_DUART28C_PID),
72 + .driver_info = (kernel_ulong_t)&ftdi_duart28c_quirk },
73 { } /* Terminating entry */
74 };
75
76 @@ -1952,6 +1961,39 @@ static int ftdi_stmclite_probe(struct usb_serial *serial)
77 return 0;
78 }
79
80 +/*
81 + * FreeCalypso DUART28C is an FT2232D-based USB to dual UART adapter
82 + * with a special quirk: Channel B RTS and DTR outputs (BDBUS2 and BDBUS4
83 + * on the chip) have been repurposed to drive PWON and RESET controls
84 + * on Calypso targets. The circuit is wired such that BDBUS[24] high
85 + * (RTS/DTR inactive) is the normal state with Iota VRPC controls
86 + * NOT activated, whereas BDBUS[24] low (RTS or DTR active) turn ON
87 + * the corresponding open drain control signal drivers.
88 + *
89 + * A special ftdi_sio driver quirk is needed in order to suppress
90 + * automatic assertion of DTR & RTS on device open: this device's
91 + * special PWON and RESET control drivers MUST NOT be activated
92 + * when the port is ordinarily opened for plain serial communication,
93 + * instead they must only be activated when a special userspace
94 + * application explicitly requests such activation with a TIOCMBIS ioctl.
95 + * These special userspace applications are responsible for making the
96 + * needed pulse with a TIOCMBIS, delay, TIOCMBIC sequence.
97 + *
98 + * The special quirk must be applied only to FT2232D Channel B:
99 + * Channel A is wired normally, with the chip's ADBUS2 and ADBUS4 outputs
100 + * actually being RTS and DTR rather than something else.
101 + */
102 +static void ftdi_duart28c_setup(struct usb_serial_port *port)
103 +{
104 + struct ftdi_private *priv = usb_get_serial_port_data(port);
105 + struct usb_serial *serial = port->serial;
106 + struct usb_interface *intf = serial->interface;
107 + int ifnum = intf->cur_altsetting->desc.bInterfaceNumber;
108 +
109 + if (ifnum == 1)
110 + priv->no_auto_dtr_rts = 1;
111 +}
112 +
113 static int ftdi_sio_port_remove(struct usb_serial_port *port)
114 {
115 struct ftdi_private *priv = usb_get_serial_port_data(port);
116 @@ -2001,10 +2043,18 @@ static void ftdi_dtr_rts(struct usb_serial_port *port, int on)
117 dev_err(&port->dev, "error from flowcontrol urb\n");
118 }
119 }
120 - /* drop RTS and DTR */
121 - if (on)
122 - set_mctrl(port, TIOCM_DTR | TIOCM_RTS);
123 - else
124 + /*
125 + * Assert or negate RTS and DTR as requested. When DUART28C
126 + * quirk is applied, we suppress automatic assertion, but
127 + * automatic negation on device close is retained - these
128 + * special control signals are meant to be pulsed, and leaving
129 + * either of them stuck on when the responsible userspace
130 + * program has terminated unexpectedly is undesirable.
131 + */
132 + if (on) {
133 + if (!priv->no_auto_dtr_rts)
134 + set_mctrl(port, TIOCM_DTR | TIOCM_RTS);
135 + } else
136 clear_mctrl(port, TIOCM_DTR | TIOCM_RTS);
137 }
138
139 @@ -2346,7 +2396,8 @@ static void ftdi_set_termios(struct tty_struct *tty,
140 dev_err(ddev, "%s urb failed to set baudrate\n", __func__);
141 mutex_unlock(&priv->cfg_lock);
142 /* Ensure RTS and DTR are raised when baudrate changed from 0 */
143 - if (old_termios && (old_termios->c_cflag & CBAUD) == B0)
144 + if (old_termios && (old_termios->c_cflag & CBAUD) == B0
145 + && !priv->no_auto_dtr_rts)
146 set_mctrl(port, TIOCM_DTR | TIOCM_RTS);
147 }
148
149 diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h
150 index 3d47c6d72256..3081b8916a0a 100644
151 --- a/drivers/usb/serial/ftdi_sio_ids.h
152 +++ b/drivers/usb/serial/ftdi_sio_ids.h
153 @@ -45,6 +45,7 @@
154 */
155 #define FTDI_FALCONIA_JTAG_BUF_PID 0x7150
156 #define FTDI_FALCONIA_JTAG_UNBUF_PID 0x7151
157 +#define FTDI_FALCONIA_DUART28C_PID 0x7152
158
159 /* Sienna Serial Interface by Secyourit GmbH */
160 #define FTDI_SIENNA_PID 0x8348
161 --
162 2.9.0
163