comparison linux-patch/minpatch-4.4.14/0003-USB-serial-ftdi_sio-add-support-for-FreeCalypso-DUAR.patch @ 83:d7a1e7a6d6ba

linux-patch: current best offering of minpatch-*
author Mychaela Falconia <falcon@freecalypso.org>
date Sun, 06 Dec 2020 02:55:40 +0000
parents
children
comparison
equal deleted inserted replaced
82:e2161ac7d641 83:d7a1e7a6d6ba
1 From 32c23625ab6e7cdc7da7849e866ccee66cbe2ee9 Mon Sep 17 00:00:00 2001
2 From: "Mychaela N. Falconia" <falcon@freecalypso.org>
3 Date: Sat, 5 Dec 2020 20:53:18 +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 60d1831ee8c3..b9abe8571aa1 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 struct ftdi_sio_quirk ftdi_jtag_quirk = {
55 .probe = ftdi_jtag_probe,
56 @@ -117,6 +120,10 @@ static struct ftdi_sio_quirk ftdi_8u2232c_quirk = {
57 .probe = ftdi_8u2232c_probe,
58 };
59
60 +static 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 @@ -1013,6 +1020,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 @@ -1935,6 +1944,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 @@ -1984,10 +2026,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 @@ -2325,7 +2375,8 @@ no_data_parity_stop_changes:
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 6218f9c45016..5720768859fe 100644
151 --- a/drivers/usb/serial/ftdi_sio_ids.h
152 +++ b/drivers/usb/serial/ftdi_sio_ids.h
153 @@ -44,6 +44,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 /* Cyber Cortex AV by Fabulous Silicon (http://fabuloussilicon.com) */
160 #define CYBER_CORTEX_AV_PID 0x8698
161 --
162 2.9.0
163