PERFORCE change 168992 for review
Hans Petter Selasky
hselasky at FreeBSD.org
Mon Sep 28 21:09:33 UTC 2009
http://perforce.freebsd.org/chv.cgi?CH=168992
Change 168992 by hselasky at hselasky_laptop001 on 2009/09/28 21:09:06
USB serial:
- merge the two uchxxx drivers together
- some register programming had to be removed
because it was making the newer version
of the chip not working. Hopefully no
essential features are missed out.
Affected files ...
.. //depot/projects/usb/src/sys/conf/files#81 edit
.. //depot/projects/usb/src/sys/dev/usb/serial/uch341.c#3 delete
.. //depot/projects/usb/src/sys/dev/usb/serial/uchcom.c#14 edit
.. //depot/projects/usb/src/sys/dev/usb/usbdevs#80 edit
.. //depot/projects/usb/src/sys/modules/usb/Makefile#21 edit
.. //depot/projects/usb/src/sys/modules/usb/uch341/Makefile#2 delete
Differences ...
==== //depot/projects/usb/src/sys/conf/files#81 (text+ko) ====
@@ -1643,7 +1643,6 @@
dev/usb/serial/uark.c optional uark
dev/usb/serial/ubsa.c optional ubsa
dev/usb/serial/ubser.c optional ubser
-dev/usb/serial/uch341.c optional uch341
dev/usb/serial/uchcom.c optional uchcom
dev/usb/serial/ucycom.c optional ucycom
dev/usb/serial/ufoma.c optional ufoma
==== //depot/projects/usb/src/sys/dev/usb/serial/uchcom.c#14 (text+ko) ====
@@ -66,7 +66,8 @@
__FBSDID("$FreeBSD: src/sys/dev/usb/serial/uchcom.c,v 1.11 2009/06/23 02:19:59 thompsa Exp $");
/*
- * driver for WinChipHead CH341/340, the worst USB-serial chip in the world.
+ * Driver for WinChipHead CH341/340, the worst USB-serial chip in the
+ * world.
*/
#include <sys/stdint.h>
@@ -206,7 +207,7 @@
static const struct usb_device_id uchcom_devs[] = {
{USB_VPI(USB_VENDOR_WCH, USB_PRODUCT_WCH_CH341SER, 0)},
- {USB_VPI(0x1a86, 0x7523, 0)},
+ {USB_VPI(USB_VENDOR_WCH2, USB_PRODUCT_WCH2_CH341SER, 0)},
};
/* protypes */
@@ -226,12 +227,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_dtrrts(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_dte_rate(struct uchcom_softc *, uint32_t);
-static void uchcom_set_line_control(struct uchcom_softc *, tcflag_t);
-static void uchcom_clear_chip(struct uchcom_softc *);
-static void uchcom_reset_chip(struct uchcom_softc *);
+static void uchcom_set_baudrate(struct uchcom_softc *, uint32_t);
static void uchcom_poll(struct ucom_softc *ucom);
static device_probe_t uchcom_probe;
@@ -345,9 +343,6 @@
goto detach;
}
- sc->sc_dtr = 1;
- sc->sc_rts = 1;
-
/* clear stall at first run */
mtx_lock(&sc->sc_mtx);
usbd_xfer_set_stall(sc->sc_xfer[UCHCOM_BULK_DT_WR]);
@@ -453,8 +448,7 @@
{
uint8_t buf[UCHCOM_INPUT_BUF_SIZE];
- uchcom_ctrl_read(
- sc, UCHCOM_REQ_GET_VERSION, 0, 0, buf, sizeof(buf));
+ uchcom_ctrl_read(sc, UCHCOM_REQ_GET_VERSION, 0, 0, buf, sizeof(buf));
if (rver)
*rver = buf[0];
@@ -467,13 +461,13 @@
}
static void
-uchcom_set_dtrrts_10(struct uchcom_softc *sc, uint8_t val)
+uchcom_set_dtr_rts_10(struct uchcom_softc *sc, uint8_t val)
{
uchcom_write_reg(sc, UCHCOM_REG_STAT1, val, UCHCOM_REG_STAT1, val);
}
static void
-uchcom_set_dtrrts_20(struct uchcom_softc *sc, uint8_t val)
+uchcom_set_dtr_rts_20(struct uchcom_softc *sc, uint8_t val)
{
uchcom_ctrl_write(sc, UCHCOM_REQ_SET_DTRRTS, val, 0);
}
@@ -510,7 +504,7 @@
static void
-uchcom_set_dtrrts(struct uchcom_softc *sc)
+uchcom_set_dtr_rts(struct uchcom_softc *sc)
{
uint8_t val = 0;
@@ -520,9 +514,9 @@
val |= UCHCOM_RTS_MASK;
if (sc->sc_version < UCHCOM_VER_20)
- uchcom_set_dtrrts_10(sc, ~val);
+ uchcom_set_dtr_rts_10(sc, ~val);
else
- uchcom_set_dtrrts_20(sc, ~val);
+ uchcom_set_dtr_rts_20(sc, ~val);
}
static void
@@ -578,16 +572,16 @@
dp->dv_div = (uint8_t)-div;
}
- mod = UCHCOM_BPS_MOD_BASE / rate + UCHCOM_BPS_MOD_BASE_OFS;
- mod = mod + mod / 2;
+ mod = (UCHCOM_BPS_MOD_BASE / rate) + UCHCOM_BPS_MOD_BASE_OFS;
+ mod = mod + (mod / 2);
- dp->dv_mod = mod / 0x100;
+ dp->dv_mod = (mod + 0xFF) / 0x100;
return (0);
}
static void
-uchcom_set_dte_rate(struct uchcom_softc *sc, uint32_t rate)
+uchcom_set_baudrate(struct uchcom_softc *sc, uint32_t rate)
{
struct uchcom_divider dv;
@@ -602,76 +596,6 @@
UCHCOM_REG_BPS_PAD, 0);
}
-static void
-uchcom_set_line_control(struct uchcom_softc *sc, tcflag_t cflag)
-{
- uint8_t lcr1 = 0;
- uint8_t lcr2 = 0;
-
- uchcom_read_reg(sc, UCHCOM_REG_LCR1, &lcr1, UCHCOM_REG_LCR2, &lcr2);
-
- lcr1 &= ~UCHCOM_LCR1_MASK;
- lcr2 &= ~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.
- */
-
- if (cflag & PARENB) {
- lcr1 |= UCHCOM_LCR1_PARENB;
- if (cflag & PARODD)
- lcr2 |= UCHCOM_LCR2_PARODD;
- else
- lcr2 |= UCHCOM_LCR2_PAREVEN;
- }
- uchcom_write_reg(sc, UCHCOM_REG_LCR1, lcr1, UCHCOM_REG_LCR2, lcr2);
-}
-
-static void
-uchcom_clear_chip(struct uchcom_softc *sc)
-{
- DPRINTF("\n");
- uchcom_ctrl_write(sc, UCHCOM_REQ_RESET, 0, 0);
-}
-
-static void
-uchcom_reset_chip(struct uchcom_softc *sc)
-{
- uint16_t val;
- uint16_t idx;
- uint8_t lcr1;
- uint8_t lcr2;
- uint8_t pre;
- uint8_t div;
- uint8_t mod;
-
- uchcom_read_reg(sc, UCHCOM_REG_LCR1, &lcr1, UCHCOM_REG_LCR2, &lcr2);
- uchcom_read_reg(sc, UCHCOM_REG_BPS_PRE, &pre, UCHCOM_REG_BPS_DIV, &div);
- uchcom_read_reg(sc, UCHCOM_REG_BPS_MOD, &mod, UCHCOM_REG_BPS_PAD, NULL);
-
- val = 0;
- idx = 0;
- val |= (uint16_t)(lcr1 & 0xF0) << 8;
- val |= 0x01;
- val |= (uint16_t)(lcr2 & 0x0F) << 8;
- val |= 0x02;
- idx |= pre & 0x07;
- val |= 0x04;
- idx |= (uint16_t)div << 8;
- val |= 0x08;
- idx |= mod & 0xF8;
- val |= 0x10;
-
- DPRINTF("reset v=0x%04X, i=0x%04X\n", val, idx);
-
- uchcom_ctrl_write(sc, UCHCOM_REQ_RESET, val, idx);
-}
-
/* ----------------------------------------------------------------------
* methods for ucom
*/
@@ -694,7 +618,7 @@
DPRINTF("onoff = %d\n", onoff);
sc->sc_dtr = onoff;
- uchcom_set_dtrrts(sc);
+ uchcom_set_dtr_rts(sc);
}
static void
@@ -705,7 +629,7 @@
DPRINTF("onoff = %d\n", onoff);
sc->sc_rts = onoff;
- uchcom_set_dtrrts(sc);
+ uchcom_set_dtr_rts(sc);
}
static void
@@ -716,8 +640,6 @@
DPRINTF("\n");
uchcom_update_version(sc);
- uchcom_clear_chip(sc);
- uchcom_reset_chip(sc);
uchcom_update_status(sc);
}
@@ -744,8 +666,16 @@
{
struct uchcom_softc *sc = ucom->sc_parent;
- uchcom_set_line_control(sc, t->c_cflag);
- uchcom_set_dte_rate(sc, t->c_ospeed);
+ uchcom_get_version(sc, 0);
+ uchcom_ctrl_write(sc, UCHCOM_REQ_RESET, 0, 0);
+ uchcom_set_baudrate(sc, t->c_ospeed);
+ uchcom_read_reg(sc, 0x18, 0, 0x25, 0);
+ uchcom_write_reg(sc, 0x18, 0x50, 0x25, 0x00);
+ uchcom_update_status(sc);
+ uchcom_ctrl_write(sc, UCHCOM_REQ_RESET, 0x501f, 0xd90a);
+ uchcom_set_baudrate(sc, t->c_ospeed);
+ uchcom_set_dtr_rts(sc);
+ uchcom_update_status(sc);
}
static void
@@ -846,14 +776,14 @@
tr_setup:
pc = usbd_xfer_get_frame(xfer, 0);
if (ucom_get_data(&sc->sc_ucom, pc, 0,
- UCHCOM_BULK_BUF_SIZE, &actlen)) {
+ usbd_xfer_max_len(xfer), &actlen)) {
DPRINTF("actlen = %d\n", actlen);
usbd_xfer_set_frame_len(xfer, 0, actlen);
usbd_transfer_submit(xfer);
}
- return;
+ break;
default: /* Error */
if (error != USB_ERR_CANCELLED) {
@@ -861,8 +791,7 @@
usbd_xfer_set_stall(xfer);
goto tr_setup;
}
- return;
-
+ break;
}
}
@@ -877,14 +806,17 @@
switch (USB_GET_STATE(xfer)) {
case USB_ST_TRANSFERRED:
- pc = usbd_xfer_get_frame(xfer, 0);
- ucom_put_data(&sc->sc_ucom, pc, 0, actlen);
+
+ if (actlen > 0) {
+ pc = usbd_xfer_get_frame(xfer, 0);
+ ucom_put_data(&sc->sc_ucom, pc, 0, actlen);
+ }
case USB_ST_SETUP:
tr_setup:
usbd_xfer_set_frame_len(xfer, 0, usbd_xfer_max_len(xfer));
usbd_transfer_submit(xfer);
- return;
+ break;
default: /* Error */
if (error != USB_ERR_CANCELLED) {
@@ -892,7 +824,7 @@
usbd_xfer_set_stall(xfer);
goto tr_setup;
}
- return;
+ break;
}
}
==== //depot/projects/usb/src/sys/dev/usb/usbdevs#80 (text+ko) ====
@@ -626,6 +626,7 @@
vendor QCOM 0x18e8 Qcom
vendor LINKSYS3 0x1915 Linksys
vendor QUALCOMMINC 0x19d2 Qualcomm, Incorporated
+vendor WCH2 0x1a86 QinHeng Electronics
vendor STELERA 0x1a8d Stelera Wireless
vendor MPMAN 0x1cae MpMan
vendor DRESDENELEKTRONIK 0x1cf1 dresden elektronik
@@ -2506,8 +2507,10 @@
product WACOM GRAPHIRE3_4X5 0x0013 Graphire 3 4x5
product WACOM INTUOSA5 0x0021 Intuos A5
product WACOM GD0912U 0x0022 Intuos 9x12 Graphics Tablet
-/* WCH products*/
+/* WCH products */
product WCH CH341SER 0x5523 CH341/CH340 USB-Serial Bridge
+/* WCH products */
+product WCH2 CH341SER 0x7523 CH341/CH340 USB-Serial Bridge
/* Western Digital products */
product WESTERN COMBO 0x0200 Firewire USB Combo
product WESTERN EXTHDD 0x0400 External HDD
==== //depot/projects/usb/src/sys/modules/usb/Makefile#21 (text+ko) ====
@@ -29,7 +29,7 @@
SUBDIR += ehci musb ohci uhci uss820dci ${_at91dci} ${_atmegadci}
SUBDIR += rum uath upgt ural zyd ${_urtw}
SUBDIR += uhid ukbd ums udbp ufm
-SUBDIR += ucom u3g uark ubsa ubser uch341 uchcom ucycom ufoma uftdi ugensa uipaq ulpt \
+SUBDIR += ucom u3g uark ubsa ubser uchcom ucycom ufoma uftdi ugensa uipaq ulpt \
umct umodem umoscom uplcom uslcom uvisor uvscom
SUBDIR += uether aue axe cdce cue kue rue udav
SUBDIR += usfs umass urio
More information about the p4-projects
mailing list