diff options
author | Mats O Jansson <maja@cvs.openbsd.org> | 2010-10-16 07:06:21 +0000 |
---|---|---|
committer | Mats O Jansson <maja@cvs.openbsd.org> | 2010-10-16 07:06:21 +0000 |
commit | 74714b25c74598a0d799f5db5ac2399a8eff8fca (patch) | |
tree | 817049aa4358e5bd9486772698f4132c82090cb9 /sys/dev/usb/udl.c | |
parent | b5610462eb71565c57a32f69f8cd3f204fcbcd25 (diff) |
SUNWEIT DVI can be just about any chipset. Use the revision to select which.
Some other products use more than one generation of chipset. e.g. both
DL160 and DL165. Change to a later chipset if the family is newer than
expected. ok mglocker@ -moj
Diffstat (limited to 'sys/dev/usb/udl.c')
-rw-r--r-- | sys/dev/usb/udl.c | 100 |
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); |