# HG changeset patch # User Mychaela Falconia # Date 1702276173 0 # Node ID 407bae787996585103b611edacd813784f29fb8a # Parent e8b699ce98a2d603de9632f82a7d811d8f33034b add 5.12 diff -r e8b699ce98a2 -r 407bae787996 5.12/0001-USB-serial-ftdi_sio-pass-port-to-quirk-port_probe-fu.patch --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/5.12/0001-USB-serial-ftdi_sio-pass-port-to-quirk-port_probe-fu.patch Mon Dec 11 06:29:33 2023 +0000 @@ -0,0 +1,85 @@ +From 28e1cea403f1db216acfe0a8bb38840429655eaa 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 c867592477c9..0525dab7c281 100644 +--- a/drivers/usb/serial/ftdi_sio.c ++++ b/drivers/usb/serial/ftdi_sio.c +@@ -88,15 +88,15 @@ struct ftdi_private { + struct ftdi_sio_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_sio_quirk ftdi_jtag_quirk = { + .probe = ftdi_jtag_probe, +@@ -2270,11 +2270,11 @@ static int ftdi_sio_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); ++ + ftdi_determine_type(port); + ftdi_set_max_packet_size(port); + if (read_latency_timer(port) < 0) +@@ -2295,8 +2295,10 @@ static int ftdi_sio_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; +@@ -2305,8 +2307,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 e8b699ce98a2 -r 407bae787996 5.12/0002-USB-serial-ftdi_sio-add-support-for-FreeCalypso-DUAR.patch --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/5.12/0002-USB-serial-ftdi_sio-add-support-for-FreeCalypso-DUAR.patch Mon Dec 11 06:29:33 2023 +0000 @@ -0,0 +1,163 @@ +From f44a0870903a9b01eb348018bcdb1f4d73e057a8 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 0525dab7c281..56f2d23460dd 100644 +--- a/drivers/usb/serial/ftdi_sio.c ++++ b/drivers/usb/serial/ftdi_sio.c +@@ -69,6 +69,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; +@@ -97,6 +99,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_sio_quirk ftdi_jtag_quirk = { + .probe = ftdi_jtag_probe, +@@ -122,6 +125,10 @@ static const struct ftdi_sio_quirk ftdi_8u2232c_quirk = { + .probe = ftdi_8u2232c_probe, + }; + ++static const struct ftdi_sio_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: +@@ -1042,6 +1049,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 */ + }; + +@@ -2404,6 +2413,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_sio_port_remove(struct usb_serial_port *port) + { + struct ftdi_private *priv = usb_get_serial_port_data(port); +@@ -2453,10 +2495,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); + } + +@@ -2804,7 +2854,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 3d47c6d72256..3081b8916a0a 100644 +--- a/drivers/usb/serial/ftdi_sio_ids.h ++++ b/drivers/usb/serial/ftdi_sio_ids.h +@@ -45,6 +45,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 +