# HG changeset patch # User Mychaela Falconia # Date 1702276495 0 # Node ID d84895fc703bbb2cb75a8936a13dbce1aafebf45 # Parent 407bae787996585103b611edacd813784f29fb8a add 6.1 diff -r 407bae787996 -r d84895fc703b 6.1/0001-USB-serial-ftdi_sio-pass-port-to-quirk-port_probe-fu.patch --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/6.1/0001-USB-serial-ftdi_sio-pass-port-to-quirk-port_probe-fu.patch Mon Dec 11 06:34:55 2023 +0000 @@ -0,0 +1,85 @@ +From 9e0c4dc68a5ed2b2939ccf0694e3dfdd052c2e40 Mon Sep 17 00:00:00 2001 +From: "Mychaela N. Falconia" +Date: Fri, 2 Oct 2020 17:38:56 +0000 +Subject: [PATCH 1/2] USB: serial: ftdi_sio: pass port to quirk port_probe + functions + +The original code passed only the pointer to the ftdi_private struct +to quirk port_probe functions. However, some quirks may need to be +applied conditionally only to some channels of a multichannel FT2232x +or FT4232H device, and if a given quirk's port_probe function needs +to figure out which channel of a multichannel device is currently +being considered, it needs access to the port pointer passed to the +ftdi_sio_port_probe() function, so it can traverse USB data structures +from there. + +Signed-off-by: Mychaela N. Falconia +--- + drivers/usb/serial/ftdi_sio.c | 20 ++++++++++++-------- + 1 file changed, 12 insertions(+), 8 deletions(-) + +diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c +index 05e28a5ce42b..1587c22180c0 100644 +--- a/drivers/usb/serial/ftdi_sio.c ++++ b/drivers/usb/serial/ftdi_sio.c +@@ -103,15 +103,15 @@ struct ftdi_private { + struct ftdi_quirk { + int (*probe)(struct usb_serial *); + /* Special settings for probed ports. */ +- void (*port_probe)(struct ftdi_private *); ++ void (*port_probe)(struct usb_serial_port *); + }; + + static int ftdi_jtag_probe(struct usb_serial *serial); + static int ftdi_NDI_device_setup(struct usb_serial *serial); + static int ftdi_stmclite_probe(struct usb_serial *serial); + static int ftdi_8u2232c_probe(struct usb_serial *serial); +-static void ftdi_USB_UIRT_setup(struct ftdi_private *priv); +-static void ftdi_HE_TIRA1_setup(struct ftdi_private *priv); ++static void ftdi_USB_UIRT_setup(struct usb_serial_port *port); ++static void ftdi_HE_TIRA1_setup(struct usb_serial_port *port); + + static const struct ftdi_quirk ftdi_jtag_quirk = { + .probe = ftdi_jtag_probe, +@@ -2197,11 +2197,11 @@ static int ftdi_port_probe(struct usb_serial_port *port) + + mutex_init(&priv->cfg_lock); + +- if (quirk && quirk->port_probe) +- quirk->port_probe(priv); +- + usb_set_serial_port_data(port, priv); + ++ if (quirk && quirk->port_probe) ++ quirk->port_probe(port); ++ + result = ftdi_determine_type(port); + if (result) + goto err_free; +@@ -2229,8 +2229,10 @@ static int ftdi_port_probe(struct usb_serial_port *port) + /* Setup for the USB-UIRT device, which requires hardwired + * baudrate (38400 gets mapped to 312500) */ + /* Called from usbserial:serial_probe */ +-static void ftdi_USB_UIRT_setup(struct ftdi_private *priv) ++static void ftdi_USB_UIRT_setup(struct usb_serial_port *port) + { ++ struct ftdi_private *priv = usb_get_serial_port_data(port); ++ + priv->flags |= ASYNC_SPD_CUST; + priv->custom_divisor = 77; + priv->force_baud = 38400; +@@ -2239,8 +2241,10 @@ static void ftdi_USB_UIRT_setup(struct ftdi_private *priv) + /* Setup for the HE-TIRA1 device, which requires hardwired + * baudrate (38400 gets mapped to 100000) and RTS-CTS enabled. */ + +-static void ftdi_HE_TIRA1_setup(struct ftdi_private *priv) ++static void ftdi_HE_TIRA1_setup(struct usb_serial_port *port) + { ++ struct ftdi_private *priv = usb_get_serial_port_data(port); ++ + priv->flags |= ASYNC_SPD_CUST; + priv->custom_divisor = 240; + priv->force_baud = 38400; +-- +2.9.0 + diff -r 407bae787996 -r d84895fc703b 6.1/0002-USB-serial-ftdi_sio-add-support-for-FreeCalypso-DUAR.patch --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/6.1/0002-USB-serial-ftdi_sio-add-support-for-FreeCalypso-DUAR.patch Mon Dec 11 06:34:55 2023 +0000 @@ -0,0 +1,163 @@ +From e0b7be2ad39d65ddd59e65e654ce4196b8be69bc Mon Sep 17 00:00:00 2001 +From: "Mychaela N. Falconia" +Date: Fri, 2 Oct 2020 18:01:12 +0000 +Subject: [PATCH 2/2] USB: serial: ftdi_sio: add support for FreeCalypso + DUART28C adapter + +FreeCalypso DUART28C is an FT2232D-based USB to dual UART adapter +with a special quirk: Channel B RTS and DTR outputs (BDBUS2 and BDBUS4 +on the chip) have been repurposed to drive PWON and RESET controls +on Calypso targets. The circuit is wired such that BDBUS[24] high +(RTS/DTR inactive) is the normal state with Iota VRPC controls +NOT activated, whereas BDBUS[24] low (RTS or DTR active) turn ON +the corresponding open drain control signal drivers. + +A special ftdi_sio driver quirk is needed in order to suppress +automatic assertion of DTR & RTS on device open: this device's +special PWON and RESET control drivers MUST NOT be activated +when the port is ordinarily opened for plain serial communication, +instead they must only be activated when a special userspace +application explicitly requests such activation with a TIOCMBIS ioctl. +These special userspace applications are responsible for making the +needed pulse with a TIOCMBIS, delay, TIOCMBIC sequence. + +The special quirk is conditionalized on the DUART28C adapter's custom +USB ID, and is further limited to FT2232D Channel B only: Channel A +is wired normally, with the chip's ADBUS2 and ADBUS4 outputs +actually being RTS and DTR rather than something else. + +Signed-off-by: Mychaela N. Falconia +--- + drivers/usb/serial/ftdi_sio.c | 61 +++++++++++++++++++++++++++++++++++---- + drivers/usb/serial/ftdi_sio_ids.h | 1 + + 2 files changed, 57 insertions(+), 5 deletions(-) + +diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c +index 1587c22180c0..0ab2835d2c10 100644 +--- a/drivers/usb/serial/ftdi_sio.c ++++ b/drivers/usb/serial/ftdi_sio.c +@@ -85,6 +85,8 @@ struct ftdi_private { + this value */ + int force_rtscts; /* if non-zero, force RTS-CTS to always + be enabled */ ++ int no_auto_dtr_rts; /* if non-zero, suppress automatic assertion ++ of DTR & RTS on device open */ + + unsigned int latency; /* latency setting in use */ + unsigned short max_packet_size; +@@ -112,6 +114,7 @@ static int ftdi_stmclite_probe(struct usb_serial *serial); + static int ftdi_8u2232c_probe(struct usb_serial *serial); + static void ftdi_USB_UIRT_setup(struct usb_serial_port *port); + static void ftdi_HE_TIRA1_setup(struct usb_serial_port *port); ++static void ftdi_duart28c_setup(struct usb_serial_port *port); + + static const struct ftdi_quirk ftdi_jtag_quirk = { + .probe = ftdi_jtag_probe, +@@ -137,6 +140,10 @@ static const struct ftdi_quirk ftdi_8u2232c_quirk = { + .probe = ftdi_8u2232c_probe, + }; + ++static const struct ftdi_quirk ftdi_duart28c_quirk = { ++ .port_probe = ftdi_duart28c_setup, ++}; ++ + /* + * The 8U232AM has the same API as the sio except for: + * - it can support MUCH higher baudrates; up to: +@@ -1077,6 +1084,8 @@ static const struct usb_device_id id_table_combined[] = { + .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, + { USB_DEVICE(FTDI_VID, FTDI_FALCONIA_JTAG_UNBUF_PID), + .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, ++ { USB_DEVICE(FTDI_VID, FTDI_FALCONIA_DUART28C_PID), ++ .driver_info = (kernel_ulong_t)&ftdi_duart28c_quirk }, + { } /* Terminating entry */ + }; + +@@ -2338,6 +2347,39 @@ static int ftdi_stmclite_probe(struct usb_serial *serial) + return 0; + } + ++/* ++ * FreeCalypso DUART28C is an FT2232D-based USB to dual UART adapter ++ * with a special quirk: Channel B RTS and DTR outputs (BDBUS2 and BDBUS4 ++ * on the chip) have been repurposed to drive PWON and RESET controls ++ * on Calypso targets. The circuit is wired such that BDBUS[24] high ++ * (RTS/DTR inactive) is the normal state with Iota VRPC controls ++ * NOT activated, whereas BDBUS[24] low (RTS or DTR active) turn ON ++ * the corresponding open drain control signal drivers. ++ * ++ * A special ftdi_sio driver quirk is needed in order to suppress ++ * automatic assertion of DTR & RTS on device open: this device's ++ * special PWON and RESET control drivers MUST NOT be activated ++ * when the port is ordinarily opened for plain serial communication, ++ * instead they must only be activated when a special userspace ++ * application explicitly requests such activation with a TIOCMBIS ioctl. ++ * These special userspace applications are responsible for making the ++ * needed pulse with a TIOCMBIS, delay, TIOCMBIC sequence. ++ * ++ * The special quirk must be applied only to FT2232D Channel B: ++ * Channel A is wired normally, with the chip's ADBUS2 and ADBUS4 outputs ++ * actually being RTS and DTR rather than something else. ++ */ ++static void ftdi_duart28c_setup(struct usb_serial_port *port) ++{ ++ struct ftdi_private *priv = usb_get_serial_port_data(port); ++ struct usb_serial *serial = port->serial; ++ struct usb_interface *intf = serial->interface; ++ int ifnum = intf->cur_altsetting->desc.bInterfaceNumber; ++ ++ if (ifnum == 1) ++ priv->no_auto_dtr_rts = 1; ++} ++ + static void ftdi_port_remove(struct usb_serial_port *port) + { + struct ftdi_private *priv = usb_get_serial_port_data(port); +@@ -2385,10 +2427,18 @@ static void ftdi_dtr_rts(struct usb_serial_port *port, int on) + dev_err(&port->dev, "error from flowcontrol urb\n"); + } + } +- /* drop RTS and DTR */ +- if (on) +- set_mctrl(port, TIOCM_DTR | TIOCM_RTS); +- else ++ /* ++ * Assert or negate RTS and DTR as requested. When DUART28C ++ * quirk is applied, we suppress automatic assertion, but ++ * automatic negation on device close is retained - these ++ * special control signals are meant to be pulsed, and leaving ++ * either of them stuck on when the responsible userspace ++ * program has terminated unexpectedly is undesirable. ++ */ ++ if (on) { ++ if (!priv->no_auto_dtr_rts) ++ set_mctrl(port, TIOCM_DTR | TIOCM_RTS); ++ } else + clear_mctrl(port, TIOCM_DTR | TIOCM_RTS); + } + +@@ -2737,7 +2787,8 @@ static void ftdi_set_termios(struct tty_struct *tty, + dev_err(ddev, "%s urb failed to set baudrate\n", __func__); + mutex_unlock(&priv->cfg_lock); + /* Ensure RTS and DTR are raised when baudrate changed from 0 */ +- if (old_termios && (old_termios->c_cflag & CBAUD) == B0) ++ if (old_termios && (old_termios->c_cflag & CBAUD) == B0 ++ && !priv->no_auto_dtr_rts) + set_mctrl(port, TIOCM_DTR | TIOCM_RTS); + } + +diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h +index e2099445db70..713c38190352 100644 +--- a/drivers/usb/serial/ftdi_sio_ids.h ++++ b/drivers/usb/serial/ftdi_sio_ids.h +@@ -52,6 +52,7 @@ + */ + #define FTDI_FALCONIA_JTAG_BUF_PID 0x7150 + #define FTDI_FALCONIA_JTAG_UNBUF_PID 0x7151 ++#define FTDI_FALCONIA_DUART28C_PID 0x7152 + + /* Sienna Serial Interface by Secyourit GmbH */ + #define FTDI_SIENNA_PID 0x8348 +-- +2.9.0 +