Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 24 Dec 2007 21:15:58 GMT
From:      Steve Franks <stevefranks@ieee.org>
To:        freebsd-gnats-submit@FreeBSD.org
Subject:   usb/119002: add "ucp" driver support
Message-ID:  <200712242115.lBOLFw0L097454@www.freebsd.org>
Resent-Message-ID: <200712242120.lBOLK1o4072630@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help


>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@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@microtron.org.uk>
+ *
+ * Copyright (C) 2006 Daniel O'Connor <doconnor@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:



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200712242115.lBOLFw0L097454>