lkml.org 
[lkml]   [2020]   [Nov]   [30]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5/5] USB: serial: ftdi_sio: add support for FreeCalypso DUART28C adapter
    Date
    From: "Mychaela N. Falconia" <falcon@freecalypso.org>

    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 <falcon@freecalypso.org>
    [johan: reimplement using new NORDY flag, trim quirk comment]
    Signed-off-by: Johan Hovold <johan@kernel.org>
    ---
    drivers/usb/serial/ftdi_sio.c | 22 ++++++++++++++++++++++
    drivers/usb/serial/ftdi_sio_ids.h | 1 +
    2 files changed, 23 insertions(+)

    diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
    index b69032c9ec2b..b555bbc1b0a9 100644
    --- a/drivers/usb/serial/ftdi_sio.c
    +++ b/drivers/usb/serial/ftdi_sio.c
    @@ -97,6 +97,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 +123,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 +1047,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 */
    };

    @@ -2386,6 +2393,21 @@ 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.
    + */
    +static void ftdi_duart28c_setup(struct usb_serial_port *port)
    +{
    + struct usb_serial *serial = port->serial;
    + struct usb_interface *intf = serial->interface;
    + int ifnum = intf->cur_altsetting->desc.bInterfaceNumber;
    +
    + if (ifnum == 1)
    + tty_port_set_nordy(&port->port, 1);
    +}
    +
    static int ftdi_sio_port_remove(struct usb_serial_port *port)
    {
    struct ftdi_private *priv = usb_get_serial_port_data(port);
    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.26.2
    \
     
     \ /
      Last update: 2020-11-30 16:39    [W:4.121 / U:0.048 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site