From nobody Wed Jun 25 05:53:08 2025 X-Original-To: dev-commits-src-main@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4bRrZy2nlqz60mfC for ; Wed, 25 Jun 2025 05:53:14 +0000 (UTC) (envelope-from 01000197a5a5aff1-ed598ba1-80f2-406b-b11d-fc36e727d9c7-000000@amazonses.com) Received: from a8-60.smtp-out.amazonses.com (a8-60.smtp-out.amazonses.com [54.240.8.60]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 4bRrZy2BCKz3PsH for ; Wed, 25 Jun 2025 05:53:14 +0000 (UTC) (envelope-from 01000197a5a5aff1-ed598ba1-80f2-406b-b11d-fc36e727d9c7-000000@amazonses.com) Authentication-Results: mx1.freebsd.org; none DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/simple; s=vnqrkfnvu6csdl6mwgk5t6ix3nnepx57; d=tarsnap.com; t=1750830788; h=Message-ID:Date:MIME-Version:Subject:To:Cc:References:From:In-Reply-To:Content-Type:Content-Transfer-Encoding; bh=QbIgY2n8tZ+66DbH7bc0W7+ogdqRBXRSa3CpUduqyEU=; b=bruogOvsFUA4mX0X6fCURWKNVhzuPkVZrB6/x++Xm0DmrVqFI9lpt8k6paqkE/y1 vcUMk/r9AFBlV11fUM3jbUx7ZgdH63jIV0izhEGEyHbHelm0SltwpvRiznsiqU/pZGv QD4lWXwjQUKrFvO85COmZAR9SaDJi9/MSqH+KnJ4= DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/simple; s=6gbrjpgwjskckoa6a5zn6fwqkn67xbtw; d=amazonses.com; t=1750830788; h=Message-ID:Date:MIME-Version:Subject:To:Cc:References:From:In-Reply-To:Content-Type:Content-Transfer-Encoding:Feedback-ID; bh=QbIgY2n8tZ+66DbH7bc0W7+ogdqRBXRSa3CpUduqyEU=; b=KhJ5r2FUYxtJT2hAr3llL2Xc+XmJUgfeaX0pdQayLgPjFRRY+Sd2SJi6PdfintXA LL3s7Pq/rUz1eeErINadSiR5PyTDXcPCFKg7Ol8FxiB02QlnHO2BfIHL0lpeVEczPJJ /5DoU35tLFTthN3iGVlacZdLE3YEclxZj//pEWQk= Message-ID: <01000197a5a5aff1-ed598ba1-80f2-406b-b11d-fc36e727d9c7-000000@email.amazonses.com> Date: Wed, 25 Jun 2025 05:53:08 +0000 List-Id: Commit messages for the main branch of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-main List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-main@freebsd.org Sender: owner-dev-commits-src-main@FreeBSD.org MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: Re: git: 1395712cab8e - main - uchcom: add support for CH9102 and CH343 uarts To: Ronald Klop , Kevin Lo Cc: dev-commits-src-all@FreeBSD.org, src-committers@FreeBSD.org, dev-commits-src-main@FreeBSD.org References: <202506250136.55P1aag8094334@gitrepo.freebsd.org> <727722724.560.1750830351345@localhost> Content-Language: en-US From: Colin Percival Autocrypt: addr=cperciva@tarsnap.com; keydata= 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 In-Reply-To: <727722724.560.1750830351345@localhost> Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit Feedback-ID: ::1.us-east-1.Lv9FVjaNvvR5llaqfLoOVbo2VxOELl7cjN0AOyXnPlk=:AmazonSES X-SES-Outgoing: 2025.06.25-54.240.8.60 X-Rspamd-Queue-Id: 4bRrZy2BCKz3PsH X-Spamd-Bar: ---- X-Rspamd-Pre-Result: action=no action; module=replies; Message is reply to one we originated X-Spamd-Result: default: False [-4.00 / 15.00]; REPLY(-4.00)[]; ASN(0.00)[asn:14618, ipnet:54.240.8.0/21, country:US] Yes. Please keep the HARDWARE section in device driver man pages. The text from there goes directly into the "hardware notes" page on the website. Colin Percival On 6/24/25 22:45, Ronald Klop wrote: > 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 > *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/?id=1395712cab8e95808064ba68c5a792b7cd0fe35f> > > commit 1395712cab8e95808064ba68c5a792b7cd0fe35f > Author:     Kevin Lo > AuthorDate: 2025-06-25 01:33:35 +0000 > Commit:     Kevin Lo > 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 >     Differential Revision: https://reviews.freebsd.org/D46290 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 > @@ -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 = ÷rs[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 > ------------------------------------------------------------------------------ > > -- Colin Percival FreeBSD Release Engineering Lead & EC2 platform maintainer Founder, Tarsnap | www.tarsnap.com | Online backups for the truly paranoid