summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/dev/usb/udl.c100
1 files changed, 75 insertions, 25 deletions
diff --git a/sys/dev/usb/udl.c b/sys/dev/usb/udl.c
index 14cdf577ee6..36651bc19b9 100644
--- a/sys/dev/usb/udl.c
+++ b/sys/dev/usb/udl.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: udl.c,v 1.63 2010/10/10 11:11:54 mglocker Exp $ */
+/* $OpenBSD: udl.c,v 1.64 2010/10/16 07:06:20 maja Exp $ */
/*
* Copyright (c) 2009 Marcus Glocker <mglocker@openbsd.org>
@@ -245,7 +245,7 @@ static const struct udl_type udl_devs[] = {
{ { USB_VENDOR_DISPLAYLINK, USB_PRODUCT_DISPLAYLINK_NL571 }, DL160 },
{ { USB_VENDOR_DISPLAYLINK, USB_PRODUCT_DISPLAYLINK_M01061 }, DL195 },
{ { USB_VENDOR_DISPLAYLINK, USB_PRODUCT_DISPLAYLINK_NBDOCK }, DL165 },
- { { USB_VENDOR_DISPLAYLINK, USB_PRODUCT_DISPLAYLINK_SWDVI }, DL160 },
+ { { USB_VENDOR_DISPLAYLINK, USB_PRODUCT_DISPLAYLINK_SWDVI }, DLUNK },
{ { USB_VENDOR_DISPLAYLINK, USB_PRODUCT_DISPLAYLINK_UM7X0 }, DL120 },
{ { USB_VENDOR_DISPLAYLINK, USB_PRODUCT_DISPLAYLINK_CONV }, DL160 },
{ { USB_VENDOR_DISPLAYLINK, USB_PRODUCT_DISPLAYLINK_LUM70 }, DL125 }
@@ -1290,32 +1290,67 @@ udl_select_chip(struct udl_softc *sc)
dd = usbd_get_device_descriptor(sc->sc_udev);
- bzero(serialnum, sizeof serialnum);
- error = usbd_get_string_desc(sc->sc_udev, dd->iSerialNumber,
- 0, &us, &len);
- if (error != USBD_NORMAL_COMPLETION)
- return (1);
-
- s = &serialnum[0];
- n = len / 2 - 1;
- for (i = 0; i < n && i < USB_MAX_STRING_LEN; i++) {
- c = UGETW(us.bString[i]);
- /* Convert from Unicode, handle buggy strings. */
- if ((c & 0xff00) == 0)
- *s++ = c;
- else if ((c & 0x00ff) == 0)
- *s++ = c >> 8;
- else
- *s++ = '?';
+ if ((UGETW(dd->idVendor) == USB_VENDOR_DISPLAYLINK) &&
+ (UGETW(dd->idProduct) == USB_PRODUCT_DISPLAYLINK_WSDVI)) {
+
+ /*
+ * WS Tech DVI is DL120 or DL160. All deviced uses the
+ * same revision (0.04) so iSerialNumber must be used
+ * to determin which chip it is.
+ */
+
+ bzero(serialnum, sizeof serialnum);
+ error = usbd_get_string_desc(sc->sc_udev, dd->iSerialNumber,
+ 0, &us, &len);
+ if (error != USBD_NORMAL_COMPLETION)
+ return (1);
+
+ s = &serialnum[0];
+ n = len / 2 - 1;
+ for (i = 0; i < n && i < USB_MAX_STRING_LEN; i++) {
+ c = UGETW(us.bString[i]);
+ /* Convert from Unicode, handle buggy strings. */
+ if ((c & 0xff00) == 0)
+ *s++ = c;
+ else if ((c & 0x00ff) == 0)
+ *s++ = c >> 8;
+ else
+ *s++ = '?';
+ }
+ *s++ = 0;
+
+ if (strlen(serialnum) > 7)
+ if (strncmp(serialnum, "0198-13", 7) == 0)
+ sc->sc_chip = DL160;
+
+ DPRINTF(1, "%s: %s: iSerialNumber (%s) used to select chip (%d)\n",
+ DN(sc), FUNC, serialnum, sc->sc_chip);
+
}
- *s++ = 0;
- if (strlen(serialnum) > 7)
- if (strncmp(serialnum, "0198-13", 7) == 0)
- sc->sc_chip = DL160;
+ if ((UGETW(dd->idVendor) == USB_VENDOR_DISPLAYLINK) &&
+ (UGETW(dd->idProduct) == USB_PRODUCT_DISPLAYLINK_SWDVI)) {
- DPRINTF(1, "%s: %s: iSerialNumber (%s) used to select chip (%d)\n",
- DN(sc), FUNC, serialnum, sc->sc_chip);
+ /*
+ * SUNWEIT DVI is DL160, DL125, DL165 or DL195. Major revision
+ * can be used to differ between DL1x0 and DL1x5. Minor to
+ * differ between DL1x5. iSerialNumber seems not to be uniqe.
+ */
+
+ sc->sc_chip = DL160;
+
+ if (UGETW(dd->bcdDevice) >= 0x100) {
+ sc->sc_chip = DL165;
+ if (UGETW(dd->bcdDevice) == 0x104)
+ sc->sc_chip = DL195;
+ if (UGETW(dd->bcdDevice) == 0x108)
+ sc->sc_chip = DL125;
+ }
+
+ DPRINTF(1, "%s: %s: bcdDevice (%02x) used to select chip (%d)\n",
+ DN(sc), FUNC, UGETW(dd->bcdDevice), sc->sc_chip);
+
+ }
return (0);
}
@@ -1866,6 +1901,21 @@ udl_init_chip(struct udl_softc *sc)
return (error);
DPRINTF(1, "%s: %s: poll=0x%08x\n", DN(sc), FUNC, ui32);
+ /* Some products may use later chip too */
+ switch (ui32 & 0xff) {
+ case 0xf1: /* DL1x5 */
+ switch (sc->sc_chip) {
+ case DL120:
+ sc->sc_chip = DL125;
+ break;
+ case DL160:
+ sc->sc_chip = DL165;
+ break;
+ }
+ break;
+ }
+ DPRINTF(1, "%s: %s: chip %d\n", DN(sc), FUNC, sc->sc_chip);
+
error = udl_read_1(sc, 0xc484, &ui8);
if (error != USBD_NORMAL_COMPLETION)
return (error);