Module Name:    src
Committed By:   snj
Date:           Wed Dec 14 19:18:58 UTC 2016

Modified Files:
        src/sys/dev/usb [netbsd-7]: uchcom.c

Log Message:
Pull up following revision(s) (requested by bouyer in ticket #1321):
        sys/dev/usb/uchcom.c: revision 1.17
Followling an advice in a linux forum, don't update LCR1/LCR2.
With this change this CH340 usb/serial based device:
https://www.olimex.com/Products/Breadboarding/BB-CH340T/open-source-hardware
(the chip is written H340T)
works as expected. As I'm not sure if this is needed for older device,
make this change for sc_version 0x30 or newer only.
While there, match USB_PRODUCT_WINCHIPHEAD2_CH341_2 too.


To generate a diff of this commit:
cvs rdiff -u -r1.13 -r1.13.4.1 src/sys/dev/usb/uchcom.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/dev/usb/uchcom.c
diff -u src/sys/dev/usb/uchcom.c:1.13 src/sys/dev/usb/uchcom.c:1.13.4.1
--- src/sys/dev/usb/uchcom.c:1.13	Sat Mar 15 19:20:27 2014
+++ src/sys/dev/usb/uchcom.c	Wed Dec 14 19:18:58 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: uchcom.c,v 1.13 2014/03/15 19:20:27 martin Exp $	*/
+/*	$NetBSD: uchcom.c,v 1.13.4.1 2016/12/14 19:18:58 snj Exp $	*/
 
 /*
  * Copyright (c) 2007 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uchcom.c,v 1.13 2014/03/15 19:20:27 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uchcom.c,v 1.13.4.1 2016/12/14 19:18:58 snj Exp $");
 
 /*
  * driver for WinChipHead CH341/340, the worst USB-serial chip in the world.
@@ -91,6 +91,7 @@ int	uchcomdebug = 0;
 #define UCHCOM_REG_LCR2		0x25
 
 #define UCHCOM_VER_20		0x20
+#define UCHCOM_VER_30		0x30
 
 #define UCHCOM_BASE_UNKNOWN	0
 #define UCHCOM_BPS_MOD_BASE	20000000
@@ -176,6 +177,7 @@ static const struct uchcom_divider_recor
 static const struct usb_devno uchcom_devs[] = {
 	{ USB_VENDOR_WINCHIPHEAD, USB_PRODUCT_WINCHIPHEAD_CH341SER },
 	{ USB_VENDOR_WINCHIPHEAD2, USB_PRODUCT_WINCHIPHEAD2_CH341 },
+	{ USB_VENDOR_WINCHIPHEAD2, USB_PRODUCT_WINCHIPHEAD2_CH341_2 },
 };
 #define uchcom_lookup(v, p)	usb_lookup(uchcom_devs, v, p)
 
@@ -570,6 +572,7 @@ update_version(struct uchcom_softc *sc)
 		    usbd_errstr(err));
 		return EIO;
 	}
+	DPRINTF(("%s: update_version %d\n", device_xname(sc->sc_dev), sc->sc_version));
 
 	return 0;
 }
@@ -715,50 +718,52 @@ set_dte_rate(struct uchcom_softc *sc, ui
 static int
 set_line_control(struct uchcom_softc *sc, tcflag_t cflag)
 {
-	usbd_status err;
-	uint8_t lcr1val = 0, lcr2val = 0;
+	if (sc->sc_version < UCHCOM_VER_30) {
+		usbd_status err;
+		uint8_t lcr1val = 0, lcr2val = 0;
 
-	err = read_reg(sc, UCHCOM_REG_LCR1, &lcr1val, UCHCOM_REG_LCR2, &lcr2val);
-	if (err) {
-		aprint_error_dev(sc->sc_dev, "cannot get LCR: %s\n",
-		    usbd_errstr(err));
-		return EIO;
-	}
+		err = read_reg(sc, UCHCOM_REG_LCR1, &lcr1val, UCHCOM_REG_LCR2, &lcr2val);
+		if (err) {
+			aprint_error_dev(sc->sc_dev, "cannot get LCR: %s\n",
+			    usbd_errstr(err));
+			return EIO;
+		}
 
-	lcr1val &= ~UCHCOM_LCR1_MASK;
-	lcr2val &= ~UCHCOM_LCR2_MASK;
+		lcr1val &= ~UCHCOM_LCR1_MASK;
+		lcr2val &= ~UCHCOM_LCR2_MASK;
 
-	/*
-	 * XXX: it is difficult to handle the line control appropriately:
-	 *   - CS8, !CSTOPB and any parity mode seems ok, but
-	 *   - the chip doesn't have the function to calculate parity
-	 *     in !CS8 mode.
-	 *   - it is unclear that the chip supports CS5,6 mode.
-	 *   - it is unclear how to handle stop bits.
-	 */
-
-	switch (ISSET(cflag, CSIZE)) {
-	case CS5:
-	case CS6:
-	case CS7:
-		return EINVAL;
-	case CS8:
-		break;
-	}
+		/*
+		 * XXX: it is difficult to handle the line control appropriately:
+		 *   - CS8, !CSTOPB and any parity mode seems ok, but
+		 *   - the chip doesn't have the function to calculate parity
+		 *     in !CS8 mode.
+		 *   - it is unclear that the chip supports CS5,6 mode.
+		 *   - it is unclear how to handle stop bits.
+		 */
+
+		switch (ISSET(cflag, CSIZE)) {
+		case CS5:
+		case CS6:
+		case CS7:
+			return EINVAL;
+		case CS8:
+			break;
+		}
 
-	if (ISSET(cflag, PARENB)) {
-		lcr1val |= UCHCOM_LCR1_PARENB;
-		if (ISSET(cflag, PARODD))
-			lcr2val |= UCHCOM_LCR2_PARODD;
-		else
-			lcr2val |= UCHCOM_LCR2_PAREVEN;
-	}
+		if (ISSET(cflag, PARENB)) {
+			lcr1val |= UCHCOM_LCR1_PARENB;
+			if (ISSET(cflag, PARODD))
+				lcr2val |= UCHCOM_LCR2_PARODD;
+			else
+				lcr2val |= UCHCOM_LCR2_PAREVEN;
+		}
 
-	err = write_reg(sc, UCHCOM_REG_LCR1, lcr1val, UCHCOM_REG_LCR2, lcr2val);
-	if (err) {
-		aprint_error_dev(sc->sc_dev, "cannot set LCR: %s\n",
-		    usbd_errstr(err));
-		return EIO;
+		err = write_reg(sc, UCHCOM_REG_LCR1, lcr1val, UCHCOM_REG_LCR2, lcr2val);
+		if (err) {
+			aprint_error_dev(sc->sc_dev, "cannot set LCR: %s\n",
+			    usbd_errstr(err));
+			return EIO;
+		}
 	}
 
 	return 0;

Reply via email to