>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     [EMAIL 
PROTECTED]:/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 <[EMAIL PROTECTED]>
+ *
+ * Copyright (C) 2006 Daniel O'Connor <[EMAIL PROTECTED]>
+ * 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:
_______________________________________________
[email protected] mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-usb
To unsubscribe, send any mail to "[EMAIL PROTECTED]"

Reply via email to