Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 25 Jun 2025 07:45:51 +0200 (CEST)
From:      Ronald Klop <ronald-lists@klop.ws>
To:        Kevin Lo <kevlo@FreeBSD.org>
Cc:        dev-commits-src-all@FreeBSD.org, src-committers@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   Re: git: 1395712cab8e - main - uchcom: add support for CH9102  and CH343 uarts
Message-ID:  <727722724.560.1750830351345@localhost>
In-Reply-To: <202506250136.55P1aag8094334@gitrepo.freebsd.org>
References:  <202506250136.55P1aag8094334@gitrepo.freebsd.org>

next in thread | previous in thread | raw e-mail | index | archive | help
------=_Part_559_1619721974.1750830351251
Content-Type: text/plain; charset=us-ascii; format=flowed
Content-Transfer-Encoding: 7bit

Hi,

nice work!

Isn't the HARDWARE section in the man page used to generate a supported hardware list in the release notes of a new FreeBSD version?

Regards,
Ronald.

 
Van: Kevin Lo <kevlo@FreeBSD.org>
Datum:woensdag, 25 juni 2025 03:36
Aan:src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Onderwerp:git: 1395712cab8e - main - uchcom: add support for CH9102 and CH343 uarts
> 
> The branch main has been updated by kevlo:
> 
> URL: https://cgit.FreeBSD.org/src/commit/?id=1395712cab8e95808064ba68c5a792b7cd0fe35f
> 
> commit 1395712cab8e95808064ba68c5a792b7cd0fe35f
> Author:     Kevin Lo <kevlo@FreeBSD.org>
> AuthorDate: 2025-06-25 01:33:35 +0000
> Commit:     Kevin Lo <kevlo@FreeBSD.org>
> CommitDate: 2025-06-25 01:33:35 +0000
> 
>     uchcom: add support for CH9102 and CH343 uarts
>     
>     The CH343 devices support any baud rate up to 6 Mbps.
>     PR:     272803
>     Reviewed by:    imp
>     Tested by:      joerg, Tomasz "CeDeROM" CEDRO <tomek_AT_cedro_DOT_info>
>     Differential Revision:  https://reviews.freebsd.org/D46290
> ---
>  share/man/man4/uchcom.4     |  27 +---
>  sys/dev/usb/serial/uchcom.c | 353 +++++++++++++++++++++++++-------------------
>  sys/dev/usb/usbdevs         |   4 +-
>  3 files changed, 208 insertions(+), 176 deletions(-)
> 
> diff --git a/share/man/man4/uchcom.4 b/share/man/man4/uchcom.4
> index d5efe83286ba..4d395573589f 100644
> --- a/share/man/man4/uchcom.4
> +++ b/share/man/man4/uchcom.4
> @@ -27,12 +27,12 @@
>  .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
>  .\" POSSIBILITY OF SUCH DAMAGE.
>  .\"
> -.Dd April 26, 2017
> +.Dd August 19, 2024
>  .Dt UCHCOM 4
>  .Os
>  .Sh NAME
>  .Nm uchcom
> -.Nd WinChipHead CH341/CH340 serial adapter driver
> +.Nd WinChipHead CH9102/CH343/CH341/CH340 serial adapter driver
>  .Sh SYNOPSIS
>  To compile this driver into the kernel,
>  place the following lines in your
> @@ -52,22 +52,12 @@ uchcom_load="YES"
>  .Sh DESCRIPTION
>  The
>  .Nm
> -driver provides support for the WinChipHead CH341/CH340 USB-to-RS-232
> -Bridge chip.
> +driver provides support for the WinChipHead CH9102/CH343/CH341/CH340
> +USB-to-RS-232 Bridge chip.
>  .Pp
> -The device is accessed through the
> -.Xr ucom 4
> -driver which makes it behave like a
> -.Xr tty 4 .
> -.Sh HARDWARE
> -The
> -.Nm
> -driver supports the following adapters:
> -.Pp
> -.Bl -bullet -compact
> -.It
> -HL USB-RS232
> -.El
> +The datasheets for the CH340/CH341 list the maximum
> +supported baud rate as 2,000,000.
> +CH9102/CH343 devices support any baud rate up to 6 Mbps.
>  .Sh FILES
>  .Bl -tag -width "/dev/ttyU*.init" -compact
>  .It Pa /dev/ttyU*
> @@ -95,6 +85,3 @@ The first
>  .Fx
>  release to include it was
>  .Fx 8.0 .
> -.Sh BUGS
> -Actually, this chip seems unable to drive other than 8 data bits and
> -1 stop bit line.
> diff --git a/sys/dev/usb/serial/uchcom.c b/sys/dev/usb/serial/uchcom.c
> index a886b25c89d7..fdc5515fa722 100644
> --- a/sys/dev/usb/serial/uchcom.c
> +++ b/sys/dev/usb/serial/uchcom.c
> @@ -58,8 +58,7 @@
>   */
>  
>  /*
> - * Driver for WinChipHead CH341/340, the worst USB-serial chip in the
> - * world.
> + * Driver for WinChipHead CH9102/343/341/340.
>   */
>  
>  #include <sys/stdint.h>
> @@ -101,17 +100,19 @@ SYSCTL_INT(_hw_usb_uchcom, OID_AUTO, debug, CTLFLAG_RWTUN,
>      &uchcom_debug, 0, "uchcom debug level");
>  #endif
>  
> -#define    UCHCOM_IFACE_INDEX  0
> -#define    UCHCOM_CONFIG_INDEX 0
> +#define    UCHCOM_IFACE_INDEX      0
> +#define    UCHCOM_CONFIG_INDEX     0
> +#define    UCHCOM_SECOND_IFACE_INDEX   1
>  
>  #define    UCHCOM_REV_CH340    0x0250
>  #define    UCHCOM_INPUT_BUF_SIZE   8
>  
> -#define    UCHCOM_REQ_GET_VERSION  0x5F
> -#define    UCHCOM_REQ_READ_REG 0x95
> -#define    UCHCOM_REQ_WRITE_REG    0x9A
> -#define    UCHCOM_REQ_RESET    0xA1
> -#define    UCHCOM_REQ_SET_DTRRTS   0xA4
> +#define    UCHCOM_REQ_GET_VERSION      0x5F
> +#define    UCHCOM_REQ_READ_REG     0x95
> +#define    UCHCOM_REQ_WRITE_REG        0x9A
> +#define    UCHCOM_REQ_RESET        0xA1
> +#define    UCHCOM_REQ_SET_DTRRTS       0xA4
> +#define UCHCOM_REQ_CH343_WRITE_REG 0xA8
>  
>  #define    UCHCOM_REG_STAT1    0x06
>  #define    UCHCOM_REG_STAT2    0x07
> @@ -134,13 +135,21 @@ SYSCTL_INT(_hw_usb_uchcom, OID_AUTO, debug, CTLFLAG_RWTUN,
>  #define    UCHCOM_RTS_MASK     0x40
>  
>  #define    UCHCOM_BRK_MASK     0x01
> +#define    UCHCOM_ABRK_MASK    0x10
> +#define    UCHCOM_CH343_BRK_MASK   0x80
>  
>  #define    UCHCOM_LCR1_MASK    0xAF
>  #define    UCHCOM_LCR2_MASK    0x07
>  #define    UCHCOM_LCR1_RX      0x80
>  #define    UCHCOM_LCR1_TX      0x40
>  #define    UCHCOM_LCR1_PARENB  0x08
> +#define    UCHCOM_LCR1_CS5     0x00
> +#define    UCHCOM_LCR1_CS6     0x01
> +#define    UCHCOM_LCR1_CS7     0x02
>  #define    UCHCOM_LCR1_CS8     0x03
> +#define    UCHCOM_LCR1_STOPB   0x04
> +#define    UCHCOM_LCR1_PARODD  0x00
> +#define    UCHCOM_LCR1_PAREVEN 0x10
>  #define    UCHCOM_LCR2_PAREVEN 0x07
>  #define    UCHCOM_LCR2_PARODD  0x06
>  #define    UCHCOM_LCR2_PARMARK 0x05
> @@ -150,12 +159,18 @@ SYSCTL_INT(_hw_usb_uchcom, OID_AUTO, debug, CTLFLAG_RWTUN,
>  #define    UCHCOM_INTR_STAT2   0x03
>  #define    UCHCOM_INTR_LEAST   4
>  
> -#define    UCHCOM_BULK_BUF_SIZE 1024   /* bytes */
> +#define    UCHCOM_T        0x08
> +#define    UCHCOM_CL       0x04
> +#define    UCHCOM_CH343_CT     0x80
> +#define    UCHCOM_CT       0x90
> +
> +#define    UCHCOM_BULK_BUF_SIZE    1024    /* bytes */
> +
> +#define    TYPE_CH343      1
>  
>  enum {
>     UCHCOM_BULK_DT_WR,
>     UCHCOM_BULK_DT_RD,
> -   UCHCOM_INTR_DT_RD,
>     UCHCOM_N_TRANSFER,
>  };
>  
> @@ -164,6 +179,7 @@ struct uchcom_softc {
>     struct ucom_softc sc_ucom;
>  
>     struct usb_xfer *sc_xfer[UCHCOM_N_TRANSFER];
> +   struct usb_xfer *sc_intr_xfer;  /* Interrupt endpoint */
>     struct usb_device *sc_udev;
>     struct mtx sc_mtx;
>  
> @@ -171,39 +187,19 @@ struct uchcom_softc {
>     uint8_t sc_rts;         /* local copy */
>     uint8_t sc_version;
>     uint8_t sc_msr;
> -   uint8_t sc_lsr;         /* local status register */
> -};
> -
> -struct uchcom_divider {
> -   uint8_t dv_prescaler;
> -   uint8_t dv_div;
> -   uint8_t dv_mod;
> -};
> -
> -struct uchcom_divider_record {
> -   uint32_t dvr_high;
> -   uint32_t dvr_low;
> -   uint32_t dvr_base_clock;
> -   struct uchcom_divider dvr_divider;
> -};
> -
> -static const struct uchcom_divider_record dividers[] =
> -{
> -   {307200, 307200, UCHCOM_BASE_UNKNOWN, {7, 0xD9, 0}},
> -   {921600, 921600, UCHCOM_BASE_UNKNOWN, {7, 0xF3, 0}},
> -   {2999999, 23530, 6000000, {3, 0, 0}},
> -   {23529, 2942, 750000, {2, 0, 0}},
> -   {2941, 368, 93750, {1, 0, 0}},
> -   {367, 1, 11719, {0, 0, 0}},
> +   uint8_t sc_lsr;         /* local status register */
> +   uint8_t sc_chiptype;        /* type of chip */
> +   uint8_t sc_ctrl_iface_no;
> +   uint8_t sc_iface_index;
>  };
>  
> -#define    NUM_DIVIDERS    nitems(dividers)
> -
>  static const STRUCT_USB_HOST_ID uchcom_devs[] = {
>     {USB_VPI(USB_VENDOR_WCH, USB_PRODUCT_WCH_CH341SER, 0)},
>     {USB_VPI(USB_VENDOR_WCH2, USB_PRODUCT_WCH2_CH341SER, 0)},
>     {USB_VPI(USB_VENDOR_WCH2, USB_PRODUCT_WCH2_CH341SER_2, 0)},
>     {USB_VPI(USB_VENDOR_WCH2, USB_PRODUCT_WCH2_CH341SER_3, 0)},
> +   {USB_VPI(USB_VENDOR_WCH2, USB_PRODUCT_WCH2_CH343SER, 0)},
> +   {USB_VPI(USB_VENDOR_WCH2, USB_PRODUCT_WCH2_CH9102SER, 0)},
>  };
>  
>  /* protypes */
> @@ -225,8 +221,9 @@ static void uchcom_update_version(struct uchcom_softc *);
>  static void    uchcom_convert_status(struct uchcom_softc *, uint8_t);
>  static void    uchcom_update_status(struct uchcom_softc *);
>  static void    uchcom_set_dtr_rts(struct uchcom_softc *);
> -static int uchcom_calc_divider_settings(struct uchcom_divider *, uint32_t);
> -static void    uchcom_set_baudrate(struct uchcom_softc *, uint32_t);
> +static void    uchcom_calc_baudrate(struct uchcom_softc *, uint32_t, uint8_t *,
> +           uint8_t *);
> +static void    uchcom_set_baudrate(struct uchcom_softc *, uint32_t, uint16_t);
>  static void    uchcom_poll(struct ucom_softc *ucom);
>  
>  static device_probe_t uchcom_probe;
> @@ -244,7 +241,7 @@ static const struct usb_config uchcom_config_data[UCHCOM_N_TRANSFER] = {
>         .endpoint = UE_ADDR_ANY,
>         .direction = UE_DIR_OUT,
>         .bufsize = UCHCOM_BULK_BUF_SIZE,
> -       .flags = {.pipe_bof = 1,.force_short_xfer = 1,},
> +       .flags = {.pipe_bof = 1,},
>         .callback = &uchcom_write_callback,
>     },
>  
> @@ -256,8 +253,10 @@ static const struct usb_config uchcom_config_data[UCHCOM_N_TRANSFER] = {
>         .flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
>         .callback = &uchcom_read_callback,
>     },
> +};
>  
> -   [UCHCOM_INTR_DT_RD] = {
> +static const struct usb_config uchcom_intr_config_data[1] = {
> +   [0] = {
>         .type = UE_INTERRUPT,
>         .endpoint = UE_ADDR_ANY,
>         .direction = UE_DIR_IN,
> @@ -311,8 +310,9 @@ uchcom_attach(device_t dev)
>  {
>     struct uchcom_softc *sc = device_get_softc(dev);
>     struct usb_attach_arg *uaa = device_get_ivars(dev);
> +   struct usb_interface *iface;
> +   struct usb_interface_descriptor *id;
>     int error;
> -   uint8_t iface_index;
>  
>     DPRINTFN(11, "\n");
>  
> @@ -330,20 +330,49 @@ uchcom_attach(device_t dev)
>     case USB_PRODUCT_WCH2_CH341SER_3:
>         device_printf(dev, "CH341 detected\n");
>         break;
> +   case USB_PRODUCT_WCH2_CH343SER:
> +       device_printf(dev, "CH343 detected\n");
> +       break;
> +   case USB_PRODUCT_WCH2_CH9102SER:
> +       device_printf(dev, "CH9102 detected\n");
> +       break;
>     default:
> -       device_printf(dev, "New CH340/CH341 product 0x%04x detected\n",
> -           uaa->info.idProduct);
> +       device_printf(dev, "New CH340/CH341/CH343/CH9102 product "
> +           "0x%04x detected\n", uaa->info.idProduct);
>         break;
>     }
>  
> -   iface_index = UCHCOM_IFACE_INDEX;
> -   error = usbd_transfer_setup(uaa->device,
> -       &iface_index, sc->sc_xfer, uchcom_config_data,
> -       UCHCOM_N_TRANSFER, sc, &sc->sc_mtx);
> +   /* CH343/CH9102 has two interfaces. */
> +   sc->sc_ctrl_iface_no = uaa->info.bIfaceNum;
>  
> +   iface = usbd_get_iface(uaa->device, UCHCOM_SECOND_IFACE_INDEX);
> +   if (iface) {
> +       id = usbd_get_interface_descriptor(iface);
> +       if (id == NULL) {
> +           device_printf(dev, "no interface descriptor\n");
> +           goto detach;
> +       }
> +       sc->sc_iface_index = UCHCOM_SECOND_IFACE_INDEX;
> +       usbd_set_parent_iface(uaa->device, UCHCOM_SECOND_IFACE_INDEX,
> +           uaa->info.bIfaceIndex);
> +       sc->sc_chiptype = TYPE_CH343;
> +   } else {
> +       sc->sc_iface_index = UCHCOM_IFACE_INDEX;
> +   }
> +
> +   /* Setup all transfers. */
> +   error = usbd_transfer_setup(uaa->device, &sc->sc_iface_index,
> +       sc->sc_xfer, uchcom_config_data, UCHCOM_N_TRANSFER, sc,
> +       &sc->sc_mtx);
> +   if (error) {
> +       device_printf(dev, "could not allocate all pipes\n");
> +       goto detach;
> +   }
> +   error = usbd_transfer_setup(uaa->device, &sc->sc_ctrl_iface_no,
> +       &sc->sc_intr_xfer, uchcom_intr_config_data, 1, sc, &sc->sc_mtx);
>     if (error) {
> -       DPRINTF("one or more missing USB endpoints, "
> -           "error=%s\n", usbd_errstr(error));
> +       device_printf(dev, "allocating USB transfers failed for "
> +           "interrupt\n");
>         goto detach;
>     }
>  
> @@ -449,7 +478,9 @@ uchcom_write_reg(struct uchcom_softc *sc,
>         (unsigned)reg1, (unsigned)val1,
>         (unsigned)reg2, (unsigned)val2);
>     uchcom_ctrl_write(
> -       sc, UCHCOM_REQ_WRITE_REG,
> +       sc,
> +       (sc->sc_chiptype != TYPE_CH343) ?
> +       UCHCOM_REQ_WRITE_REG : UCHCOM_REQ_CH343_WRITE_REG,
>         reg1 | ((uint16_t)reg2 << 8), val1 | ((uint16_t)val2 << 8));
>  }
>  
> @@ -516,9 +547,6 @@ uchcom_update_version(struct uchcom_softc *sc)
>  static void
>  uchcom_convert_status(struct uchcom_softc *sc, uint8_t cur)
>  {
> -   sc->sc_dtr = !(cur & UCHCOM_DTR_MASK);
> -   sc->sc_rts = !(cur & UCHCOM_RTS_MASK);
> -
>     cur = ~cur & 0x0F;
>     sc->sc_msr = (cur << 4) | ((sc->sc_msr >> 4) ^ cur);
>  }
> @@ -555,78 +583,69 @@ uchcom_cfg_set_break(struct ucom_softc *ucom, uint8_t onoff)
>     uint8_t brk1;
>     uint8_t brk2;
>  
> -   uchcom_read_reg(sc, UCHCOM_REG_BREAK1, &brk1, UCHCOM_REG_LCR1, &brk2);
> -   if (onoff) {
> -       /* on - clear bits */
> -       brk1 &= ~UCHCOM_BRK_MASK;
> -       brk2 &= ~UCHCOM_LCR1_TX;
> +   if (sc->sc_chiptype == TYPE_CH343) {
> +       brk1 = UCHCOM_CH343_BRK_MASK;
> +       if (!onoff)
> +           brk1 |= UCHCOM_ABRK_MASK;
> +       uchcom_write_reg(sc, brk1, 0, 0, 0);
>     } else {
> -       /* off - set bits */
> -       brk1 |= UCHCOM_BRK_MASK;
> -       brk2 |= UCHCOM_LCR1_TX;
> +       uchcom_read_reg(sc, UCHCOM_REG_BREAK1, &brk1, UCHCOM_REG_LCR1,
> +           &brk2);
> +       if (onoff) {
> +           /* on - clear bits */
> +           brk1 &= ~UCHCOM_BRK_MASK;
> +           brk2 &= ~UCHCOM_LCR1_TX;
> +       } else {
> +           /* off - set bits */
> +           brk1 |= UCHCOM_BRK_MASK;
> +           brk2 |= UCHCOM_LCR1_TX;
> +       }
> +       uchcom_write_reg(sc, UCHCOM_REG_BREAK1, brk1, UCHCOM_REG_LCR1,
> +           brk2);
>     }
> -   uchcom_write_reg(sc, UCHCOM_REG_BREAK1, brk1, UCHCOM_REG_LCR1, brk2);
>  }
>  
> -static int
> -uchcom_calc_divider_settings(struct uchcom_divider *dp, uint32_t rate)
> -{
> -   const struct uchcom_divider_record *rp;
> -   uint32_t div;
> -   uint32_t rem;
> -   uint32_t mod;
> -   uint8_t i;
> -
> -   /* find record */
> -   for (i = 0; i != NUM_DIVIDERS; i++) {
> -       if (dividers[i].dvr_high >= rate &&
> -           dividers[i].dvr_low <= rate) {
> -           rp = &dividers[i];
> -           goto found;
> -       }
> -   }
> -   return (-1);
> -
> -found:
> -   dp->dv_prescaler = rp->dvr_divider.dv_prescaler;
> -   if (rp->dvr_base_clock == UCHCOM_BASE_UNKNOWN)
> -       dp->dv_div = rp->dvr_divider.dv_div;
> -   else {
> -       div = rp->dvr_base_clock / rate;
> -       rem = rp->dvr_base_clock % rate;
> -       if (div == 0 || div >= 0xFF)
> -           return (-1);
> -       if ((rem << 1) >= rate)
> -           div += 1;
> -       dp->dv_div = (uint8_t)-div;
> +static void
> +uchcom_calc_baudrate(struct uchcom_softc *sc, uint32_t rate, uint8_t *divisor,
> +    uint8_t *factor)
> +{
> +   uint32_t clk = 12000000;
> +
> +   if (rate >= 256000 && sc->sc_chiptype == TYPE_CH343)
> +       *divisor = 7;
> +   else if (rate > 23529) {
> +       clk /= 2;
> +       *divisor = 3;
> +   } else if (rate > 2941) {
> +       clk /=  16;
> +       *divisor = 2;
> +   } else if (rate > 367) {
> +       clk /= 128;
> +       *divisor = 1;
> +   } else {
> +       clk = 11719;
> +       *divisor = 0;
>     }
>  
> -   mod = (UCHCOM_BPS_MOD_BASE / rate) + UCHCOM_BPS_MOD_BASE_OFS;
> -   mod = mod + (mod / 2);
> +   *factor = 256 - clk / rate;
>  
> -   dp->dv_mod = (mod + 0xFF) / 0x100;
> -
> -   return (0);
> +   if (rate == 921600 && sc->sc_chiptype != TYPE_CH343) {
> +       *divisor = 7;
> +       *factor = 243;
> +   }
>  }
>  
>  static void
> -uchcom_set_baudrate(struct uchcom_softc *sc, uint32_t rate)
> +uchcom_set_baudrate(struct uchcom_softc *sc, uint32_t rate, uint16_t lcr)
>  {
> -   struct uchcom_divider dv;
> +   uint16_t idx;
> +   uint8_t factor, div;
>  
> -   if (uchcom_calc_divider_settings(&dv, rate))
> -       return;
> +   uchcom_calc_baudrate(sc, rate, &div, &factor);
> +   div |= (sc->sc_chiptype != TYPE_CH343) ? 0x80 : 0x00;
> +   idx = (factor << 8) | div;
>  
> -   /*
> -    * According to linux code we need to set bit 7 of UCHCOM_REG_BPS_PRE,
> -    * otherwise the chip will buffer data.
> -    */
> -   uchcom_write_reg(sc,
> -       UCHCOM_REG_BPS_PRE, dv.dv_prescaler | 0x80,
> -       UCHCOM_REG_BPS_DIV, dv.dv_div);
> -   uchcom_write_reg(sc,
> -       UCHCOM_REG_BPS_MOD, dv.dv_mod,
> -       UCHCOM_REG_BPS_PAD, 0);
> +   uchcom_ctrl_write(sc, UCHCOM_REQ_RESET, lcr, idx);
>  }
>  
>  /* ----------------------------------------------------------------------
> @@ -673,6 +692,14 @@ uchcom_cfg_open(struct ucom_softc *ucom)
>  
>     DPRINTF("\n");
>  
> +   if (sc->sc_chiptype != TYPE_CH343) {
> +       /* Set default configuration. */
> +       uchcom_get_version(sc, NULL);
> +       uchcom_ctrl_write(sc, UCHCOM_REQ_RESET, 0, 0);
> +       uchcom_write_reg(sc, UCHCOM_REG_BPS_PRE, 0x82,
> +           UCHCOM_REG_BPS_DIV, 0xd9);
> +       uchcom_write_reg(sc, 0x2c, 0x07, UCHCOM_REG_BPS_PAD, 0);
> +   }
>     uchcom_update_version(sc);
>     uchcom_update_status(sc);
>  }
> @@ -680,53 +707,69 @@ uchcom_cfg_open(struct ucom_softc *ucom)
>  static int
>  uchcom_pre_param(struct ucom_softc *ucom, struct termios *t)
>  {
> -   struct uchcom_divider dv;
> +   struct uchcom_softc *sc = ucom->sc_parent;
>  
> -   switch (t->c_cflag & CSIZE) {
> -   case CS8:
> +   /*
> +    * Check requested baud rate.
> +    * The CH340/CH341 can set any baud rate up to 2Mb.
> +    * The CH9102/CH343 can set any baud rate up to 6Mb.
> +    */
> +   switch (sc->sc_chiptype) {
> +   case TYPE_CH343:
> +       if (t->c_ospeed <= 6000000)
> +           return (0);
>         break;
>     default:
> -       return (EIO);
> +       if (t->c_ospeed <= 2000000)
> +           return (0);
> +       break;
>     }
> -   if ((t->c_cflag & CSTOPB) != 0)
> -       return (EIO);
> -   if ((t->c_cflag & PARENB) != 0)
> -       return (EIO);
>  
> -   if (uchcom_calc_divider_settings(&dv, t->c_ospeed)) {
> -       return (EIO);
> -   }
> -   return (0);         /* success */
> +   return (EIO);
>  }
>  
>  static void
>  uchcom_cfg_param(struct ucom_softc *ucom, struct termios *t)
>  {
>     struct uchcom_softc *sc = ucom->sc_parent;
> +   uint8_t lcr;
>  
> -   uchcom_get_version(sc, NULL);
> -   uchcom_ctrl_write(sc, UCHCOM_REQ_RESET, 0, 0);
> -   uchcom_set_baudrate(sc, t->c_ospeed);
> -   if (sc->sc_version < UCHCOM_VER_30) {
> -       uchcom_read_reg(sc, UCHCOM_REG_LCR1, NULL,
> -           UCHCOM_REG_LCR2, NULL);
> -       uchcom_write_reg(sc, UCHCOM_REG_LCR1, 0x50,
> -           UCHCOM_REG_LCR2, 0x00);
> -   } else {
> -       /*
> -        * Set up line control:
> -        * - enable transmit and receive
> -        * - set 8n1 mode
> -        * To do: support other sizes, parity, stop bits.
> -        */
> -       uchcom_write_reg(sc,
> -           UCHCOM_REG_LCR1,
> -           UCHCOM_LCR1_RX | UCHCOM_LCR1_TX | UCHCOM_LCR1_CS8,
> -           UCHCOM_REG_LCR2, 0x00);
> +   lcr = UCHCOM_LCR1_RX | UCHCOM_LCR1_TX;
> +
> +   if (t->c_cflag & CSTOPB)
> +       lcr |= UCHCOM_LCR1_STOPB;
> +
> +   if (t->c_cflag & PARENB) {
> +       lcr |= UCHCOM_LCR1_PARENB;
> +       if (t->c_cflag & PARODD)
> +           lcr |= UCHCOM_LCR1_PARODD;
> +       else
> +           lcr |= UCHCOM_LCR1_PAREVEN;
>     }
> -   uchcom_update_status(sc);
> -   uchcom_ctrl_write(sc, UCHCOM_REQ_RESET, 0x501f, 0xd90a);
> -   uchcom_set_baudrate(sc, t->c_ospeed);
> +
> +   switch (t->c_cflag & CSIZE) {
> +   case CS5:
> +       lcr |= UCHCOM_LCR1_CS5;
> +       break;
> +   case CS6:
> +       lcr |= UCHCOM_LCR1_CS6;
> +       break;
> +   case CS7:
> +       lcr |= UCHCOM_LCR1_CS7;
> +       break;
> +   case CS8:
> +   default:
> +       lcr |= UCHCOM_LCR1_CS8;
> +       break;
> +   }
> +
> +   if (sc->sc_chiptype == TYPE_CH343)
> +       uchcom_set_baudrate(sc, t->c_ospeed,
> +           UCHCOM_T | UCHCOM_CL | UCHCOM_CH343_CT | lcr << 8);
> +   else
> +       uchcom_set_baudrate(sc, t->c_ospeed,
> +           UCHCOM_T | UCHCOM_CL | UCHCOM_CT | lcr << 8);
> +
>     uchcom_set_dtr_rts(sc);
>     uchcom_update_status(sc);
>  }
> @@ -737,7 +780,7 @@ uchcom_start_read(struct ucom_softc *ucom)
>     struct uchcom_softc *sc = ucom->sc_parent;
>  
>     /* start interrupt endpoint */
> -   usbd_transfer_start(sc->sc_xfer[UCHCOM_INTR_DT_RD]);
> +   usbd_transfer_start(sc->sc_intr_xfer);
>  
>     /* start read endpoint */
>     usbd_transfer_start(sc->sc_xfer[UCHCOM_BULK_DT_RD]);
> @@ -749,7 +792,7 @@ uchcom_stop_read(struct ucom_softc *ucom)
>     struct uchcom_softc *sc = ucom->sc_parent;
>  
>     /* stop interrupt endpoint */
> -   usbd_transfer_stop(sc->sc_xfer[UCHCOM_INTR_DT_RD]);
> +   usbd_transfer_stop(sc->sc_intr_xfer);
>  
>     /* stop read endpoint */
>     usbd_transfer_stop(sc->sc_xfer[UCHCOM_BULK_DT_RD]);
> @@ -779,7 +822,8 @@ uchcom_intr_callback(struct usb_xfer *xfer, usb_error_t error)
>  {
>     struct uchcom_softc *sc = usbd_xfer_softc(xfer);
>     struct usb_page_cache *pc;
> -   uint8_t buf[UCHCOM_INTR_LEAST];
> +   uint32_t intrstat;
> +   uint8_t buf[16];
>     int actlen;
>  
>     usbd_xfer_status(xfer, &actlen, NULL, NULL, NULL);
> @@ -791,13 +835,12 @@ uchcom_intr_callback(struct usb_xfer *xfer, usb_error_t error)
>  
>         if (actlen >= UCHCOM_INTR_LEAST) {
>             pc = usbd_xfer_get_frame(xfer, 0);
> -           usbd_copy_out(pc, 0, buf, UCHCOM_INTR_LEAST);
> +           usbd_copy_out(pc, 0, buf, sizeof(buf));
>  
> -           DPRINTF("data = 0x%02X 0x%02X 0x%02X 0x%02X\n",
> -               (unsigned)buf[0], (unsigned)buf[1],
> -               (unsigned)buf[2], (unsigned)buf[3]);
> +           intrstat = (sc->sc_chiptype == TYPE_CH343) ?
> +               actlen - 1 : UCHCOM_INTR_STAT1;
>  
> -           uchcom_convert_status(sc, buf[UCHCOM_INTR_STAT1]);
> +           uchcom_convert_status(sc, buf[intrstat]);
>             ucom_status_change(&sc->sc_ucom);
>         }
>     case USB_ST_SETUP:
> diff --git a/sys/dev/usb/usbdevs b/sys/dev/usb/usbdevs
> index f26edcebcb9c..2318e6bd0017 100644
> --- a/sys/dev/usb/usbdevs
> +++ b/sys/dev/usb/usbdevs
> @@ -4972,9 +4972,11 @@ product WAVESENSE JAZZ       0xaaaa  Jazz blood glucose meter
>  /* WCH products */
>  product WCH CH341SER       0x5523  CH341/CH340 USB-Serial Bridge
>  product WCH2 CH341SER_2        0x5523  CH341/CH340 USB-Serial Bridge
> +product WCH2 CH343SER      0x55d3  CH343 USB Serial
> +product WCH2 CH9102SER     0x55d4  CH9102 USB Serial
>  product WCH2 CH341SER_3        0x7522  CH341/CH340 USB-Serial Bridge
>  product WCH2 CH341SER      0x7523  CH341/CH340 USB-Serial Bridge
> -product WCH2 U2M       0X752d  CH345 USB2.0-MIDI
> +product WCH2 U2M       0x752d  CH345 USB2.0-MIDI
>  
>  /* West Mountain Radio products */
>  product WESTMOUNTAIN RIGBLASTER_ADVANTAGE  0x0003  RIGblaster Advantage
>  
> 
> 
> 

 
------=_Part_559_1619721974.1750830351251
Content-Type: text/html; charset=us-ascii
Content-Transfer-Encoding: 7bit

<html><head></head><body>Hi,<br>
<br>
nice work!<br>
<br>
Isn't the HARDWARE section in the man page used to generate a supported hardware list in the release notes of a new FreeBSD version?<br>
<br>
Regards,<br>
Ronald.<br>
<br>
&nbsp;
<p><strong>Van:</strong> Kevin Lo &lt;kevlo@FreeBSD.org&gt;<br>
<strong>Datum:</strong>woensdag, 25 juni 2025 03:36<br>
<strong>Aan:</strong>src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org<br>
<strong>Onderwerp:</strong>git: 1395712cab8e - main - uchcom: add support for CH9102 and CH343 uarts</p>

<blockquote style="padding-right: 0px; padding-left: 5px; margin-left: 5px; border-left: #000000 2px solid; margin-right: 0px">
<div class="MessageRFC822Viewer" id="P">
<div class="TextPlainViewer" id="P.P">The branch main has been updated by kevlo:<br>
<br>
URL: <a href="https://cgit.FreeBSD.org/src/commit/?id=1395712cab8e95808064ba68c5a792b7cd0fe35f">https://cgit.FreeBSD.org/src/commit/?id=1395712cab8e95808064ba68c5a792b7cd0fe35f</a><br>;
<br>
commit 1395712cab8e95808064ba68c5a792b7cd0fe35f<br>
Author: &nbsp;&nbsp;&nbsp;&nbsp;Kevin Lo &lt;kevlo@FreeBSD.org&gt;<br>
AuthorDate: 2025-06-25 01:33:35 +0000<br>
Commit: &nbsp;&nbsp;&nbsp;&nbsp;Kevin Lo &lt;kevlo@FreeBSD.org&gt;<br>
CommitDate: 2025-06-25 01:33:35 +0000<br>
<br>
&nbsp;&nbsp;&nbsp;&nbsp;uchcom: add support for CH9102 and CH343 uarts<br>
&nbsp;&nbsp;&nbsp;&nbsp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;The CH343 devices support any baud rate up to 6 Mbps.<br>
&nbsp;&nbsp;&nbsp;&nbsp;PR: &nbsp;&nbsp;&nbsp;&nbsp;272803<br>
&nbsp;&nbsp;&nbsp;&nbsp;Reviewed by: &nbsp;&nbsp;&nbsp;imp<br>
&nbsp;&nbsp;&nbsp;&nbsp;Tested by: &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;joerg, Tomasz "CeDeROM" CEDRO &lt;tomek_AT_cedro_DOT_info&gt;<br>
&nbsp;&nbsp;&nbsp;&nbsp;Differential Revision: &nbsp;<a href="https://reviews.freebsd.org/D46290">https://reviews.freebsd.org/D46290</a><br>;
---<br>
&nbsp;share/man/man4/uchcom.4 &nbsp;&nbsp;&nbsp;&nbsp;| &nbsp;27 +---<br>
&nbsp;sys/dev/usb/serial/uchcom.c | 353 +++++++++++++++++++++++++-------------------<br>
&nbsp;sys/dev/usb/usbdevs &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| &nbsp;&nbsp;4 +-<br>
&nbsp;3 files changed, 208 insertions(+), 176 deletions(-)<br>
<br>
diff --git a/share/man/man4/uchcom.4 b/share/man/man4/uchcom.4<br>
index d5efe83286ba..4d395573589f 100644<br>
--- a/share/man/man4/uchcom.4<br>
+++ b/share/man/man4/uchcom.4<br>
@@ -27,12 +27,12 @@<br>
&nbsp;.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE<br>
&nbsp;.\" POSSIBILITY OF SUCH DAMAGE.<br>
&nbsp;.\"<br>
-.Dd April 26, 2017<br>
+.Dd August 19, 2024<br>
&nbsp;.Dt UCHCOM 4<br>
&nbsp;.Os<br>
&nbsp;.Sh NAME<br>
&nbsp;.Nm uchcom<br>
-.Nd WinChipHead CH341/CH340 serial adapter driver<br>
+.Nd WinChipHead CH9102/CH343/CH341/CH340 serial adapter driver<br>
&nbsp;.Sh SYNOPSIS<br>
&nbsp;To compile this driver into the kernel,<br>
&nbsp;place the following lines in your<br>
@@ -52,22 +52,12 @@ uchcom_load="YES"<br>
&nbsp;.Sh DESCRIPTION<br>
&nbsp;The<br>
&nbsp;.Nm<br>
-driver provides support for the WinChipHead CH341/CH340 USB-to-RS-232<br>
-Bridge chip.<br>
+driver provides support for the WinChipHead CH9102/CH343/CH341/CH340<br>
+USB-to-RS-232 Bridge chip.<br>
&nbsp;.Pp<br>
-The device is accessed through the<br>
-.Xr ucom 4<br>
-driver which makes it behave like a<br>
-.Xr tty 4 .<br>
-.Sh HARDWARE<br>
-The<br>
-.Nm<br>
-driver supports the following adapters:<br>
-.Pp<br>
-.Bl -bullet -compact<br>
-.It<br>
-HL USB-RS232<br>
-.El<br>
+The datasheets for the CH340/CH341 list the maximum<br>
+supported baud rate as 2,000,000.<br>
+CH9102/CH343 devices support any baud rate up to 6 Mbps.<br>
&nbsp;.Sh FILES<br>
&nbsp;.Bl -tag -width "/dev/ttyU*.init" -compact<br>
&nbsp;.It Pa /dev/ttyU*<br>
@@ -95,6 +85,3 @@ The first<br>
&nbsp;.Fx<br>
&nbsp;release to include it was<br>
&nbsp;.Fx 8.0 .<br>
-.Sh BUGS<br>
-Actually, this chip seems unable to drive other than 8 data bits and<br>
-1 stop bit line.<br>
diff --git a/sys/dev/usb/serial/uchcom.c b/sys/dev/usb/serial/uchcom.c<br>
index a886b25c89d7..fdc5515fa722 100644<br>
--- a/sys/dev/usb/serial/uchcom.c<br>
+++ b/sys/dev/usb/serial/uchcom.c<br>
@@ -58,8 +58,7 @@<br>
&nbsp;&nbsp;*/<br>
&nbsp;<br>
&nbsp;/*<br>
- * Driver for WinChipHead CH341/340, the worst USB-serial chip in the<br>
- * world.<br>
+ * Driver for WinChipHead CH9102/343/341/340.<br>
&nbsp;&nbsp;*/<br>
&nbsp;<br>
&nbsp;#include &lt;sys/stdint.h&gt;<br>
@@ -101,17 +100,19 @@ SYSCTL_INT(_hw_usb_uchcom, OID_AUTO, debug, CTLFLAG_RWTUN,<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&amp;uchcom_debug, 0, "uchcom debug level");<br>
&nbsp;#endif<br>
&nbsp;<br>
-#define &nbsp;&nbsp;&nbsp;UCHCOM_IFACE_INDEX &nbsp;0<br>
-#define &nbsp;&nbsp;&nbsp;UCHCOM_CONFIG_INDEX 0<br>
+#define &nbsp;&nbsp;&nbsp;UCHCOM_IFACE_INDEX &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0<br>
+#define &nbsp;&nbsp;&nbsp;UCHCOM_CONFIG_INDEX &nbsp;&nbsp;&nbsp;&nbsp;0<br>
+#define &nbsp;&nbsp;&nbsp;UCHCOM_SECOND_IFACE_INDEX &nbsp;&nbsp;1<br>
&nbsp;<br>
&nbsp;#define &nbsp;&nbsp;&nbsp;UCHCOM_REV_CH340 &nbsp;&nbsp;&nbsp;0x0250<br>
&nbsp;#define &nbsp;&nbsp;&nbsp;UCHCOM_INPUT_BUF_SIZE &nbsp;&nbsp;8<br>
&nbsp;<br>
-#define &nbsp;&nbsp;&nbsp;UCHCOM_REQ_GET_VERSION &nbsp;0x5F<br>
-#define &nbsp;&nbsp;&nbsp;UCHCOM_REQ_READ_REG 0x95<br>
-#define &nbsp;&nbsp;&nbsp;UCHCOM_REQ_WRITE_REG &nbsp;&nbsp;&nbsp;0x9A<br>
-#define &nbsp;&nbsp;&nbsp;UCHCOM_REQ_RESET &nbsp;&nbsp;&nbsp;0xA1<br>
-#define &nbsp;&nbsp;&nbsp;UCHCOM_REQ_SET_DTRRTS &nbsp;&nbsp;0xA4<br>
+#define &nbsp;&nbsp;&nbsp;UCHCOM_REQ_GET_VERSION &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x5F<br>
+#define &nbsp;&nbsp;&nbsp;UCHCOM_REQ_READ_REG &nbsp;&nbsp;&nbsp;&nbsp;0x95<br>
+#define &nbsp;&nbsp;&nbsp;UCHCOM_REQ_WRITE_REG &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x9A<br>
+#define &nbsp;&nbsp;&nbsp;UCHCOM_REQ_RESET &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0xA1<br>
+#define &nbsp;&nbsp;&nbsp;UCHCOM_REQ_SET_DTRRTS &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0xA4<br>
+#define UCHCOM_REQ_CH343_WRITE_REG 0xA8<br>
&nbsp;<br>
&nbsp;#define &nbsp;&nbsp;&nbsp;UCHCOM_REG_STAT1 &nbsp;&nbsp;&nbsp;0x06<br>
&nbsp;#define &nbsp;&nbsp;&nbsp;UCHCOM_REG_STAT2 &nbsp;&nbsp;&nbsp;0x07<br>
@@ -134,13 +135,21 @@ SYSCTL_INT(_hw_usb_uchcom, OID_AUTO, debug, CTLFLAG_RWTUN,<br>
&nbsp;#define &nbsp;&nbsp;&nbsp;UCHCOM_RTS_MASK &nbsp;&nbsp;&nbsp;&nbsp;0x40<br>
&nbsp;<br>
&nbsp;#define &nbsp;&nbsp;&nbsp;UCHCOM_BRK_MASK &nbsp;&nbsp;&nbsp;&nbsp;0x01<br>
+#define &nbsp;&nbsp;&nbsp;UCHCOM_ABRK_MASK &nbsp;&nbsp;&nbsp;0x10<br>
+#define &nbsp;&nbsp;&nbsp;UCHCOM_CH343_BRK_MASK &nbsp;&nbsp;0x80<br>
&nbsp;<br>
&nbsp;#define &nbsp;&nbsp;&nbsp;UCHCOM_LCR1_MASK &nbsp;&nbsp;&nbsp;0xAF<br>
&nbsp;#define &nbsp;&nbsp;&nbsp;UCHCOM_LCR2_MASK &nbsp;&nbsp;&nbsp;0x07<br>
&nbsp;#define &nbsp;&nbsp;&nbsp;UCHCOM_LCR1_RX &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x80<br>
&nbsp;#define &nbsp;&nbsp;&nbsp;UCHCOM_LCR1_TX &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x40<br>
&nbsp;#define &nbsp;&nbsp;&nbsp;UCHCOM_LCR1_PARENB &nbsp;0x08<br>
+#define &nbsp;&nbsp;&nbsp;UCHCOM_LCR1_CS5 &nbsp;&nbsp;&nbsp;&nbsp;0x00<br>
+#define &nbsp;&nbsp;&nbsp;UCHCOM_LCR1_CS6 &nbsp;&nbsp;&nbsp;&nbsp;0x01<br>
+#define &nbsp;&nbsp;&nbsp;UCHCOM_LCR1_CS7 &nbsp;&nbsp;&nbsp;&nbsp;0x02<br>
&nbsp;#define &nbsp;&nbsp;&nbsp;UCHCOM_LCR1_CS8 &nbsp;&nbsp;&nbsp;&nbsp;0x03<br>
+#define &nbsp;&nbsp;&nbsp;UCHCOM_LCR1_STOPB &nbsp;&nbsp;0x04<br>
+#define &nbsp;&nbsp;&nbsp;UCHCOM_LCR1_PARODD &nbsp;0x00<br>
+#define &nbsp;&nbsp;&nbsp;UCHCOM_LCR1_PAREVEN 0x10<br>
&nbsp;#define &nbsp;&nbsp;&nbsp;UCHCOM_LCR2_PAREVEN 0x07<br>
&nbsp;#define &nbsp;&nbsp;&nbsp;UCHCOM_LCR2_PARODD &nbsp;0x06<br>
&nbsp;#define &nbsp;&nbsp;&nbsp;UCHCOM_LCR2_PARMARK 0x05<br>
@@ -150,12 +159,18 @@ SYSCTL_INT(_hw_usb_uchcom, OID_AUTO, debug, CTLFLAG_RWTUN,<br>
&nbsp;#define &nbsp;&nbsp;&nbsp;UCHCOM_INTR_STAT2 &nbsp;&nbsp;0x03<br>
&nbsp;#define &nbsp;&nbsp;&nbsp;UCHCOM_INTR_LEAST &nbsp;&nbsp;4<br>
&nbsp;<br>
-#define &nbsp;&nbsp;&nbsp;UCHCOM_BULK_BUF_SIZE 1024 &nbsp;&nbsp;/* bytes */<br>
+#define &nbsp;&nbsp;&nbsp;UCHCOM_T &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x08<br>
+#define &nbsp;&nbsp;&nbsp;UCHCOM_CL &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x04<br>
+#define &nbsp;&nbsp;&nbsp;UCHCOM_CH343_CT &nbsp;&nbsp;&nbsp;&nbsp;0x80<br>
+#define &nbsp;&nbsp;&nbsp;UCHCOM_CT &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x90<br>
+<br>
+#define &nbsp;&nbsp;&nbsp;UCHCOM_BULK_BUF_SIZE &nbsp;&nbsp;&nbsp;1024 &nbsp;&nbsp;&nbsp;/* bytes */<br>
+<br>
+#define &nbsp;&nbsp;&nbsp;TYPE_CH343 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1<br>
&nbsp;<br>
&nbsp;enum {<br>
&nbsp;&nbsp;&nbsp;&nbsp;UCHCOM_BULK_DT_WR,<br>
&nbsp;&nbsp;&nbsp;&nbsp;UCHCOM_BULK_DT_RD,<br>
- &nbsp;&nbsp;UCHCOM_INTR_DT_RD,<br>
&nbsp;&nbsp;&nbsp;&nbsp;UCHCOM_N_TRANSFER,<br>
&nbsp;};<br>
&nbsp;<br>
@@ -164,6 +179,7 @@ struct uchcom_softc {<br>
&nbsp;&nbsp;&nbsp;&nbsp;struct ucom_softc sc_ucom;<br>
&nbsp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;struct usb_xfer *sc_xfer[UCHCOM_N_TRANSFER];<br>
+ &nbsp;&nbsp;struct usb_xfer *sc_intr_xfer; &nbsp;/* Interrupt endpoint */<br>
&nbsp;&nbsp;&nbsp;&nbsp;struct usb_device *sc_udev;<br>
&nbsp;&nbsp;&nbsp;&nbsp;struct mtx sc_mtx;<br>
&nbsp;<br>
@@ -171,39 +187,19 @@ struct uchcom_softc {<br>
&nbsp;&nbsp;&nbsp;&nbsp;uint8_t sc_rts; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/* local copy */<br>
&nbsp;&nbsp;&nbsp;&nbsp;uint8_t sc_version;<br>
&nbsp;&nbsp;&nbsp;&nbsp;uint8_t sc_msr;<br>
- &nbsp;&nbsp;uint8_t sc_lsr; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/* local status register */<br>
-};<br>
-<br>
-struct uchcom_divider {<br>
- &nbsp;&nbsp;uint8_t dv_prescaler;<br>
- &nbsp;&nbsp;uint8_t dv_div;<br>
- &nbsp;&nbsp;uint8_t dv_mod;<br>
-};<br>
-<br>
-struct uchcom_divider_record {<br>
- &nbsp;&nbsp;uint32_t dvr_high;<br>
- &nbsp;&nbsp;uint32_t dvr_low;<br>
- &nbsp;&nbsp;uint32_t dvr_base_clock;<br>
- &nbsp;&nbsp;struct uchcom_divider dvr_divider;<br>
-};<br>
-<br>
-static const struct uchcom_divider_record dividers[] =<br>
-{<br>
- &nbsp;&nbsp;{307200, 307200, UCHCOM_BASE_UNKNOWN, {7, 0xD9, 0}},<br>
- &nbsp;&nbsp;{921600, 921600, UCHCOM_BASE_UNKNOWN, {7, 0xF3, 0}},<br>
- &nbsp;&nbsp;{2999999, 23530, 6000000, {3, 0, 0}},<br>
- &nbsp;&nbsp;{23529, 2942, 750000, {2, 0, 0}},<br>
- &nbsp;&nbsp;{2941, 368, 93750, {1, 0, 0}},<br>
- &nbsp;&nbsp;{367, 1, 11719, {0, 0, 0}},<br>
+ &nbsp;&nbsp;uint8_t sc_lsr; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/* local status register */<br>
+ &nbsp;&nbsp;uint8_t sc_chiptype; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/* type of chip */<br>
+ &nbsp;&nbsp;uint8_t sc_ctrl_iface_no;<br>
+ &nbsp;&nbsp;uint8_t sc_iface_index;<br>
&nbsp;};<br>
&nbsp;<br>
-#define &nbsp;&nbsp;&nbsp;NUM_DIVIDERS &nbsp;&nbsp;&nbsp;nitems(dividers)<br>
-<br>
&nbsp;static const STRUCT_USB_HOST_ID uchcom_devs[] = {<br>
&nbsp;&nbsp;&nbsp;&nbsp;{USB_VPI(USB_VENDOR_WCH, USB_PRODUCT_WCH_CH341SER, 0)},<br>
&nbsp;&nbsp;&nbsp;&nbsp;{USB_VPI(USB_VENDOR_WCH2, USB_PRODUCT_WCH2_CH341SER, 0)},<br>
&nbsp;&nbsp;&nbsp;&nbsp;{USB_VPI(USB_VENDOR_WCH2, USB_PRODUCT_WCH2_CH341SER_2, 0)},<br>
&nbsp;&nbsp;&nbsp;&nbsp;{USB_VPI(USB_VENDOR_WCH2, USB_PRODUCT_WCH2_CH341SER_3, 0)},<br>
+ &nbsp;&nbsp;{USB_VPI(USB_VENDOR_WCH2, USB_PRODUCT_WCH2_CH343SER, 0)},<br>
+ &nbsp;&nbsp;{USB_VPI(USB_VENDOR_WCH2, USB_PRODUCT_WCH2_CH9102SER, 0)},<br>
&nbsp;};<br>
&nbsp;<br>
&nbsp;/* protypes */<br>
@@ -225,8 +221,9 @@ static void uchcom_update_version(struct uchcom_softc *);<br>
&nbsp;static void &nbsp;&nbsp;&nbsp;uchcom_convert_status(struct uchcom_softc *, uint8_t);<br>
&nbsp;static void &nbsp;&nbsp;&nbsp;uchcom_update_status(struct uchcom_softc *);<br>
&nbsp;static void &nbsp;&nbsp;&nbsp;uchcom_set_dtr_rts(struct uchcom_softc *);<br>
-static int uchcom_calc_divider_settings(struct uchcom_divider *, uint32_t);<br>
-static void &nbsp;&nbsp;&nbsp;uchcom_set_baudrate(struct uchcom_softc *, uint32_t);<br>
+static void &nbsp;&nbsp;&nbsp;uchcom_calc_baudrate(struct uchcom_softc *, uint32_t, uint8_t *,<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;uint8_t *);<br>
+static void &nbsp;&nbsp;&nbsp;uchcom_set_baudrate(struct uchcom_softc *, uint32_t, uint16_t);<br>
&nbsp;static void &nbsp;&nbsp;&nbsp;uchcom_poll(struct ucom_softc *ucom);<br>
&nbsp;<br>
&nbsp;static device_probe_t uchcom_probe;<br>
@@ -244,7 +241,7 @@ static const struct usb_config uchcom_config_data[UCHCOM_N_TRANSFER] = {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.endpoint = UE_ADDR_ANY,<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.direction = UE_DIR_OUT,<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.bufsize = UCHCOM_BULK_BUF_SIZE,<br>
- &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.flags = {.pipe_bof = 1,.force_short_xfer = 1,},<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.flags = {.pipe_bof = 1,},<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.callback = &amp;uchcom_write_callback,<br>
&nbsp;&nbsp;&nbsp;&nbsp;},<br>
&nbsp;<br>
@@ -256,8 +253,10 @@ static const struct usb_config uchcom_config_data[UCHCOM_N_TRANSFER] = {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.flags = {.pipe_bof = 1,.short_xfer_ok = 1,},<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.callback = &amp;uchcom_read_callback,<br>
&nbsp;&nbsp;&nbsp;&nbsp;},<br>
+};<br>
&nbsp;<br>
- &nbsp;&nbsp;[UCHCOM_INTR_DT_RD] = {<br>
+static const struct usb_config uchcom_intr_config_data[1] = {<br>
+ &nbsp;&nbsp;[0] = {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.type = UE_INTERRUPT,<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.endpoint = UE_ADDR_ANY,<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.direction = UE_DIR_IN,<br>
@@ -311,8 +310,9 @@ uchcom_attach(device_t dev)<br>
&nbsp;{<br>
&nbsp;&nbsp;&nbsp;&nbsp;struct uchcom_softc *sc = device_get_softc(dev);<br>
&nbsp;&nbsp;&nbsp;&nbsp;struct usb_attach_arg *uaa = device_get_ivars(dev);<br>
+ &nbsp;&nbsp;struct usb_interface *iface;<br>
+ &nbsp;&nbsp;struct usb_interface_descriptor *id;<br>
&nbsp;&nbsp;&nbsp;&nbsp;int error;<br>
- &nbsp;&nbsp;uint8_t iface_index;<br>
&nbsp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;DPRINTFN(11, "\n");<br>
&nbsp;<br>
@@ -330,20 +330,49 @@ uchcom_attach(device_t dev)<br>
&nbsp;&nbsp;&nbsp;&nbsp;case USB_PRODUCT_WCH2_CH341SER_3:<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;device_printf(dev, "CH341 detected\n");<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br>
+ &nbsp;&nbsp;case USB_PRODUCT_WCH2_CH343SER:<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;device_printf(dev, "CH343 detected\n");<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br>
+ &nbsp;&nbsp;case USB_PRODUCT_WCH2_CH9102SER:<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;device_printf(dev, "CH9102 detected\n");<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br>
&nbsp;&nbsp;&nbsp;&nbsp;default:<br>
- &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;device_printf(dev, "New CH340/CH341 product 0x%04x detected\n",<br>
- &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;uaa-&gt;info.idProduct);<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;device_printf(dev, "New CH340/CH341/CH343/CH9102 product "<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"0x%04x detected\n", uaa-&gt;info.idProduct);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br>
&nbsp;&nbsp;&nbsp;&nbsp;}<br>
&nbsp;<br>
- &nbsp;&nbsp;iface_index = UCHCOM_IFACE_INDEX;<br>
- &nbsp;&nbsp;error = usbd_transfer_setup(uaa-&gt;device,<br>
- &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&amp;iface_index, sc-&gt;sc_xfer, uchcom_config_data,<br>
- &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;UCHCOM_N_TRANSFER, sc, &amp;sc-&gt;sc_mtx);<br>
+ &nbsp;&nbsp;/* CH343/CH9102 has two interfaces. */<br>
+ &nbsp;&nbsp;sc-&gt;sc_ctrl_iface_no = uaa-&gt;info.bIfaceNum;<br>
&nbsp;<br>
+ &nbsp;&nbsp;iface = usbd_get_iface(uaa-&gt;device, UCHCOM_SECOND_IFACE_INDEX);<br>
+ &nbsp;&nbsp;if (iface) {<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;id = usbd_get_interface_descriptor(iface);<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (id == NULL) {<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;device_printf(dev, "no interface descriptor\n");<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;goto detach;<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sc-&gt;sc_iface_index = UCHCOM_SECOND_IFACE_INDEX;<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;usbd_set_parent_iface(uaa-&gt;device, UCHCOM_SECOND_IFACE_INDEX,<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;uaa-&gt;info.bIfaceIndex);<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sc-&gt;sc_chiptype = TYPE_CH343;<br>
+ &nbsp;&nbsp;} else {<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sc-&gt;sc_iface_index = UCHCOM_IFACE_INDEX;<br>
+ &nbsp;&nbsp;}<br>
+<br>
+ &nbsp;&nbsp;/* Setup all transfers. */<br>
+ &nbsp;&nbsp;error = usbd_transfer_setup(uaa-&gt;device, &amp;sc-&gt;sc_iface_index,<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sc-&gt;sc_xfer, uchcom_config_data, UCHCOM_N_TRANSFER, sc,<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&amp;sc-&gt;sc_mtx);<br>
+ &nbsp;&nbsp;if (error) {<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;device_printf(dev, "could not allocate all pipes\n");<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;goto detach;<br>
+ &nbsp;&nbsp;}<br>
+ &nbsp;&nbsp;error = usbd_transfer_setup(uaa-&gt;device, &amp;sc-&gt;sc_ctrl_iface_no,<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&amp;sc-&gt;sc_intr_xfer, uchcom_intr_config_data, 1, sc, &amp;sc-&gt;sc_mtx);<br>
&nbsp;&nbsp;&nbsp;&nbsp;if (error) {<br>
- &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DPRINTF("one or more missing USB endpoints, "<br>
- &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"error=%s\n", usbd_errstr(error));<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;device_printf(dev, "allocating USB transfers failed for "<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"interrupt\n");<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;goto detach;<br>
&nbsp;&nbsp;&nbsp;&nbsp;}<br>
&nbsp;<br>
@@ -449,7 +478,9 @@ uchcom_write_reg(struct uchcom_softc *sc,<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(unsigned)reg1, (unsigned)val1,<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(unsigned)reg2, (unsigned)val2);<br>
&nbsp;&nbsp;&nbsp;&nbsp;uchcom_ctrl_write(<br>
- &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sc, UCHCOM_REQ_WRITE_REG,<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sc,<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(sc-&gt;sc_chiptype != TYPE_CH343) ?<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;UCHCOM_REQ_WRITE_REG : UCHCOM_REQ_CH343_WRITE_REG,<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;reg1 | ((uint16_t)reg2 &lt;&lt; 8), val1 | ((uint16_t)val2 &lt;&lt; 8));<br>
&nbsp;}<br>
&nbsp;<br>
@@ -516,9 +547,6 @@ uchcom_update_version(struct uchcom_softc *sc)<br>
&nbsp;static void<br>
&nbsp;uchcom_convert_status(struct uchcom_softc *sc, uint8_t cur)<br>
&nbsp;{<br>
- &nbsp;&nbsp;sc-&gt;sc_dtr = !(cur &amp; UCHCOM_DTR_MASK);<br>
- &nbsp;&nbsp;sc-&gt;sc_rts = !(cur &amp; UCHCOM_RTS_MASK);<br>
-<br>
&nbsp;&nbsp;&nbsp;&nbsp;cur = ~cur &amp; 0x0F;<br>
&nbsp;&nbsp;&nbsp;&nbsp;sc-&gt;sc_msr = (cur &lt;&lt; 4) | ((sc-&gt;sc_msr &gt;&gt; 4) ^ cur);<br>
&nbsp;}<br>
@@ -555,78 +583,69 @@ uchcom_cfg_set_break(struct ucom_softc *ucom, uint8_t onoff)<br>
&nbsp;&nbsp;&nbsp;&nbsp;uint8_t brk1;<br>
&nbsp;&nbsp;&nbsp;&nbsp;uint8_t brk2;<br>
&nbsp;<br>
- &nbsp;&nbsp;uchcom_read_reg(sc, UCHCOM_REG_BREAK1, &amp;brk1, UCHCOM_REG_LCR1, &amp;brk2);<br>
- &nbsp;&nbsp;if (onoff) {<br>
- &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/* on - clear bits */<br>
- &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;brk1 &amp;= ~UCHCOM_BRK_MASK;<br>
- &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;brk2 &amp;= ~UCHCOM_LCR1_TX;<br>
+ &nbsp;&nbsp;if (sc-&gt;sc_chiptype == TYPE_CH343) {<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;brk1 = UCHCOM_CH343_BRK_MASK;<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (!onoff)<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;brk1 |= UCHCOM_ABRK_MASK;<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;uchcom_write_reg(sc, brk1, 0, 0, 0);<br>
&nbsp;&nbsp;&nbsp;&nbsp;} else {<br>
- &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/* off - set bits */<br>
- &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;brk1 |= UCHCOM_BRK_MASK;<br>
- &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;brk2 |= UCHCOM_LCR1_TX;<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;uchcom_read_reg(sc, UCHCOM_REG_BREAK1, &amp;brk1, UCHCOM_REG_LCR1,<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&amp;brk2);<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (onoff) {<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/* on - clear bits */<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;brk1 &amp;= ~UCHCOM_BRK_MASK;<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;brk2 &amp;= ~UCHCOM_LCR1_TX;<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} else {<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/* off - set bits */<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;brk1 |= UCHCOM_BRK_MASK;<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;brk2 |= UCHCOM_LCR1_TX;<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;uchcom_write_reg(sc, UCHCOM_REG_BREAK1, brk1, UCHCOM_REG_LCR1,<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;brk2);<br>
&nbsp;&nbsp;&nbsp;&nbsp;}<br>
- &nbsp;&nbsp;uchcom_write_reg(sc, UCHCOM_REG_BREAK1, brk1, UCHCOM_REG_LCR1, brk2);<br>
&nbsp;}<br>
&nbsp;<br>
-static int<br>
-uchcom_calc_divider_settings(struct uchcom_divider *dp, uint32_t rate)<br>
-{<br>
- &nbsp;&nbsp;const struct uchcom_divider_record *rp;<br>
- &nbsp;&nbsp;uint32_t div;<br>
- &nbsp;&nbsp;uint32_t rem;<br>
- &nbsp;&nbsp;uint32_t mod;<br>
- &nbsp;&nbsp;uint8_t i;<br>
-<br>
- &nbsp;&nbsp;/* find record */<br>
- &nbsp;&nbsp;for (i = 0; i != NUM_DIVIDERS; i++) {<br>
- &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (dividers[i].dvr_high &gt;= rate &amp;&amp;<br>
- &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dividers[i].dvr_low &lt;= rate) {<br>
- &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rp = &amp;dividers[i];<br>
- &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;goto found;<br>
- &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>
- &nbsp;&nbsp;}<br>
- &nbsp;&nbsp;return (-1);<br>
-<br>
-found:<br>
- &nbsp;&nbsp;dp-&gt;dv_prescaler = rp-&gt;dvr_divider.dv_prescaler;<br>
- &nbsp;&nbsp;if (rp-&gt;dvr_base_clock == UCHCOM_BASE_UNKNOWN)<br>
- &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dp-&gt;dv_div = rp-&gt;dvr_divider.dv_div;<br>
- &nbsp;&nbsp;else {<br>
- &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;div = rp-&gt;dvr_base_clock / rate;<br>
- &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rem = rp-&gt;dvr_base_clock % rate;<br>
- &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (div == 0 || div &gt;= 0xFF)<br>
- &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return (-1);<br>
- &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if ((rem &lt;&lt; 1) &gt;= rate)<br>
- &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;div += 1;<br>
- &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dp-&gt;dv_div = (uint8_t)-div;<br>
+static void<br>
+uchcom_calc_baudrate(struct uchcom_softc *sc, uint32_t rate, uint8_t *divisor,<br>
+ &nbsp;&nbsp;&nbsp;uint8_t *factor)<br>
+{<br>
+ &nbsp;&nbsp;uint32_t clk = 12000000;<br>
+<br>
+ &nbsp;&nbsp;if (rate &gt;= 256000 &amp;&amp; sc-&gt;sc_chiptype == TYPE_CH343)<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*divisor = 7;<br>
+ &nbsp;&nbsp;else if (rate &gt; 23529) {<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;clk /= 2;<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*divisor = 3;<br>
+ &nbsp;&nbsp;} else if (rate &gt; 2941) {<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;clk /= &nbsp;16;<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*divisor = 2;<br>
+ &nbsp;&nbsp;} else if (rate &gt; 367) {<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;clk /= 128;<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*divisor = 1;<br>
+ &nbsp;&nbsp;} else {<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;clk = 11719;<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*divisor = 0;<br>
&nbsp;&nbsp;&nbsp;&nbsp;}<br>
&nbsp;<br>
- &nbsp;&nbsp;mod = (UCHCOM_BPS_MOD_BASE / rate) + UCHCOM_BPS_MOD_BASE_OFS;<br>
- &nbsp;&nbsp;mod = mod + (mod / 2);<br>
+ &nbsp;&nbsp;*factor = 256 - clk / rate;<br>
&nbsp;<br>
- &nbsp;&nbsp;dp-&gt;dv_mod = (mod + 0xFF) / 0x100;<br>
-<br>
- &nbsp;&nbsp;return (0);<br>
+ &nbsp;&nbsp;if (rate == 921600 &amp;&amp; sc-&gt;sc_chiptype != TYPE_CH343) {<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*divisor = 7;<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*factor = 243;<br>
+ &nbsp;&nbsp;}<br>
&nbsp;}<br>
&nbsp;<br>
&nbsp;static void<br>
-uchcom_set_baudrate(struct uchcom_softc *sc, uint32_t rate)<br>
+uchcom_set_baudrate(struct uchcom_softc *sc, uint32_t rate, uint16_t lcr)<br>
&nbsp;{<br>
- &nbsp;&nbsp;struct uchcom_divider dv;<br>
+ &nbsp;&nbsp;uint16_t idx;<br>
+ &nbsp;&nbsp;uint8_t factor, div;<br>
&nbsp;<br>
- &nbsp;&nbsp;if (uchcom_calc_divider_settings(&amp;dv, rate))<br>
- &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return;<br>
+ &nbsp;&nbsp;uchcom_calc_baudrate(sc, rate, &amp;div, &amp;factor);<br>
+ &nbsp;&nbsp;div |= (sc-&gt;sc_chiptype != TYPE_CH343) ? 0x80 : 0x00;<br>
+ &nbsp;&nbsp;idx = (factor &lt;&lt; 8) | div;<br>
&nbsp;<br>
- &nbsp;&nbsp;/*<br>
- &nbsp;&nbsp;&nbsp;* According to linux code we need to set bit 7 of UCHCOM_REG_BPS_PRE,<br>
- &nbsp;&nbsp;&nbsp;* otherwise the chip will buffer data.<br>
- &nbsp;&nbsp;&nbsp;*/<br>
- &nbsp;&nbsp;uchcom_write_reg(sc,<br>
- &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;UCHCOM_REG_BPS_PRE, dv.dv_prescaler | 0x80,<br>
- &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;UCHCOM_REG_BPS_DIV, dv.dv_div);<br>
- &nbsp;&nbsp;uchcom_write_reg(sc,<br>
- &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;UCHCOM_REG_BPS_MOD, dv.dv_mod,<br>
- &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;UCHCOM_REG_BPS_PAD, 0);<br>
+ &nbsp;&nbsp;uchcom_ctrl_write(sc, UCHCOM_REQ_RESET, lcr, idx);<br>
&nbsp;}<br>
&nbsp;<br>
&nbsp;/* ----------------------------------------------------------------------<br>
@@ -673,6 +692,14 @@ uchcom_cfg_open(struct ucom_softc *ucom)<br>
&nbsp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;DPRINTF("\n");<br>
&nbsp;<br>
+ &nbsp;&nbsp;if (sc-&gt;sc_chiptype != TYPE_CH343) {<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/* Set default configuration. */<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;uchcom_get_version(sc, NULL);<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;uchcom_ctrl_write(sc, UCHCOM_REQ_RESET, 0, 0);<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;uchcom_write_reg(sc, UCHCOM_REG_BPS_PRE, 0x82,<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;UCHCOM_REG_BPS_DIV, 0xd9);<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;uchcom_write_reg(sc, 0x2c, 0x07, UCHCOM_REG_BPS_PAD, 0);<br>
+ &nbsp;&nbsp;}<br>
&nbsp;&nbsp;&nbsp;&nbsp;uchcom_update_version(sc);<br>
&nbsp;&nbsp;&nbsp;&nbsp;uchcom_update_status(sc);<br>
&nbsp;}<br>
@@ -680,53 +707,69 @@ uchcom_cfg_open(struct ucom_softc *ucom)<br>
&nbsp;static int<br>
&nbsp;uchcom_pre_param(struct ucom_softc *ucom, struct termios *t)<br>
&nbsp;{<br>
- &nbsp;&nbsp;struct uchcom_divider dv;<br>
+ &nbsp;&nbsp;struct uchcom_softc *sc = ucom-&gt;sc_parent;<br>
&nbsp;<br>
- &nbsp;&nbsp;switch (t-&gt;c_cflag &amp; CSIZE) {<br>
- &nbsp;&nbsp;case CS8:<br>
+ &nbsp;&nbsp;/*<br>
+ &nbsp;&nbsp;&nbsp;* Check requested baud rate.<br>
+ &nbsp;&nbsp;&nbsp;* The CH340/CH341 can set any baud rate up to 2Mb.<br>
+ &nbsp;&nbsp;&nbsp;* The CH9102/CH343 can set any baud rate up to 6Mb.<br>
+ &nbsp;&nbsp;&nbsp;*/<br>
+ &nbsp;&nbsp;switch (sc-&gt;sc_chiptype) {<br>
+ &nbsp;&nbsp;case TYPE_CH343:<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (t-&gt;c_ospeed &lt;= 6000000)<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return (0);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br>
&nbsp;&nbsp;&nbsp;&nbsp;default:<br>
- &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return (EIO);<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (t-&gt;c_ospeed &lt;= 2000000)<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return (0);<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br>
&nbsp;&nbsp;&nbsp;&nbsp;}<br>
- &nbsp;&nbsp;if ((t-&gt;c_cflag &amp; CSTOPB) != 0)<br>
- &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return (EIO);<br>
- &nbsp;&nbsp;if ((t-&gt;c_cflag &amp; PARENB) != 0)<br>
- &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return (EIO);<br>
&nbsp;<br>
- &nbsp;&nbsp;if (uchcom_calc_divider_settings(&amp;dv, t-&gt;c_ospeed)) {<br>
- &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return (EIO);<br>
- &nbsp;&nbsp;}<br>
- &nbsp;&nbsp;return (0); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/* success */<br>
+ &nbsp;&nbsp;return (EIO);<br>
&nbsp;}<br>
&nbsp;<br>
&nbsp;static void<br>
&nbsp;uchcom_cfg_param(struct ucom_softc *ucom, struct termios *t)<br>
&nbsp;{<br>
&nbsp;&nbsp;&nbsp;&nbsp;struct uchcom_softc *sc = ucom-&gt;sc_parent;<br>
+ &nbsp;&nbsp;uint8_t lcr;<br>
&nbsp;<br>
- &nbsp;&nbsp;uchcom_get_version(sc, NULL);<br>
- &nbsp;&nbsp;uchcom_ctrl_write(sc, UCHCOM_REQ_RESET, 0, 0);<br>
- &nbsp;&nbsp;uchcom_set_baudrate(sc, t-&gt;c_ospeed);<br>
- &nbsp;&nbsp;if (sc-&gt;sc_version &lt; UCHCOM_VER_30) {<br>
- &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;uchcom_read_reg(sc, UCHCOM_REG_LCR1, NULL,<br>
- &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;UCHCOM_REG_LCR2, NULL);<br>
- &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;uchcom_write_reg(sc, UCHCOM_REG_LCR1, 0x50,<br>
- &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;UCHCOM_REG_LCR2, 0x00);<br>
- &nbsp;&nbsp;} else {<br>
- &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/*<br>
- &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* Set up line control:<br>
- &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* - enable transmit and receive<br>
- &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* - set 8n1 mode<br>
- &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* To do: support other sizes, parity, stop bits.<br>
- &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/<br>
- &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;uchcom_write_reg(sc,<br>
- &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;UCHCOM_REG_LCR1,<br>
- &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;UCHCOM_LCR1_RX | UCHCOM_LCR1_TX | UCHCOM_LCR1_CS8,<br>
- &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;UCHCOM_REG_LCR2, 0x00);<br>
+ &nbsp;&nbsp;lcr = UCHCOM_LCR1_RX | UCHCOM_LCR1_TX;<br>
+<br>
+ &nbsp;&nbsp;if (t-&gt;c_cflag &amp; CSTOPB)<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lcr |= UCHCOM_LCR1_STOPB;<br>
+<br>
+ &nbsp;&nbsp;if (t-&gt;c_cflag &amp; PARENB) {<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lcr |= UCHCOM_LCR1_PARENB;<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (t-&gt;c_cflag &amp; PARODD)<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lcr |= UCHCOM_LCR1_PARODD;<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lcr |= UCHCOM_LCR1_PAREVEN;<br>
&nbsp;&nbsp;&nbsp;&nbsp;}<br>
- &nbsp;&nbsp;uchcom_update_status(sc);<br>
- &nbsp;&nbsp;uchcom_ctrl_write(sc, UCHCOM_REQ_RESET, 0x501f, 0xd90a);<br>
- &nbsp;&nbsp;uchcom_set_baudrate(sc, t-&gt;c_ospeed);<br>
+<br>
+ &nbsp;&nbsp;switch (t-&gt;c_cflag &amp; CSIZE) {<br>
+ &nbsp;&nbsp;case CS5:<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lcr |= UCHCOM_LCR1_CS5;<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br>
+ &nbsp;&nbsp;case CS6:<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lcr |= UCHCOM_LCR1_CS6;<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br>
+ &nbsp;&nbsp;case CS7:<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lcr |= UCHCOM_LCR1_CS7;<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br>
+ &nbsp;&nbsp;case CS8:<br>
+ &nbsp;&nbsp;default:<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lcr |= UCHCOM_LCR1_CS8;<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br>
+ &nbsp;&nbsp;}<br>
+<br>
+ &nbsp;&nbsp;if (sc-&gt;sc_chiptype == TYPE_CH343)<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;uchcom_set_baudrate(sc, t-&gt;c_ospeed,<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;UCHCOM_T | UCHCOM_CL | UCHCOM_CH343_CT | lcr &lt;&lt; 8);<br>
+ &nbsp;&nbsp;else<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;uchcom_set_baudrate(sc, t-&gt;c_ospeed,<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;UCHCOM_T | UCHCOM_CL | UCHCOM_CT | lcr &lt;&lt; 8);<br>
+<br>
&nbsp;&nbsp;&nbsp;&nbsp;uchcom_set_dtr_rts(sc);<br>
&nbsp;&nbsp;&nbsp;&nbsp;uchcom_update_status(sc);<br>
&nbsp;}<br>
@@ -737,7 +780,7 @@ uchcom_start_read(struct ucom_softc *ucom)<br>
&nbsp;&nbsp;&nbsp;&nbsp;struct uchcom_softc *sc = ucom-&gt;sc_parent;<br>
&nbsp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;/* start interrupt endpoint */<br>
- &nbsp;&nbsp;usbd_transfer_start(sc-&gt;sc_xfer[UCHCOM_INTR_DT_RD]);<br>
+ &nbsp;&nbsp;usbd_transfer_start(sc-&gt;sc_intr_xfer);<br>
&nbsp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;/* start read endpoint */<br>
&nbsp;&nbsp;&nbsp;&nbsp;usbd_transfer_start(sc-&gt;sc_xfer[UCHCOM_BULK_DT_RD]);<br>
@@ -749,7 +792,7 @@ uchcom_stop_read(struct ucom_softc *ucom)<br>
&nbsp;&nbsp;&nbsp;&nbsp;struct uchcom_softc *sc = ucom-&gt;sc_parent;<br>
&nbsp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;/* stop interrupt endpoint */<br>
- &nbsp;&nbsp;usbd_transfer_stop(sc-&gt;sc_xfer[UCHCOM_INTR_DT_RD]);<br>
+ &nbsp;&nbsp;usbd_transfer_stop(sc-&gt;sc_intr_xfer);<br>
&nbsp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;/* stop read endpoint */<br>
&nbsp;&nbsp;&nbsp;&nbsp;usbd_transfer_stop(sc-&gt;sc_xfer[UCHCOM_BULK_DT_RD]);<br>
@@ -779,7 +822,8 @@ uchcom_intr_callback(struct usb_xfer *xfer, usb_error_t error)<br>
&nbsp;{<br>
&nbsp;&nbsp;&nbsp;&nbsp;struct uchcom_softc *sc = usbd_xfer_softc(xfer);<br>
&nbsp;&nbsp;&nbsp;&nbsp;struct usb_page_cache *pc;<br>
- &nbsp;&nbsp;uint8_t buf[UCHCOM_INTR_LEAST];<br>
+ &nbsp;&nbsp;uint32_t intrstat;<br>
+ &nbsp;&nbsp;uint8_t buf[16];<br>
&nbsp;&nbsp;&nbsp;&nbsp;int actlen;<br>
&nbsp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;usbd_xfer_status(xfer, &amp;actlen, NULL, NULL, NULL);<br>
@@ -791,13 +835,12 @@ uchcom_intr_callback(struct usb_xfer *xfer, usb_error_t error)<br>
&nbsp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (actlen &gt;= UCHCOM_INTR_LEAST) {<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pc = usbd_xfer_get_frame(xfer, 0);<br>
- &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;usbd_copy_out(pc, 0, buf, UCHCOM_INTR_LEAST);<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;usbd_copy_out(pc, 0, buf, sizeof(buf));<br>
&nbsp;<br>
- &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DPRINTF("data = 0x%02X 0x%02X 0x%02X 0x%02X\n",<br>
- &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(unsigned)buf[0], (unsigned)buf[1],<br>
- &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(unsigned)buf[2], (unsigned)buf[3]);<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;intrstat = (sc-&gt;sc_chiptype == TYPE_CH343) ?<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;actlen - 1 : UCHCOM_INTR_STAT1;<br>
&nbsp;<br>
- &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;uchcom_convert_status(sc, buf[UCHCOM_INTR_STAT1]);<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;uchcom_convert_status(sc, buf[intrstat]);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ucom_status_change(&amp;sc-&gt;sc_ucom);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>
&nbsp;&nbsp;&nbsp;&nbsp;case USB_ST_SETUP:<br>
diff --git a/sys/dev/usb/usbdevs b/sys/dev/usb/usbdevs<br>
index f26edcebcb9c..2318e6bd0017 100644<br>
--- a/sys/dev/usb/usbdevs<br>
+++ b/sys/dev/usb/usbdevs<br>
@@ -4972,9 +4972,11 @@ product WAVESENSE JAZZ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0xaaaa &nbsp;Jazz blood glucose meter<br>
&nbsp;/* WCH products */<br>
&nbsp;product WCH CH341SER &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x5523 &nbsp;CH341/CH340 USB-Serial Bridge<br>
&nbsp;product WCH2 CH341SER_2 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x5523 &nbsp;CH341/CH340 USB-Serial Bridge<br>
+product WCH2 CH343SER &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x55d3 &nbsp;CH343 USB Serial<br>
+product WCH2 CH9102SER &nbsp;&nbsp;&nbsp;&nbsp;0x55d4 &nbsp;CH9102 USB Serial<br>
&nbsp;product WCH2 CH341SER_3 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x7522 &nbsp;CH341/CH340 USB-Serial Bridge<br>
&nbsp;product WCH2 CH341SER &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x7523 &nbsp;CH341/CH340 USB-Serial Bridge<br>
-product WCH2 U2M &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0X752d &nbsp;CH345 USB2.0-MIDI<br>
+product WCH2 U2M &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x752d &nbsp;CH345 USB2.0-MIDI<br>
&nbsp;<br>
&nbsp;/* West Mountain Radio products */<br>
&nbsp;product WESTMOUNTAIN RIGBLASTER_ADVANTAGE &nbsp;0x0003 &nbsp;RIGblaster Advantage<br>
&nbsp;</div>

<hr></div>
</blockquote>
<br>
&nbsp;</body></html>
------=_Part_559_1619721974.1750830351251--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?727722724.560.1750830351345>