usb/119002: add "ucp" driver support
Steve Franks
stevefranks at ieee.org
Mon Dec 24 13:20:02 PST 2007
>Number: 119002
>Category: usb
>Synopsis: add "ucp" driver support
>Confidential: no
>Severity: non-critical
>Priority: medium
>Responsible: freebsd-usb
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: update
>Submitter-Id: current-users
>Arrival-Date: Mon Dec 24 21:20:01 UTC 2007
>Closed-Date:
>Last-Modified:
>Originator: Steve Franks
>Release: 6.2-amd64
>Organization:
>Environment:
FreeBSD aire.franks-development.dyndns.biz 6.2-RELEASE-p7 FreeBSD 6.2-RELEASE-p7 #1: Mon Dec 24 11:13:11 MST 2007 steve at aire.franks-development.dyndns.biz:/usr/obj/usr/src/sys/GENERIC amd64
>Description:
All the *BSD's except FreeBSD apparently have support for the "ucp" device driver - Silicon Laboratories CP210x USB to UART/rs-232 bridge chip. All pertinent listserv entries are from 2006, so this has been the case for sometime.
I am unable to build the module on my system due to being a n00b, so far as I can tell - others have built it successfully, although /sys/dev/usb/usbdevs must be merged manually from the diff file in circulation (http://www.dons.net.au/~darius/ucp-0.01.diff.gz)
I was told to submit a PR to add this driver by several users on freebsd-questions (thread: "how to compile and install a new driver").
While the original author of the patch had reservations about the advanced functionality, as an electrical engineer using this part for several years, I find no one uses the advanced features, and the existing diff should make a fully functional driver (if I could get it to build)...
>How-To-Repeat:
cd /usr/src/sys
patch < ucp-0.01.diff
cd ..
make buildkernel KERNCONF=GENERIC
>Fix:
unknown.
Patch attached with submission follows:
Index: modules/ucp/Makefile
===================================================================
RCS file: modules/ucp/Makefile
diff -N modules/ucp/Makefile
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ modules/ucp/Makefile 9 May 2006 00:42:24 -0000
@@ -0,0 +1,10 @@
+# $FreeBSD$
+
+S= ${.CURDIR}/../..
+.PATH: $S/dev/usb
+
+KMOD= ucp
+SRCS= ucp.c ucpreg.h opt_usb.h device_if.h bus_if.h usbdevs.h
+
+CFLAGS+=-DUSB_DEBUG
+.include <bsd.kmod.mk>
Index: dev/usb/ucp.c
===================================================================
RCS file: dev/usb/ucp.c
diff -N dev/usb/ucp.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ dev/usb/ucp.c 9 May 2006 00:44:56 -0000
@@ -0,0 +1,590 @@
+/*
+ * Silicon Labs CP2101/2102 USB UART driver
+ *
+ * Based on the Linux driver written by Craig Shelley <craig at microtron.org.uk>
+ *
+ * Copyright (C) 2006 Daniel O'Connor <doconnor at gsoft.com.au>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/cdefs.h>
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/malloc.h>
+#include <sys/module.h>
+#include <sys/bus.h>
+#include <sys/ioccom.h>
+#include <sys/fcntl.h>
+#include <sys/conf.h>
+#include <sys/tty.h>
+#include <sys/serial.h>
+#include <sys/file.h>
+
+#include <sys/selinfo.h>
+
+#include <sys/sysctl.h>
+
+#include <sys/endian.h>
+
+#include <machine/bus.h>
+#include <sys/bus_dma.h>
+
+#include <dev/usb/usb.h>
+#include <dev/usb/usbdi.h>
+#include <dev/usb/usbdi_util.h>
+#include <dev/usb/usbdivar.h>
+#include "usbdevs.h"
+
+#include <dev/usb/ucomvar.h>
+
+#include <dev/usb/ucpreg.h>
+
+
+#ifdef USB_DEBUG
+static int ucpdebug = 0;
+SYSCTL_NODE(_hw_usb, OID_AUTO, ucp, CTLFLAG_RW, 0, "USB ucp");
+SYSCTL_INT(_hw_usb_ucp, OID_AUTO, debug, CTLFLAG_RW,
+ &ucpdebug, 0, "ucp debug level");
+#define DPRINTF(x) do { \
+ if (ucpdebug) \
+ logprintf x; \
+ } while (0)
+
+#define DPRINTFN(n, x) do { \
+ if (ucpdebug > (n)) \
+ logprintf x; \
+ } while (0)
+
+#else
+#define DPRINTF(x)
+#define DPRINTFN(n,x)
+#endif
+
+#define UCP_CONFIG_INDEX 0
+#define UCP_IFACE_INDEX 0
+
+/* XXX: Pretty sure this is right... */
+#define UCPIBUFSIZE 64
+#define UCPOBUFSIZE 64
+
+struct ucp_softc {
+ struct ucom_softc sc_ucom;
+
+ usbd_interface_handle sc_iface; /* interface */
+};
+
+Static int ucp_open(void *sc, int portno);
+Static void ucp_close(void *sc, int portno);
+Static void ucp_set(void *, int, int, int);
+Static int ucp_param(void *, int, struct termios *);
+Static void ucp_get_status(void *, int portno, u_char *lsr, u_char *msr);
+Static void ucp_break(void *sc, int portno, int onoff);
+Static int ucp_set_config(struct ucom_softc *ucom, uint8_t request, uint16_t data);
+Static int ucp_get_config(struct ucom_softc *ucom, uint8_t request, uint16_t *data);
+
+struct ucom_callback ucp_callback = {
+ .ucom_get_status = ucp_get_status,
+ .ucom_set = ucp_set,
+ .ucom_param = ucp_param,
+ .ucom_open = ucp_open,
+ .ucom_close = ucp_close,
+};
+
+static const struct usb_devno ucp_devs[] = {
+ { USB_VENDOR_SILABS, USB_PRODUCT_SILABS_CRUMB128 },
+ { USB_VENDOR_SILABS, USB_PRODUCT_SILABS_DEGREE },
+ { USB_VENDOR_SILABS, USB_PRODUCT_SILABS_SUUNTO },
+ { USB_VENDOR_SILABS, USB_PRODUCT_SILABS_BURNSIDE },
+ { USB_VENDOR_SILABS, USB_PRODUCT_SILABS_HELICOM },
+ { USB_VENDOR_SILABS, USB_PRODUCT_SILABS_CP2102 },
+ { USB_VENDOR_PLX, USB_PRODUCT_PLX_NOKIA_CA42 }
+
+};
+
+USB_MATCH(ucp) {
+ USB_MATCH_START(ucp, uaa);
+
+ DPRINTFN(20,("ucp: vendor=0x%x, product=0x%x\n",
+ uaa->vendor, uaa->product));
+
+ if (uaa->iface != NULL)
+ return UMATCH_NONE;
+
+ return (usb_lookup(ucp_devs, uaa->vendor, uaa->product) != NULL) ?
+ UMATCH_VENDOR_PRODUCT : UMATCH_NONE;
+}
+
+USB_ATTACH(ucp) {
+ USB_ATTACH_START(ucp, sc, uaa);
+ usbd_device_handle dev = uaa->device;
+ usbd_interface_handle iface;
+ usb_interface_descriptor_t *id;
+ usb_endpoint_descriptor_t *ed;
+ char *devinfo;
+ const char *devname;
+ int i;
+ usbd_status err;
+ struct ucom_softc *ucom = &sc->sc_ucom;
+
+ DPRINTFN(10,("\nucp_attach: sc=%p\n", sc));
+ devinfo = malloc(1024, M_USBDEV, M_WAITOK);
+
+ ucom->sc_dev = self;
+ ucom->sc_udev = dev;
+
+ devname = USBDEVNAME(ucom->sc_dev);
+
+ if (uaa->iface == NULL) {
+ /* Move the device into the configured state. */
+ err = usbd_set_config_index(dev, UCP_CONFIG_INDEX, 1);
+ if (err) {
+ printf("\n%s: failed to set configuration, err=%s\n",
+ devname, usbd_errstr(err));
+ goto bad;
+ }
+
+ err = usbd_device2interface_handle(dev, UCP_IFACE_INDEX, &iface);
+ if (err) {
+ printf("\n%s: failed to get interface, err=%s\n",
+ devname, usbd_errstr(err));
+ goto bad;
+ }
+ } else {
+ iface = uaa->iface;
+ }
+
+ usbd_devinfo(dev, 0, devinfo);
+ /* USB_ATTACH_SETUP;*/
+ printf("%s: %s\n", devname, devinfo);
+
+ id = usbd_get_interface_descriptor(iface);
+ ucom->sc_iface = iface;
+ ucom->sc_bulkin_no = ucom->sc_bulkout_no = -1;
+
+ for (i = 0; i < id->bNumEndpoints; i++) {
+ int addr, dir, attr;
+ ed = usbd_interface2endpoint_descriptor(iface, i);
+ if (ed == NULL) {
+ printf("%s: could not read endpoint descriptor\n",
+ devname);
+ goto bad;
+ }
+
+ addr = ed->bEndpointAddress;
+ dir = UE_GET_DIR(ed->bEndpointAddress);
+ attr = ed->bmAttributes & UE_XFERTYPE;
+ if (dir == UE_DIR_IN && attr == UE_BULK)
+ ucom->sc_bulkin_no = addr;
+ else if (dir == UE_DIR_OUT && attr == UE_BULK)
+ ucom->sc_bulkout_no = addr;
+ else {
+ printf("%s: unexpected endpoint\n", devname);
+ goto bad;
+ }
+ }
+ if (ucom->sc_bulkin_no == -1) {
+ printf("%s: Could not find data bulk in\n",
+ devname);
+ goto bad;
+ }
+ if (ucom->sc_bulkout_no == -1) {
+ printf("%s: Could not find data bulk out\n",
+ devname);
+ goto bad;
+ }
+ ucom->sc_parent = sc;
+ if (uaa->iface == NULL)
+ ucom->sc_portno = 0;
+
+ /* bulkin, bulkout set above */
+
+ ucom->sc_ibufsize = UCPIBUFSIZE;
+ ucom->sc_obufsize = UCPOBUFSIZE;
+ ucom->sc_ibufsizepad = UCPIBUFSIZE;
+
+ ucom->sc_callback = &ucp_callback;
+#if 0
+ usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, ucom->sc_udev,
+ USBDEV(ucom->sc_dev));
+#endif
+ DPRINTF(("ucp: in=0x%x out=0x%x\n", ucom->sc_bulkin_no, ucom->sc_bulkout_no));
+ ucom_attach(&sc->sc_ucom);
+ free(devinfo, M_USBDEV);
+
+ USB_ATTACH_SUCCESS_RETURN;
+
+bad:
+ DPRINTF(("ucp_attach: ATTACH ERROR\n"));
+ ucom->sc_dying = 1;
+ free(devinfo, M_USBDEV);
+
+ USB_ATTACH_ERROR_RETURN;
+}
+
+USB_DETACH(ucp)
+{
+ USB_DETACH_START(ucp, sc);
+
+ int rv = 0;
+
+ DPRINTF(("ucp_detach: sc=%p\n", sc));
+ sc->sc_ucom.sc_dying = 1;
+ rv = ucom_detach(&sc->sc_ucom);
+
+ return rv;
+}
+
+Static int
+ucp_open(void *vsc, int portno) {
+ struct ucp_softc *sc = vsc;
+ struct ucom_softc *ucom = &sc->sc_ucom;
+ struct termios t;
+
+ DPRINTF(("ucp_open: sc=%p\n", sc));
+
+ if (ucom->sc_dying)
+ return (EIO);
+
+ DPRINTFN(2, ("Enabling UART\n"));
+ if (ucp_set_config(ucom, CP2101_UART, UART_ENABLE)) {
+ printf("Unable to enable UART\n");
+ return(EIO);
+ }
+
+ /* Set 9600 baud, 2 stop bits, no parity, 8 bits, RTS/CTS flow control */
+ t.c_ospeed = 9600;
+ t.c_cflag = CSTOPB | CS8 | CRTSCTS;
+ (void)ucp_param(sc, 0, &t);
+
+ return(0);
+}
+
+Static void
+ucp_close(void *vsc, int portno) {
+ struct ucp_softc *sc = vsc;
+ struct ucom_softc *ucom = &sc->sc_ucom;
+
+ DPRINTF(("ucp_close: sc=%p\n", sc));
+
+ if (ucom->sc_dying)
+ return;
+
+ DPRINTFN(2, ("Disabling UART\n"));
+ if (ucp_set_config(ucom, CP2101_UART, UART_DISABLE)) {
+ printf("Unable to disable UART\n");
+ return;
+ }
+}
+
+/* Set DTR/RTS or send a break */
+Static void
+ucp_set(void *vsc, int portno, int reg, int onoff) {
+ struct ucp_softc * sc = vsc;
+ struct ucom_softc * ucom = &sc->sc_ucom;
+ uint16_t ctl;
+
+ DPRINTF(("ucp_set: port=%d reg=%d onoff=%d\n", portno, reg, onoff));
+
+ switch (reg) {
+ case UCOM_SET_DTR:
+ DPRINTFN(2, ("Setting DTR\n"));
+ ctl = CONTROL_WRITE_DTR;
+ if (onoff)
+ ctl |= CONTROL_DTR;
+ else
+ ctl &= ~CONTROL_DTR;
+ break;
+
+ case UCOM_SET_RTS:
+ ctl = 0;
+#if 0
+ DPRINTFN(2, ("Setting RTS\n"));
+ ctl = CONTROL_WRITE_RTS;
+ if (onoff)
+ ctl |= CONTROL_RTS;
+ else
+ ctl &= ~CONTROL_RTS;
+#endif
+ break;
+
+ case UCOM_SET_BREAK:
+ DPRINTFN(2, ("Setting BREAK\n"));
+ ucp_break(vsc, portno, onoff);
+ return;
+
+ default:
+ return;
+ }
+
+ (void)ucp_set_config(ucom, CP2101_CONTROL, ctl);
+}
+
+/* Set baud rate, stop/start bits, parity etc */
+Static int
+ucp_param(void *vsc, int portno, struct termios *t) {
+ struct ucp_softc * sc = vsc;
+ struct ucom_softc * ucom = &sc->sc_ucom;
+ int i;
+ uint16_t dat;
+ uint32_t modem_ctl[4];
+#if 1
+ usb_device_request_t req;
+ usbd_status result;
+#endif
+
+ DPRINTF(("ucp_param: sc=%p\n", sc));
+
+ if (ucom->sc_dying)
+ return (EIO);
+
+ switch (t->c_ospeed) {
+ case 300:
+ case 600:
+ case 1200:
+ case 2400:
+ case 4800:
+ case 9600:
+ case 19200:
+ case 38400:
+ case 57600:
+ case 115200:
+ if (ucp_set_config(ucom, CP2101_BAUDRATE, BAUD_RATE_GEN_FREQ / t->c_ospeed) != 0)
+ printf("Setting baud rate failed\n");
+
+ break;
+
+ default:
+ printf("Invalid baud rate %d\n", t->c_ospeed);
+ break;
+ }
+
+ if (ucp_get_config(ucom, CP2101_BITS, &dat) != 0) {
+ printf("Couldn't read frame format\n");
+ return(EIO);
+ }
+ DPRINTFN(2,("BITS is 0x%02x\n", dat));
+
+ dat &= ~BITS_STOP_MASK;
+ if (ISSET(t->c_cflag, CSTOPB))
+ dat |= BITS_STOP_2;
+ else
+ dat |= BITS_STOP_1;
+
+ dat &= ~BITS_PARITY_MASK;
+ if (ISSET(t->c_cflag, PARENB)) {
+ if (ISSET(t->c_cflag, PARODD))
+ dat |= BITS_PARITY_ODD;
+ else
+ dat |= BITS_PARITY_EVEN;
+ }
+
+ dat &= ~BITS_DATA_MASK;
+ switch (ISSET(t->c_cflag, CSIZE)) {
+ case CS5:
+ dat |= BITS_DATA_5;
+ break;
+ case CS6:
+ dat |= BITS_DATA_6;
+ break;
+ case CS7:
+ dat |= BITS_DATA_7;
+ break;
+ case CS8:
+ dat |= BITS_DATA_8;
+ break;
+ }
+
+ DPRINTFN(2,("Settings BITS to 0x%02x\n", dat));
+ if (ucp_get_config(ucom, CP2101_BITS, &dat) != 0) {
+ printf("Couldn't set frame format\n");
+ }
+
+#if 1
+ req.bmRequestType = UT_READ_VENDOR_INTERFACE;
+ req.bRequest = CP2101_MODEMCTL + 1;
+ USETW(req.wIndex, 0);
+ USETW(req.wValue, 0);
+ USETW(req.wLength, 16);
+
+ result = usbd_do_request(ucom->sc_udev, &req, modem_ctl);
+
+ if (result != USBD_NORMAL_COMPLETION) {
+ printf("failed to get modem control registers - %d\n", result);
+ return(EIO);
+ }
+#endif
+ for (i = 0; i < 4; i++)
+ modem_ctl[i] = le32toh(modem_ctl[i]);
+
+ DPRINTFN(2, ("modem_ctl[3..0] => 0x%08x 0x%08x 0x%08x 0x%08x\n",
+ modem_ctl[3], modem_ctl[2], modem_ctl[1], modem_ctl[0]));
+
+ if (ISSET(t->c_cflag, CRTSCTS)) {
+ DPRINTFN(2, ("Setting for RTS/CTS\n"));
+ modem_ctl[0] &= ~0x7B;
+ modem_ctl[0] |= 0x09;
+ modem_ctl[1] = 0x80;
+ } else if (ISSET(t->c_iflag, IXON|IXOFF)) {
+ DPRINTFN(2, ("Setting for XON/XOFF\n"));
+ /* XXX: what do I do here? Duplicating 'none' for now */
+ modem_ctl[0] &= ~0x7B;
+ modem_ctl[0] |= 0x01;
+ modem_ctl[1] |= 0x40;
+ } else {
+ DPRINTFN(2, ("Setting for none\n"));
+ modem_ctl[0] &= ~0x7B;
+ modem_ctl[0] |= 0x01;
+ modem_ctl[1] |= 0x40;
+ }
+ DPRINTFN(2, ("modem_ctl[3..0] <= 0x%08x 0x%08x 0x%08x 0x%08x\n",
+ modem_ctl[3], modem_ctl[2], modem_ctl[1], modem_ctl[0]));
+
+ for (i = 0; i < 4; i++)
+ modem_ctl[i] = htole32(modem_ctl[i]);
+#if 1
+ req.bmRequestType = UT_WRITE_VENDOR_INTERFACE;
+ req.bRequest = CP2101_MODEMCTL;
+ USETW(req.wIndex, 0);
+ USETW(req.wValue, 0);
+ USETW(req.wLength, 16);
+
+ result = usbd_do_request(ucom->sc_udev, &req, modem_ctl);
+
+ if (result != USBD_NORMAL_COMPLETION) {
+ printf("failed to get modem control registers - %d\n", result);
+ return(EIO);
+ }
+#endif
+ return (0);
+}
+
+void
+ucp_get_status(void *vsc, int portno, u_char *lsr, u_char *msr) {
+ struct ucp_softc * sc = vsc;
+ struct ucom_softc * ucom = &sc->sc_ucom;
+ uint16_t dat;
+
+ if (ucp_get_config(ucom, CP2101_CONTROL, &dat) != 0) {
+ printf("Couldn't get control information\n");
+ }
+
+ /* lsr appears to be unused in ucom */
+ *lsr = 0;
+ *msr = ((dat & CONTROL_DCD) ? SER_DCD : 0) |
+ ((dat & CONTROL_CTS) ? SER_CTS : 0) |
+ ((dat & CONTROL_RING) ? SER_RI : 0) |
+ ((dat & CONTROL_DSR) ? SER_DSR : 0);
+
+
+ DPRINTF(("ucp_status: msr=0x%02x lsr=0x%02x\n",
+ *msr, *lsr));
+}
+
+/*
+ * ucp_break
+ * Set/clear the break condition
+ */
+void
+ucp_break(void *vsc, int portno, int onoff) {
+ struct ucp_softc * sc = vsc;
+ struct ucom_softc * ucom = &sc->sc_ucom;
+
+ DPRINTF(("ucp_break: port=%d onoff=%d\n", portno, onoff));
+
+ if (ucp_set_config(ucom, CP2101_BREAK, onoff ? BREAK_ON : BREAK_OFF))
+ printf("Unable to change BREAK status\n");
+}
+
+/*
+ * ucp_set_config
+ * Writes to the CP2101 configuration registers
+ */
+Static int
+ucp_set_config(struct ucom_softc *ucom, uint8_t request, uint16_t data) {
+ usb_device_request_t req;
+ usbd_status result;
+
+ DPRINTFN(2,("ucp_set: request = 0x%04x <= 0x%04x\n", req.bRequest, data));
+
+ req.bmRequestType = UT_WRITE_VENDOR_INTERFACE;
+ req.bRequest = request;
+ USETW(req.wIndex, 0);
+ USETW(req.wValue, data);
+ USETW(req.wLength, 0);
+ if ((result = usbd_do_request(ucom->sc_udev, &req, NULL)) != USBD_NORMAL_COMPLETION) {
+ printf("failed to set config part a - %d\n", result);
+ return(EIO);
+ }
+
+ if ((result = usbd_do_request(ucom->sc_udev, &req, NULL)) != USBD_NORMAL_COMPLETION) {
+ printf("failed to set config part b - %d\n", result);
+ return(EIO);
+ }
+
+ return 0;
+}
+
+/*
+ * ucp_get_config
+ * Reads from the CP2101 configuration registers
+ */
+Static int
+ucp_get_config(struct ucom_softc *ucom, uint8_t request, uint16_t *data) {
+ usb_device_request_t req;
+ usbd_status result;
+
+ req.bmRequestType = UT_READ_VENDOR_INTERFACE;
+ req.bRequest = request + 1;
+ USETW(req.wIndex, 0);
+ USETW(req.wValue, 0);
+ USETW(req.wLength, 2);
+
+ if ((result = usbd_do_request(ucom->sc_udev, &req, data)) != USBD_NORMAL_COMPLETION) {
+ printf("failed to get config - %d\n", result);
+ return(EIO);
+ }
+ *data = le16toh(*data);
+
+ DPRINTFN(2,("ucp_get: request = 0x%04x => 0x%04x\n", req.bRequest, *data));
+
+ return 0;
+}
+
+Static device_method_t ucp_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, ucp_match),
+ DEVMETHOD(device_attach, ucp_attach),
+ DEVMETHOD(device_detach, ucp_detach),
+
+ { 0, 0 }
+};
+
+Static driver_t ucp_driver = {
+ "ucom",
+ ucp_methods,
+ sizeof (struct ucp_softc)
+};
+
+DRIVER_MODULE(ucp, uhub, ucp_driver, ucom_devclass, usbd_driver_load, 0);
+MODULE_DEPEND(ucp, usb, 1, 1, 1);
+MODULE_DEPEND(ucp, ucom,UCOM_MINVER, UCOM_PREFVER, UCOM_MAXVER);
+
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
Index: dev/usb/ucpreg.h
===================================================================
RCS file: dev/usb/ucpreg.h
diff -N dev/usb/ucpreg.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ dev/usb/ucpreg.h 9 May 2006 00:35:32 -0000
@@ -0,0 +1,61 @@
+/* $FreeBSD$ */
+
+/*
+ * Definitions for the SI Labs CP 2101/2102
+ */
+
+/* Config SET requests. To GET, add 1 to the request number */
+#define CP2101_UART 0x00 /* Enable / Disable */
+#define CP2101_BAUDRATE 0x01 /* (BAUD_RATE_GEN_FREQ / baudrate) */
+#define CP2101_BITS 0x03 /* 0x(0)(databits)(parity)(stopbits) */
+#define CP2101_BREAK 0x05 /* On / Off */
+#define CP2101_CONTROL 0x07 /* Flow control line states */
+#define CP2101_MODEMCTL 0x13 /* Modem controls */
+#define CP2101_CONFIG_6 0x19 /* 6 bytes of config data ??? */
+
+/* CP2101_UART */
+#define UART_ENABLE 0x0001
+#define UART_DISABLE 0x0000
+
+/* CP2101_BAUDRATE */
+#define BAUD_RATE_GEN_FREQ 0x384000
+
+/* CP2101_BITS */
+#define BITS_DATA_MASK 0X0f00
+#define BITS_DATA_5 0X0500
+#define BITS_DATA_6 0X0600
+#define BITS_DATA_7 0X0700
+#define BITS_DATA_8 0X0800
+#define BITS_DATA_9 0X0900
+
+#define BITS_PARITY_MASK 0x00f0
+#define BITS_PARITY_NONE 0x0000
+#define BITS_PARITY_ODD 0x0010
+#define BITS_PARITY_EVEN 0x0020
+#define BITS_PARITY_MARK 0x0030
+#define BITS_PARITY_SPACE 0x0040
+
+#define BITS_STOP_MASK 0x000f
+#define BITS_STOP_1 0x0000
+#define BITS_STOP_1_5 0x0001
+#define BITS_STOP_2 0x0002
+
+/* CP2101_BREAK */
+#define BREAK_ON 0x0000
+#define BREAK_OFF 0x0001
+
+/* CP2101_CONTROL */
+#define CONTROL_DTR 0x0001
+#define CONTROL_RTS 0x0002
+#define CONTROL_CTS 0x0010
+#define CONTROL_DSR 0x0020
+#define CONTROL_RING 0x0040
+#define CONTROL_DCD 0x0080
+#define CONTROL_WRITE_DTR 0x0100
+#define CONTROL_WRITE_RTS 0x0200
+
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
Index: dev/usb/usbdevs
===================================================================
RCS file: /usr/CVS-Repository/src/sys/dev/usb/usbdevs,v
retrieving revision 1.255
diff -u -r1.255 usbdevs
--- dev/usb/usbdevs 27 Feb 2006 01:01:27 -0000 1.255
+++ dev/usb/usbdevs 9 May 2006 00:44:27 -0000
@@ -493,6 +493,7 @@
vendor CCYU 0x1065 CCYU
vendor PLX 0x10b5 PLX
vendor ASANTE 0x10bd Asante
+vendor SILABS 0x10c4 SI Labs
vendor JRC 0x1145 JRC
vendor DELORME 0x1163 DeLorme
vendor SERVERWORKS 0x1166 ServerWorks
@@ -1360,6 +1361,7 @@
/* PLX products */
product PLX TESTBOARD 0x9060 test board
+product PLX NOKIA_CA42 0xac70 Nokia CA-42 USB
/* PNY products */
product PNY ATTACHE2 0x0010 USB 2.0 Flash Drive
@@ -1478,6 +1480,14 @@
product SIIG WINTERREADER 0x0330 WINTERREADER Reader
product SIIG2 US2308 0x0421 Serial
+/* SI Labs */
+product SILABS CRUMB128 0x807a Crumb128 board
+product SILABS DEGREE 0x80ca Degree Controls Inc
+product SILABS SUUNTO 0x80f6 Suunto Sports Instrument
+product SILABS BURNSIDE 0x813d Burnside Telecon Deskmobile
+product SILABS HELICOM 0x815e Helicomm IP-Link 1220-DVM
+product SILABS CP2102 0xea60 SILABS USB UART
+
/* Silicon Portals Inc. */
product SILICONPORTALS YAPPH_NF 0x0200 YAP Phone (no firmware)
product SILICONPORTALS YAPPHONE 0x0201 YAP Phone
>Release-Note:
>Audit-Trail:
>Unformatted:
More information about the freebsd-usb
mailing list