diff options
author | maxim <maxim@FreeBSD.org> | 2006-11-15 09:13:25 +0000 |
---|---|---|
committer | maxim <maxim@FreeBSD.org> | 2006-11-15 09:13:25 +0000 |
commit | e4467958862a45640eca20ed59032f70cb477d2e (patch) | |
tree | 1f66f5eea8e83333db19875570a1a68aa1320137 | |
parent | 6f35e53e01711db0a4fac8ab2aee62540f62a9c5 (diff) | |
download | FreeBSD-src-e4467958862a45640eca20ed59032f70cb477d2e.zip FreeBSD-src-e4467958862a45640eca20ed59032f70cb477d2e.tar.gz |
o Add uark(4), a driver for Arkmicro Technologies ARK3116 based serial
adapters.
Submitted by: Alex Rodin
Obtained from: OpenBSD
Reviewed by: -usb
MFC after: 6 weeks
-rw-r--r-- | share/man/man4/Makefile | 1 | ||||
-rw-r--r-- | share/man/man4/uark.4 | 69 | ||||
-rw-r--r-- | sys/conf/NOTES | 2 | ||||
-rw-r--r-- | sys/conf/files | 1 | ||||
-rw-r--r-- | sys/dev/usb/uark.c | 367 | ||||
-rw-r--r-- | sys/dev/usb/usbdevs | 4 | ||||
-rw-r--r-- | sys/modules/Makefile | 1 | ||||
-rw-r--r-- | sys/modules/uark/Makefile | 8 |
8 files changed, 453 insertions, 0 deletions
diff --git a/share/man/man4/Makefile b/share/man/man4/Makefile index e400be5..ebdc0de 100644 --- a/share/man/man4/Makefile +++ b/share/man/man4/Makefile @@ -349,6 +349,7 @@ MAN= aac.4 \ twe.4 \ tx.4 \ txp.4 \ + uark.4 \ uart.4 \ ubsa.4 \ ubsec.4 \ diff --git a/share/man/man4/uark.4 b/share/man/man4/uark.4 new file mode 100644 index 0000000..46a91e1 --- /dev/null +++ b/share/man/man4/uark.4 @@ -0,0 +1,69 @@ +.\" $OpenBSD: uark.4,v 1.3 2006/10/26 19:42:36 jmc Exp $ +.\" +.\" Copyright (c) 2006 Jonathan Gray <jsg@openbsd.org> +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.\" $FreeBSD$ +.\" +.Dd November 9, 2006 +.Dt UARK 4 +.Os +.Sh NAME +.Nm uark +.Nd Arkmicro Technologies ARK3116 based USB serial adapter +.Sh SYNOPSIS +.Cd "device uark" +.Cd "device ucom" +.Sh DESCRIPTION +The +.Nm +driver supports Arkmicro Technologies ARK3116 based serial adapters. +.Pp +The following devices should work with the +.Nm +driver: +.Pp +.Bl -bullet -compact +.It +HL USB-RS232 +.It +HugePine USB-UART +.It +KQ-U8A Data Cable +.It +Skymaster USB to RS232 +.El +.Sh SEE ALSO +.Xr tty 4 , +.Xr ucom 4 , +.Xr uhub 4 , +.Xr usb 4 +.Sh HISTORY +The +.Nm +device driver first appeared in +.Ox 4.0 . +.Sh AUTHORS +.An -nosplit +The +.Nm +driver was written by +.An Jonathan Gray +.Aq jsg@openbsd.org . +.Sh CAVEATS +Setting hardware flow control is not currently supported. +It is not yet known how to ask the hardware to send a break. +.Pp +Arkmicro Technologies do not reply to requests of documentation +for their products. diff --git a/sys/conf/NOTES b/sys/conf/NOTES index 2ab99f0..c603023 100644 --- a/sys/conf/NOTES +++ b/sys/conf/NOTES @@ -2397,6 +2397,8 @@ device uscanner # # USB serial support device ucom +# USB support for Technologies ARK3116 based serial adapters +device uark # USB support for Belkin F5U103 and compatible serial adapters device ubsa # USB support for BWCT console serial adapters diff --git a/sys/conf/files b/sys/conf/files index ff1388f..5f45746 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -1037,6 +1037,7 @@ dev/usb/ohci.c optional ohci dev/usb/ohci_pci.c optional ohci pci dev/usb/sl811hs.c optional slhci dev/usb/slhci_pccard.c optional slhci pccard +dev/usb/uark.c optional uark dev/usb/ubsa.c optional ubsa dev/usb/ubser.c optional ubser dev/usb/ucom.c optional ucom diff --git a/sys/dev/usb/uark.c b/sys/dev/usb/uark.c new file mode 100644 index 0000000..5aefc9f --- /dev/null +++ b/sys/dev/usb/uark.c @@ -0,0 +1,367 @@ +/* $OpenBSD: uark.c,v 1.1 2006/08/14 08:30:22 jsg Exp $ */ + +/* + * Copyright (c) 2006 Jonathan Gray <jsg@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * $FreeBSD$ + */ +#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/file.h> +#include <sys/selinfo.h> +#include <sys/sysctl.h> + +#include <dev/usb/usb.h> +#include <dev/usb/usbdi.h> +#include <dev/usb/usbdi_util.h> +#include "usbdevs.h" + +#include <dev/usb/ucomvar.h> + +#ifdef UARK_DEBUG +#define DPRINTFN(n, x) do { \ + if (uarkdebug > (n)) \ + logprintf x; \ +} while (0) +int uarkebug = 0; +#else +#define DPRINTFN(n, x) +#endif +#define DPRINTF(x) DPRINTFN(0, x) + +#define UARKBUFSZ 256 +#define UARK_CONFIG_NO 0 +#define UARK_IFACE_NO 0 + +#define UARK_SET_DATA_BITS(x) (x - 5) + +#define UARK_PARITY_NONE 0x00 +#define UARK_PARITY_ODD 0x08 +#define UARK_PARITY_EVEN 0x18 + +#define UARK_STOP_BITS_1 0x00 +#define UARK_STOP_BITS_2 0x04 + +#define UARK_BAUD_REF 3000000 + +#define UARK_WRITE 0x40 +#define UARK_READ 0xc0 + +#define UARK_REQUEST 0xfe + +#define UARK_CONFIG_INDEX 0 +#define UARK_IFACE_INDEX 0 + +struct uark_softc { + struct ucom_softc sc_ucom; + usbd_interface_handle sc_iface; + + u_char sc_msr; + u_char sc_lsr; +}; + +static void uark_get_status(void *, int portno, u_char *lsr, u_char *msr); +static void uark_set(void *, int, int, int); +static int uark_param(void *, int, struct termios *); +static void uark_break(void *, int, int); +static int uark_cmd(struct uark_softc *, uint16_t, uint16_t); + +struct ucom_callback uark_callback = { + uark_get_status, + uark_set, + uark_param, + NULL, + NULL, + NULL, + NULL, + NULL, +}; + +static const struct uark_product { + uint16_t vendor; + uint16_t product; +} uark_products[] = { + { USB_VENDOR_ARKMICRO, USB_PRODUCT_ARKMICRO_ARK3116 }, + { 0, 0 } +}; + +USB_MATCH(uark) +{ + USB_MATCH_START(uark, uaa); + int i; + + if (uaa->iface != NULL) + return (UMATCH_NONE); + + for (i = 0; uark_products[i].vendor != 0; i++) { + if (uark_products[i].vendor == uaa->vendor && + uark_products[i].product == uaa->product) { + return (UMATCH_VENDOR_PRODUCT); + } + } + + return (UMATCH_NONE); +} + +USB_ATTACH(uark) +{ + USB_ATTACH_START(uark, sc, uaa); + usbd_device_handle dev = uaa->device; + usbd_interface_handle iface; + usb_interface_descriptor_t *id; + usb_endpoint_descriptor_t *ed; + usbd_status error; + char *devinfo; + const char *devname; + int i; + struct ucom_softc *ucom = &sc->sc_ucom; + + devinfo = malloc(1024, M_USBDEV, M_WAITOK); + + bzero(ucom, sizeof(struct ucom_softc)); + ucom->sc_dev = self; + ucom->sc_udev = dev; + + devname = device_get_nameunit(ucom->sc_dev); + + if (uaa->iface == NULL) { + /* Move the device into the configured state. */ + error = usbd_set_config_index(dev, UARK_CONFIG_INDEX, 1); + if (error) { + printf("\n%s: failed to set configuration, err=%s\n", + devname, usbd_errstr(error)); + goto bad; + } + error = + usbd_device2interface_handle(dev, UARK_IFACE_INDEX, &iface); + if (error) { + printf("\n%s: failed to get interface, err=%s\n", + devname, usbd_errstr(error)); + goto bad; + } + } else + iface = uaa->iface; + + usbd_devinfo(dev, 0, devinfo); + 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++) { + ed = usbd_interface2endpoint_descriptor(iface, i); + if (ed == NULL) { + printf("%s: could not read endpoint descriptor\n", + devname); + goto bad; + } + if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && + UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) + ucom->sc_bulkin_no = ed->bEndpointAddress; + else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT && + UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) + ucom->sc_bulkout_no = ed->bEndpointAddress; + } + if (ucom->sc_bulkin_no == -1 || ucom->sc_bulkout_no == -1) { + printf("%s: missing endpoint\n", devname); + goto bad; + } + ucom->sc_parent = sc; + ucom->sc_ibufsize = UARKBUFSZ; + ucom->sc_obufsize = UARKBUFSZ; + ucom->sc_ibufsizepad = UARKBUFSZ; + ucom->sc_opkthdrlen = 0; + + ucom->sc_callback = &uark_callback; + + DPRINTF(("uark: 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(("uftdi_attach: ATTACH ERROR\n")); + ucom->sc_dying = 1; + free(devinfo, M_USBDEV); + + USB_ATTACH_ERROR_RETURN; +} + +USB_DETACH(uark) +{ + USB_DETACH_START(uark, sc); + int rv = 0; + + DPRINTF(("uark_detach: sc=%p\n", sc)); + sc->sc_ucom.sc_dying = 1; + rv = ucom_detach(&sc->sc_ucom); + + return (rv); +} + +static void +uark_set(void *vsc, int portno, int reg, int onoff) +{ + struct uark_softc *sc = vsc; + + switch (reg) { + case UCOM_SET_BREAK: + uark_break(sc, portno, onoff); + return; + /* NOTREACHED */ + case UCOM_SET_DTR: + case UCOM_SET_RTS: + default: + return; + /* NOTREACHED */ + } +} + +static int +uark_param(void *vsc, int portno, struct termios *t) +{ + struct uark_softc *sc = (struct uark_softc *)vsc; + int data; + + switch (t->c_ospeed) { + case 300: + case 600: + case 1200: + case 1800: + case 2400: + case 4800: + case 9600: + case 19200: + case 38400: + case 57600: + case 115200: + uark_cmd(sc, 3, 0x83); + uark_cmd(sc, 0, (UARK_BAUD_REF / t->c_ospeed) & 0xFF); + uark_cmd(sc, 1, (UARK_BAUD_REF / t->c_ospeed) >> 8); + uark_cmd(sc, 3, 0x03); + break; + default: + return (EINVAL); + /* NOTREACHED */ + } + if (ISSET(t->c_cflag, CSTOPB)) + data = UARK_STOP_BITS_2; + else + data = UARK_STOP_BITS_1; + + if (ISSET(t->c_cflag, PARENB)) { + if (ISSET(t->c_cflag, PARODD)) + data |= UARK_PARITY_ODD; + else + data |= UARK_PARITY_EVEN; + } else + data |= UARK_PARITY_NONE; + + switch (ISSET(t->c_cflag, CSIZE)) { + case CS5: + data |= UARK_SET_DATA_BITS(5); + break; + case CS6: + data |= UARK_SET_DATA_BITS(6); + break; + case CS7: + data |= UARK_SET_DATA_BITS(7); + break; + case CS8: + data |= UARK_SET_DATA_BITS(8); + break; + } + uark_cmd(sc, 3, 0x00); + uark_cmd(sc, 3, data); + + return (0); +} + +void +uark_get_status(void *vsc, int portno, u_char *lsr, u_char *msr) +{ + struct uark_softc *sc = vsc; + + if (msr != NULL) + *msr = sc->sc_msr; + if (lsr != NULL) + *lsr = sc->sc_lsr; +} + +void +uark_break(void *vsc, int portno, int onoff) +{ +#ifdef UARK_DEBUG + struct uark_softc *sc = vsc; + + printf("%s: break %s!\n", device_get_nameunit(sc->sc_dev), + onoff ? "on" : "off"); + + if (onoff) + /* break on */ + uark_cmd(sc, 4, 0x01); + else + uark_cmd(sc, 4, 0x00); +#endif +} + +int +uark_cmd(struct uark_softc *sc, uint16_t index, uint16_t value) +{ + usb_device_request_t req; + usbd_status err; + struct ucom_softc *ucom = &sc->sc_ucom; + + req.bmRequestType = UARK_WRITE; + req.bRequest = UARK_REQUEST; + USETW(req.wValue, value); + USETW(req.wIndex, index); + USETW(req.wLength, 0); + err = usbd_do_request(ucom->sc_udev, &req, NULL); + + if (err) + return (EIO); + + return (0); +} + +static device_method_t uark_methods[] = { + /* Device interface */ + DEVMETHOD(device_probe, uark_match), + DEVMETHOD(device_attach, uark_attach), + DEVMETHOD(device_detach, uark_detach), + + { 0, 0 } +}; + +static driver_t uark_driver = { + "ucom", + uark_methods, + sizeof (struct uark_softc) +}; + +DRIVER_MODULE(uark, uhub, uark_driver, ucom_devclass, usbd_driver_load, 0); +MODULE_DEPEND(uark, usb, 1, 1, 1); +MODULE_DEPEND(uark, ucom, UCOM_MINVER, UCOM_PREFVER, UCOM_MAXVER); diff --git a/sys/dev/usb/usbdevs b/sys/dev/usb/usbdevs index 4a42fae..16a261d 100644 --- a/sys/dev/usb/usbdevs +++ b/sys/dev/usb/usbdevs @@ -545,6 +545,7 @@ vendor AVERATEC 0x50c2 Averatec vendor ONSPEC2 0x55aa OnSpec vendor ZINWELL 0x5a57 Zinwell vendor SITECOM 0x6189 Sitecom +vendor ARKMICRO 0x6547 Arkmicro Technologies vendor INTEL 0x8086 Intel vendor HP2 0xf003 Hewlett Packard @@ -676,6 +677,9 @@ product APPLE IPOD_08 0x1208 iPod '08' product APPLE IPODVIDEO 0x1209 iPod Video product APPLE IPODNANO 0x120a iPod Nano +/* Arkmicro Technologies */ +product ARKMICRO ARK3116 0x0232 ARK3116 Serial + /* Asahi Optical products */ product ASAHIOPTICAL OPTIO230 0x0004 Digital camera product ASAHIOPTICAL OPTIO330 0x0006 Digital camera diff --git a/sys/modules/Makefile b/sys/modules/Makefile index 0af4960..5aa356b 100644 --- a/sys/modules/Makefile +++ b/sys/modules/Makefile @@ -247,6 +247,7 @@ SUBDIR= ${_3dfx} \ twe \ tx \ txp \ + uark \ uart \ ubsa \ ubsec \ diff --git a/sys/modules/uark/Makefile b/sys/modules/uark/Makefile new file mode 100644 index 0000000..703cc85 --- /dev/null +++ b/sys/modules/uark/Makefile @@ -0,0 +1,8 @@ +# $FreeBSD$ + +.PATH: ${.CURDIR}/../../dev/usb + +KMOD= uark +SRCS= uark.c opt_usb.h bus_if.h device_if.h usbdevs.h + +.include <bsd.kmod.mk> |