diff options
author | Marcus Glocker <mglocker@cvs.openbsd.org> | 2009-05-09 19:23:08 +0000 |
---|---|---|
committer | Marcus Glocker <mglocker@cvs.openbsd.org> | 2009-05-09 19:23:08 +0000 |
commit | 12f3ea40e46deb8cb10e6c55ea6ad8d03dccdd85 (patch) | |
tree | 45bcb1bb48451b3d6c94686e0975928122e203ae /sys | |
parent | f887e7365a5d4a9e35498e5183fe4506316e3823 (diff) |
Initial console device driver for USB displays based on the DisplayLink
DL-120 / DL-160 graphic chips, using the wsdisplay(4) layer. Based on
the reversed engineered specifications of Florian Echtler. The driver
is disabled in GENERIC for now.
Thanks to claudio@ for donating me a device and to oga@ and miod@ for
giving me hints in the graphic and wsdisplay area.
OK deraadt
Diffstat (limited to 'sys')
-rw-r--r-- | sys/arch/amd64/conf/GENERIC | 5 | ||||
-rw-r--r-- | sys/arch/amd64/conf/files.amd64 | 5 | ||||
-rw-r--r-- | sys/dev/usb/files.usb | 6 | ||||
-rw-r--r-- | sys/dev/usb/udl.c | 1344 | ||||
-rw-r--r-- | sys/dev/usb/udl.h | 641 | ||||
-rw-r--r-- | sys/dev/wscons/wsconsio.h | 3 |
6 files changed, 2000 insertions, 4 deletions
diff --git a/sys/arch/amd64/conf/GENERIC b/sys/arch/amd64/conf/GENERIC index b883278c365..368c1ea0f55 100644 --- a/sys/arch/amd64/conf/GENERIC +++ b/sys/arch/amd64/conf/GENERIC @@ -1,4 +1,4 @@ -# $OpenBSD: GENERIC,v 1.262 2009/04/20 13:26:20 ariane Exp $ +# $OpenBSD: GENERIC,v 1.263 2009/05/09 19:23:07 mglocker Exp $ # # For further information on compiling OpenBSD kernels, see the config(8) # man page. @@ -237,6 +237,9 @@ onewire* at uow? uvideo* at uhub? video* at uvideo? +#udl* at uhub? +#wsdisplay* at udl? + puc* at pci? # PCI "universal" communication device #puc* at cardbus? diff --git a/sys/arch/amd64/conf/files.amd64 b/sys/arch/amd64/conf/files.amd64 index 3a83fb1b39b..b3b74da2334 100644 --- a/sys/arch/amd64/conf/files.amd64 +++ b/sys/arch/amd64/conf/files.amd64 @@ -1,4 +1,4 @@ -# $OpenBSD: files.amd64,v 1.47 2009/05/07 11:30:16 ariane Exp $ +# $OpenBSD: files.amd64,v 1.48 2009/05/09 19:23:07 mglocker Exp $ maxpartitions 16 maxusers 2 16 128 @@ -59,6 +59,9 @@ file arch/amd64/isa/clock.c file arch/amd64/amd64/powernow-k8.c !small_kernel file arch/amd64/amd64/est.c !small_kernel +include "dev/rasops/files.rasops" +include "dev/wsfont/files.wsfont" + include "dev/mii/files.mii" include "scsi/files.scsi" diff --git a/sys/dev/usb/files.usb b/sys/dev/usb/files.usb index faacdb428ff..8cfbe15ba49 100644 --- a/sys/dev/usb/files.usb +++ b/sys/dev/usb/files.usb @@ -1,4 +1,4 @@ -# $OpenBSD: files.usb,v 1.82 2009/03/23 21:53:57 damien Exp $ +# $OpenBSD: files.usb,v 1.83 2009/05/09 19:23:07 mglocker Exp $ # $NetBSD: files.usb,v 1.16 2000/02/14 20:29:54 augustss Exp $ # # Config file and device description for machine-independent USB code. @@ -39,6 +39,10 @@ device uvideo: video, firmload attach uvideo at uhub file dev/usb/uvideo.c uvideo +device udl: wsemuldisplaydev, rasops16 +attach udl at uhub +file dev/usb/udl.c udl + # MIDI devices device umidi: midibus attach umidi at uhub diff --git a/sys/dev/usb/udl.c b/sys/dev/usb/udl.c new file mode 100644 index 00000000000..696946981c9 --- /dev/null +++ b/sys/dev/usb/udl.c @@ -0,0 +1,1344 @@ +/* $OpenBSD: udl.c,v 1.1 2009/05/09 19:23:07 mglocker Exp $ */ + +/* + * Copyright (c) 2009 Marcus Glocker <mglocker@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. + */ + +/* + * Driver for the ``DisplayLink DL-120 / DL-160'' graphic chips based + * on the reversed engineered specifications of Florian Echtler + * <floe@butterbrot.org>: + * + * http://floe.butterbrot.org/displaylink/doku.php + * + * This driver has been inspired by the cfxga(4) driver because we have + * to deal with similar challenges, like no direct access to the video + * memory. + */ + +#include <sys/param.h> +#include <sys/device.h> +#include <sys/malloc.h> +#include <uvm/uvm.h> + +#include <machine/bus.h> + +#include <dev/usb/usb.h> +#include <dev/usb/usbdi.h> +#include <dev/usb/usbdi_util.h> +#include <dev/usb/usbdevs.h> + +#include <dev/wscons/wsconsio.h> +#include <dev/wscons/wsdisplayvar.h> +#include <dev/rasops/rasops.h> + +#include <dev/usb/udl.h> + +/* + * Defines. + */ +#if 0 +#define UDL_DEBUG +#endif +#ifdef UDL_DEBUG +int udl_debug = 1; +#define DPRINTF(l, x...) do { if ((l) <= udl_debug) printf(x); } while (0) +#else +#define DPRINTF(l, x...) +#endif + +#define DN(sc) ((sc)->sc_dev.dv_xname) +#define FUNC __func__ + +/* + * Prototypes. + */ +int udl_match(struct device *, void *, void *); +void udl_attach(struct device *, struct device *, void *); +int udl_detach(struct device *, int); +int udl_activate(struct device *, enum devact); + +int udl_ioctl(void *, u_long, caddr_t, int, struct proc *); +paddr_t udl_mmap(void *, off_t, int); +int udl_alloc_screen(void *, const struct wsscreen_descr *, + void **, int *, int *, long *); +void udl_free_screen(void *, void *); +int udl_show_screen(void *, void *, int, + void (*)(void *, int, int), void *); +void udl_burner(void *, u_int, u_int); + +void udl_copycols(void *, int, int, int, int); +void udl_copyrows(void *, int, int, int); +void udl_erasecols(void *, int, int, int, long); +void udl_eraserows(void *, int, int, long); +void udl_putchar(void *, int, int, u_int, long); +void udl_do_cursor(struct rasops_info *); + +usbd_status udl_ctrl_msg(struct udl_softc *, uint8_t, uint8_t, + uint16_t, uint16_t, uint8_t *, size_t); +usbd_status udl_poll(struct udl_softc *, uint32_t *); +usbd_status udl_read_1(struct udl_softc *, uint16_t, uint8_t *); +usbd_status udl_write_1(struct udl_softc *, uint16_t, uint8_t); +usbd_status udl_read_edid(struct udl_softc *, uint8_t *); +usbd_status udl_set_enc_key(struct udl_softc *, uint8_t *, uint8_t); +usbd_status udl_set_decomp_table(struct udl_softc *, uint8_t *, uint16_t); + +usbd_status udl_cmd_alloc_xfer(struct udl_softc *); +void udl_cmd_free_xfer(struct udl_softc *); +int udl_cmd_alloc_buf(struct udl_softc *); +void udl_cmd_free_buf(struct udl_softc *); +void udl_cmd_insert_int_1(struct udl_softc *, uint8_t); +void udl_cmd_insert_int_2(struct udl_softc *, uint16_t); +void udl_cmd_insert_int_3(struct udl_softc *, uint32_t); +void udl_cmd_insert_int_4(struct udl_softc *, uint32_t); +void udl_cmd_insert_buf(struct udl_softc *, uint8_t *, uint32_t); +void udl_cmd_insert_check(struct udl_cmd_buf *, int); +void udl_cmd_write_reg_1(struct udl_softc *, uint8_t, uint8_t); +void udl_cmd_write_reg_3(struct udl_softc *, uint8_t, uint32_t); +usbd_status udl_cmd_send(struct udl_softc *); +usbd_status udl_cmd_send_async(struct udl_softc *); +void udl_cmd_send_async_cb(usbd_xfer_handle, usbd_private_handle, + usbd_status); + +usbd_status udl_init_chip(struct udl_softc *); +void udl_init_fb_offsets(struct udl_softc *, uint32_t, uint32_t, + uint32_t, uint32_t); +usbd_status udl_init_resolution(struct udl_softc *, uint8_t *, uint8_t); +void udl_fb_off_write(struct udl_softc *, uint16_t, uint32_t, + uint8_t); +void udl_fb_pos_write(struct udl_softc *, uint16_t, uint32_t, + uint32_t, uint32_t); +void udl_fb_blk_write(struct udl_softc *, uint16_t, uint32_t, + uint32_t, uint32_t, uint32_t); +void udl_fb_off_copy(struct udl_softc *, uint32_t, uint32_t, + uint8_t); +void udl_fb_pos_copy(struct udl_softc *, uint32_t, uint32_t, + uint32_t, uint32_t, uint32_t); +void udl_fb_blk_copy(struct udl_softc *, uint32_t, uint32_t, + uint32_t, uint32_t, uint32_t, uint32_t); +void udl_draw_char(struct udl_softc *, uint32_t, uint32_t, + uint16_t, uint16_t, u_int); +#ifdef UDL_DEBUG +void udl_hexdump(void *, int, int); +usbd_status udl_init_test(struct udl_softc *); +#endif + +/* + * Driver glue. + */ +struct cfdriver udl_cd = { + NULL, "udl", DV_DULL +}; + +const struct cfattach udl_ca = { + sizeof(struct udl_softc), + udl_match, + udl_attach, + udl_detach, + udl_activate +}; + +/* + * wsdisplay glue. + */ +struct wsscreen_descr udl_stdscreen = { + "std", /* name */ + 0, 0, /* ncols, nrows */ + NULL, /* textops */ + 0, 0, /* fontwidth, fontheight */ + WSSCREEN_WSCOLORS /* capabilities */ +}; + +const struct wsscreen_descr *udl_scrlist[] = { + &udl_stdscreen +}; + +struct wsscreen_list udl_screenlist = { + sizeof(udl_scrlist) / sizeof(struct wsscreen_descr *), udl_scrlist +}; + +struct wsdisplay_accessops udl_accessops = { + udl_ioctl, + udl_mmap, + udl_alloc_screen, + udl_free_screen, + udl_show_screen, + NULL, + NULL, + NULL, + udl_burner +}; + +/* + * Matching devices. + */ +static const struct usb_devno udl_devs[] = { + { USB_VENDOR_DISPLAYLINK, USB_PRODUCT_DISPLAYLINK_DL120 } +}; + +int +udl_match(struct device *parent, void *match, void *aux) +{ + struct usb_attach_arg *uaa = aux; + + if (uaa->iface != NULL) + return (UMATCH_NONE); + + if (usb_lookup(udl_devs, uaa->vendor, uaa->product) != NULL) + return (UMATCH_VENDOR_PRODUCT); + + return (UMATCH_NONE); +} + +void +udl_attach(struct device *parent, struct device *self, void *aux) +{ + struct udl_softc *sc = (struct udl_softc *)self; + struct usb_attach_arg *uaa = aux; + struct wsemuldisplaydev_attach_args aa; + usbd_status error; + int err; + + sc->sc_udev = uaa->device; + + /* + * Set device configuration descriptor number. + */ + error = usbd_set_config_no(sc->sc_udev, 1, 0); + if (error != USBD_NORMAL_COMPLETION) + return; + + /* + * Create device handle to interface descriptor. + */ + error = usbd_device2interface_handle(sc->sc_udev, 0, &sc->sc_iface); + if (error != USBD_NORMAL_COMPLETION) + return; + + /* + * Allocate bulk command xfer. + */ + error = udl_cmd_alloc_xfer(sc); + if (error != USBD_NORMAL_COMPLETION) + return; + + /* + * Allocate command buffer. + */ + err = udl_cmd_alloc_buf(sc); + if (err != 0) + return; + + /* + * Open bulk TX pipe. + */ + error = usbd_open_pipe(sc->sc_iface, 0x01, USBD_EXCLUSIVE_USE, + &sc->sc_tx_pipeh); + if (error != USBD_NORMAL_COMPLETION) + return; + + /* + * Initialize chip. + */ + error = udl_init_chip(sc); + if (error != USBD_NORMAL_COMPLETION) + return; + + /* + * Initialize resolution. + */ + sc->sc_width = 800; /* XXX shouldn't we do this somewhere else? */ + sc->sc_height = 600; + sc->sc_depth = 16; + + error = udl_init_resolution(sc, udl_reg_vals_800, + sizeof(udl_reg_vals_800)); + if (error != USBD_NORMAL_COMPLETION) + return; + + /* + * Attach wsdisplay. + */ + aa.console = 0; + aa.scrdata = &udl_screenlist; + aa.accessops = &udl_accessops; + aa.accesscookie = sc; + aa.defaultscreens = 0; + + sc->sc_wsdisplay = config_found(self, &aa, wsemuldisplaydevprint); + + usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev, &sc->sc_dev); +} + +int +udl_detach(struct device *self, int flags) +{ + struct udl_softc *sc = (struct udl_softc *)self; + + /* + * Close bulk TX pipe. + */ + if (sc->sc_tx_pipeh != NULL) { + usbd_abort_pipe(sc->sc_tx_pipeh); + usbd_close_pipe(sc->sc_tx_pipeh); + } + + /* + * Free command buffer. + */ + udl_cmd_free_buf(sc); + + /* + * Free command xfer. + */ + udl_cmd_free_xfer(sc); + + /* + * Detach wsdisplay. + */ + if (sc->sc_wsdisplay != NULL) + config_detach(sc->sc_wsdisplay, DETACH_FORCE); + + usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev, &sc->sc_dev); + + return (0); +} + +int +udl_activate(struct device *self, enum devact act) +{ + switch (act) { + case DVACT_ACTIVATE: + return (EOPNOTSUPP); + case DVACT_DEACTIVATE: + break; + } + + return (0); +} + +/* ---------- */ + +int +udl_ioctl(void *v, u_long cmd, caddr_t data, int flag, struct proc *p) +{ + struct udl_softc *sc; + + sc = v; + + DPRINTF(1, "%s: %s\n", DN(sc), FUNC); + + /* TODO */ + switch (cmd) { + case WSDISPLAYIO_GTYPE: + *(u_int *)data = WSDISPLAY_TYPE_DL; + break; + default: + return (-1); + } + + return (0); +} + +paddr_t +udl_mmap(void *v, off_t off, int prot) +{ + struct udl_softc *sc; + + sc = v; + + DPRINTF(1, "%s: %s\n", DN(sc), FUNC); + + return (NULL); +} + +int +udl_alloc_screen(void *v, const struct wsscreen_descr *type, + void **cookiep, int *curxp, int *curyp, long *attrp) +{ + struct udl_softc *sc = v; + struct wsdisplay_font *font; + + DPRINTF(1, "%s: %s\n", DN(sc), FUNC); + + if (sc->sc_nscreens > 0) + return (ENOMEM); + + /* + * Initialize rasops. + */ + sc->sc_ri.ri_depth = sc->sc_depth; + sc->sc_ri.ri_bits = NULL; + sc->sc_ri.ri_width = sc->sc_width; + sc->sc_ri.ri_height = sc->sc_height; + sc->sc_ri.ri_stride = sc->sc_width * sc->sc_height / 8; + sc->sc_ri.ri_hw = (void *)sc; + sc->sc_ri.ri_flg = 0; + + /* swap B and R at 16 bpp */ + if (sc->sc_depth == 16) { + sc->sc_ri.ri_rnum = 5; + sc->sc_ri.ri_rpos = 11; + sc->sc_ri.ri_gnum = 6; + sc->sc_ri.ri_gpos = 5; + sc->sc_ri.ri_bnum = 5; + sc->sc_ri.ri_bpos = 0; + } + + rasops_init(&sc->sc_ri, 100, 100); + + sc->sc_ri.ri_ops.copycols = udl_copycols; + sc->sc_ri.ri_ops.copyrows = udl_copyrows; + sc->sc_ri.ri_ops.erasecols = udl_erasecols; + sc->sc_ri.ri_ops.eraserows = udl_eraserows; + sc->sc_ri.ri_ops.putchar = udl_putchar; + sc->sc_ri.ri_do_cursor = udl_do_cursor; + + sc->sc_ri.ri_ops.alloc_attr(&sc->sc_ri, 0, 0, 0, attrp); + + udl_stdscreen.nrows = sc->sc_ri.ri_rows; + udl_stdscreen.ncols = sc->sc_ri.ri_cols; + udl_stdscreen.textops = &sc->sc_ri.ri_ops; + udl_stdscreen.fontwidth = sc->sc_ri.ri_font->fontwidth; + udl_stdscreen.fontheight = sc->sc_ri.ri_font->fontheight; + udl_stdscreen.capabilities = sc->sc_ri.ri_caps; + + *cookiep = &sc->sc_ri; + *curxp = 0; + *curyp = 0; + + sc->sc_nscreens++; + + font = sc->sc_ri.ri_font; + DPRINTF(1, "%s: %s: using font %s (%dx%d)\n", + DN(sc), FUNC, font->name, sc->sc_ri.ri_cols, sc->sc_ri.ri_rows); + + return (0); +} + +void +udl_free_screen(void *v, void *cookie) +{ + struct udl_softc *sc; + + sc = v; + + DPRINTF(1, "%s: %s\n", DN(sc), FUNC); +} + +int +udl_show_screen(void *v, void *cookie, int waitok, + void (*cb)(void *, int, int), void *cbarg) +{ + struct udl_softc *sc; + + sc = v; + + DPRINTF(1, "%s: %s\n", DN(sc), FUNC); + + return (0); +} + +void +udl_burner(void *v, u_int on, u_int flags) +{ + struct udl_softc *sc; + + sc = v; + + DPRINTF(1, "%s: %s: %s\n", DN(sc), FUNC, on ? "on" : "off"); + + if (on) + udl_cmd_write_reg_1(sc, UDL_REG_BLANK_SCREEN, 0x01); + else + udl_cmd_write_reg_1(sc, UDL_REG_BLANK_SCREEN, 0x00); + + udl_cmd_write_reg_1(sc, UDL_REG_SYNC, 0xff); + + (void)udl_cmd_send(sc); +} + +/* ---------- */ + +void +udl_copycols(void *cookie, int row, int src, int dst, int num) +{ + struct rasops_info *ri = cookie; + struct udl_softc *sc; + int sx, sy, dx, dy, cx, cy; + + sc = ri->ri_hw; + + DPRINTF(2, "%s: %s: row=%d, src=%d, dst=%d, num=%d\n", + DN(sc), FUNC, row, src, dst, num); + + sx = src * ri->ri_font->fontwidth; + sy = row * ri->ri_font->fontheight; + dx = dst * ri->ri_font->fontwidth; + dy = row * ri->ri_font->fontheight; + cx = num * ri->ri_font->fontwidth; + cy = ri->ri_font->fontheight; + + udl_fb_blk_copy(sc, sx, sy, dx, dy, cx, cy); + + (void)udl_cmd_send_async(sc); +} + +void +udl_copyrows(void *cookie, int src, int dst, int num) +{ + struct rasops_info *ri = cookie; + struct udl_softc *sc; + int sy, dy, cx, cy; + + sc = ri->ri_hw; + + DPRINTF(2, "%s: %s: src=%d, dst=%d, num=%d\n", + DN(sc), FUNC, src, dst, num); + + sy = src * sc->sc_ri.ri_font->fontheight; + dy = dst * sc->sc_ri.ri_font->fontheight; + cx = sc->sc_ri.ri_emuwidth; + cy = num * sc->sc_ri.ri_font->fontheight; + + /* copy row block to off-screen first to fix overlay-copy problem */ + udl_fb_blk_copy(sc, 0, sy, 0, sc->sc_ri.ri_emuheight, cx, cy); + + /* copy row block back from off-screen now */ + udl_fb_blk_copy(sc, 0, sc->sc_ri.ri_emuheight, 0, dy, cx, cy); + + (void)udl_cmd_send_async(sc); +} + +void +udl_erasecols(void *cookie, int row, int col, int num, long attr) +{ + struct rasops_info *ri = cookie; + struct udl_softc *sc = ri->ri_hw; + int fg, bg; + int x, y, cx, cy; + + sc = ri->ri_hw; + + DPRINTF(2, "%s: %s: row=%d, col=%d, num=%d\n", + DN(sc), FUNC, row, col, num); + + sc->sc_ri.ri_ops.unpack_attr(cookie, attr, &fg, &bg, NULL); + + x = col * sc->sc_ri.ri_font->fontwidth; + y = row * sc->sc_ri.ri_font->fontheight; + cx = num * sc->sc_ri.ri_font->fontwidth; + cy = sc->sc_ri.ri_font->fontheight; + + udl_fb_blk_write(sc, 0x0000, x, y, cx, cy); + + (void)udl_cmd_send_async(sc); +} + +void +udl_eraserows(void *cookie, int row, int num, long attr) +{ + struct rasops_info *ri = cookie; + struct udl_softc *sc; + int x, y, cx, cy; + + sc = ri->ri_hw; + + DPRINTF(2, "%s: %s: row=%d, num=%d\n", DN(sc), FUNC, row, num); + + x = 0; + y = row * sc->sc_ri.ri_font->fontheight; + cx = sc->sc_ri.ri_emuwidth; + cy = num * sc->sc_ri.ri_font->fontheight; + + udl_fb_blk_write(sc, 0x0000, x, y, cx, cy); + + (void)udl_cmd_send_async(sc); +} + +void +udl_putchar(void *cookie, int row, int col, u_int uc, long attr) +{ + struct rasops_info *ri = cookie; + struct udl_softc *sc = ri->ri_hw; + uint16_t fgc, bgc; + uint32_t x, y, fg, bg; + + DPRINTF(2, "%s: %s\n", DN(sc), FUNC); + + sc->sc_ri.ri_ops.unpack_attr(cookie, attr, &fg, &bg, NULL); + fgc = (uint16_t)sc->sc_ri.ri_devcmap[fg]; + bgc = (uint16_t)sc->sc_ri.ri_devcmap[bg]; + + x = col * ri->ri_font->fontwidth; + y = row * ri->ri_font->fontheight; + + if (uc == ' ') { + /* + * Writting a block for the space character instead rendering + * it from font bits is more slim. + */ + udl_fb_blk_write(sc, bgc, x, y, + ri->ri_font->fontwidth, ri->ri_font->fontheight); + } else { + /* render a character from font bits */ + udl_draw_char(sc, x, y, fgc, bgc, uc); + } + + /* + * We don't call udl_cmd_send_async() here, since sending each + * character by itself gets the performance down bad. Instead the + * character will be buffered until another rasops function flush + * the buffer. + */ +} + +void +udl_do_cursor(struct rasops_info *ri) +{ + struct udl_softc *sc = ri->ri_hw; + uint32_t x, y; + + DPRINTF(2, "%s: %s: ccol=%d, crow=%d\n", + DN(sc), FUNC, ri->ri_ccol, ri->ri_crow); + + x = ri->ri_ccol * ri->ri_font->fontwidth; + y = ri->ri_crow * ri->ri_font->fontheight; + + if (sc->sc_cursor_on == 0) { + /* safe the last character block to off-screen */ + udl_fb_blk_copy(sc, x, y, 0, sc->sc_ri.ri_emuheight, + ri->ri_font->fontwidth, ri->ri_font->fontheight); + + /* draw cursor */ + udl_fb_blk_write(sc, 0xffff, x, y, + ri->ri_font->fontwidth, ri->ri_font->fontheight); + + sc->sc_cursor_on = 1; + } else { + /* restore the last safed character from off-screen */ + udl_fb_blk_copy(sc, 0, sc->sc_ri.ri_emuheight, x, y, + ri->ri_font->fontwidth, ri->ri_font->fontheight); + + sc->sc_cursor_on = 0; + } + + (void)udl_cmd_send_async(sc); +} + +/* ---------- */ + +usbd_status +udl_ctrl_msg(struct udl_softc *sc, uint8_t rt, uint8_t r, + uint16_t index, uint16_t value, uint8_t *buf, size_t len) +{ + usb_device_request_t req; + usbd_status error; + + req.bmRequestType = rt; + req.bRequest = r; + USETW(req.wIndex, index); + USETW(req.wValue, value); + USETW(req.wLength, len); + + error = usbd_do_request(sc->sc_udev, &req, buf); + if (error != USBD_NORMAL_COMPLETION) { + printf("%s: %s: %s!\n", DN(sc), FUNC, usbd_errstr(error)); + return (error); + } + + return (USBD_NORMAL_COMPLETION); +} + +usbd_status +udl_poll(struct udl_softc *sc, uint32_t *buf) +{ + uint8_t lbuf[4]; + usbd_status error; + + error = udl_ctrl_msg(sc, UT_READ_VENDOR_DEVICE, + UDL_CTRL_CMD_POLL, 0x0000, 0x0000, lbuf, 4); + if (error != USBD_NORMAL_COMPLETION) { + printf("%s: %s: %s!\n", DN(sc), FUNC, usbd_errstr(error)); + return (error); + } + *buf = *(uint32_t *)lbuf; + + return (USBD_NORMAL_COMPLETION); +} + +usbd_status +udl_read_1(struct udl_softc *sc, uint16_t addr, uint8_t *buf) +{ + uint8_t lbuf[1]; + usbd_status error; + + error = udl_ctrl_msg(sc, UT_READ_VENDOR_DEVICE, + UDL_CTRL_CMD_READ_1, addr, 0x0000, lbuf, 1); + if (error != USBD_NORMAL_COMPLETION) { + printf("%s: %s: %s!\n", DN(sc), FUNC, usbd_errstr(error)); + return (error); + } + *buf = *(uint8_t *)lbuf; + + return (USBD_NORMAL_COMPLETION); +} + +usbd_status +udl_write_1(struct udl_softc *sc, uint16_t addr, uint8_t buf) +{ + usbd_status error; + + error = udl_ctrl_msg(sc, UT_WRITE_VENDOR_DEVICE, + UDL_CTRL_CMD_WRITE_1, addr, 0x0000, &buf, 1); + if (error != USBD_NORMAL_COMPLETION) { + printf("%s: %s: %s!\n", DN(sc), FUNC, usbd_errstr(error)); + return (error); + } + + return (USBD_NORMAL_COMPLETION); +} + +usbd_status +udl_read_edid(struct udl_softc *sc, uint8_t *buf) +{ + uint8_t lbuf[64]; + uint16_t offset; + usbd_status error; + + offset = 0; + + error = udl_ctrl_msg(sc, UT_READ_VENDOR_DEVICE, + UDL_CTRL_CMD_READ_EDID, 0x00a1, (offset << 8), lbuf, 64); + if (error != USBD_NORMAL_COMPLETION) + goto fail; + bcopy(lbuf + 1, buf + offset, 63); + offset += 63; + + error = udl_ctrl_msg(sc, UT_READ_VENDOR_DEVICE, + UDL_CTRL_CMD_READ_EDID, 0x00a1, (offset << 8), lbuf, 64); + if (error != USBD_NORMAL_COMPLETION) + goto fail; + bcopy(lbuf + 1, buf + offset, 63); + offset += 63; + + error = udl_ctrl_msg(sc, UT_READ_VENDOR_DEVICE, + UDL_CTRL_CMD_READ_EDID, 0x00a1, (offset << 8), lbuf, 3); + if (error != USBD_NORMAL_COMPLETION) + goto fail; + bcopy(lbuf + 1, buf + offset, 2); + + return (USBD_NORMAL_COMPLETION); +fail: + printf("%s: %s: %s!\n", DN(sc), FUNC, usbd_errstr(error)); + return (error); +} + +usbd_status +udl_set_enc_key(struct udl_softc *sc, uint8_t *buf, uint8_t len) +{ + usbd_status error; + + error = udl_ctrl_msg(sc, UT_WRITE_VENDOR_DEVICE, + UDL_CTRL_CMD_SET_KEY, 0x0000, 0x0000, buf, len); + if (error != USBD_NORMAL_COMPLETION) { + printf("%s: %s: %s!\n", DN(sc), FUNC, usbd_errstr(error)); + return (error); + } + + return (USBD_NORMAL_COMPLETION); +} + +usbd_status +udl_set_decomp_table(struct udl_softc *sc, uint8_t *buf, uint16_t len) +{ + int err; + + udl_cmd_insert_int_1(sc, UDL_BULK_SOC); + udl_cmd_insert_int_1(sc, UDL_BULK_CMD_DECOMP); + udl_cmd_insert_int_4(sc, 0x263871cd); /* magic number */ + udl_cmd_insert_int_4(sc, 0x00000200); /* 512 byte chunks */ + udl_cmd_insert_buf(sc, buf, len); + + err = udl_cmd_send(sc); + if (err != 0) + return (USBD_INVAL); + + return (USBD_NORMAL_COMPLETION); +} + +/* ---------- */ + +usbd_status +udl_cmd_alloc_xfer(struct udl_softc *sc) +{ + int i; + + for (i = 0; i < UDL_CMD_XFER_COUNT; i++) { + struct udl_cmd_xfer *cx = &sc->sc_cmd_xfer[i]; + + cx->sc = sc; + + cx->xfer = usbd_alloc_xfer(sc->sc_udev); + if (cx->xfer == NULL) { + printf("%s: %s: can't allocate xfer handle!\n", + DN(sc), FUNC); + return (USBD_NOMEM); + } + + cx->buf = usbd_alloc_buffer(cx->xfer, UDL_CMD_MAX_XFER_SIZE); + if (cx->buf == NULL) { + printf("%s: %s: can't allocate xfer buffer!\n", + DN(sc), FUNC); + return (USBD_NOMEM); + } + } + + return (USBD_NORMAL_COMPLETION); +} + +void +udl_cmd_free_xfer(struct udl_softc *sc) +{ + int i; + + for (i = 0; i < UDL_CMD_XFER_COUNT; i++) { + struct udl_cmd_xfer *cx = &sc->sc_cmd_xfer[i]; + + if (cx->xfer != NULL) { + usbd_free_xfer(cx->xfer); + cx->xfer = NULL; + } + } +} + +int +udl_cmd_alloc_buf(struct udl_softc *sc) +{ + struct udl_cmd_buf *cb = &sc->sc_cmd_buf; + + cb->buf = malloc(UDL_CMD_MAX_XFER_SIZE, M_DEVBUF, 0); + if (cb->buf == NULL) { + printf("%s: %s: can't allocate buffer!\n", + DN(sc), FUNC); + return (ENOMEM); + } + cb->off = 0; + + return (0); +} + +void +udl_cmd_free_buf(struct udl_softc *sc) +{ + struct udl_cmd_buf *cb = &sc->sc_cmd_buf; + + free(cb->buf, M_DEVBUF); + cb->off = 0; +} + +void +udl_cmd_insert_int_1(struct udl_softc *sc, uint8_t value) +{ + struct udl_cmd_buf *cb = &sc->sc_cmd_buf; + + udl_cmd_insert_check(cb, 1); + + cb->buf[cb->off] = value; + + cb->off += 1; +} + +void +udl_cmd_insert_int_2(struct udl_softc *sc, uint16_t value) +{ + uint16_t lvalue; + struct udl_cmd_buf *cb = &sc->sc_cmd_buf; + + udl_cmd_insert_check(cb, 2); + + lvalue = htobe16(value); + bcopy(&lvalue, cb->buf + cb->off, 2); + + cb->off += 2; +} + +void +udl_cmd_insert_int_3(struct udl_softc *sc, uint32_t value) +{ + uint32_t lvalue; + struct udl_cmd_buf *cb = &sc->sc_cmd_buf; + + udl_cmd_insert_check(cb, 3); +#if BYTE_ORDER == BIG_ENDIAN + lvalue = htobe32(value) << 8; +#else + lvalue = htobe32(value) >> 8; +#endif + bcopy(&lvalue, cb->buf + cb->off, 3); + + cb->off += 3; +} + +void +udl_cmd_insert_int_4(struct udl_softc *sc, uint32_t value) +{ + uint32_t lvalue; + struct udl_cmd_buf *cb = &sc->sc_cmd_buf; + + udl_cmd_insert_check(cb, 4); + + lvalue = htobe32(value); + bcopy(&lvalue, cb->buf + cb->off, 4); + + cb->off += 4; +} + +void +udl_cmd_insert_buf(struct udl_softc *sc, uint8_t *buf, uint32_t len) +{ + struct udl_cmd_buf *cb = &sc->sc_cmd_buf; + + udl_cmd_insert_check(cb, len); + + bcopy(buf, cb->buf + cb->off, len); + + cb->off += len; +} + +void +udl_cmd_insert_check(struct udl_cmd_buf *cb, int len) +{ + int total; + + total = cb->off + len; + + if (total >= UDL_CMD_MAX_XFER_SIZE) { + /* XXX */ + panic("udl_cmd_insert_check: command buffer is full"); + } +} + +void +udl_cmd_write_reg_1(struct udl_softc *sc, uint8_t reg, uint8_t val) +{ + udl_cmd_insert_int_1(sc, UDL_BULK_SOC); + udl_cmd_insert_int_1(sc, UDL_BULK_CMD_REG_WRITE_1); + udl_cmd_insert_int_1(sc, reg); + udl_cmd_insert_int_1(sc, val); +} + +void +udl_cmd_write_reg_3(struct udl_softc *sc, uint8_t reg, uint32_t val) +{ + udl_cmd_write_reg_1(sc, reg + 0, (val >> 16) & 0xff); + udl_cmd_write_reg_1(sc, reg + 1, (val >> 8) & 0xff); + udl_cmd_write_reg_1(sc, reg + 2, (val >> 0) & 0xff); +} + +usbd_status +udl_cmd_send(struct udl_softc *sc) +{ + struct udl_cmd_buf *cb = &sc->sc_cmd_buf; + struct udl_cmd_xfer *cx = &sc->sc_cmd_xfer[0]; + int len; + usbd_status error; + + /* mark end of command stack */ + udl_cmd_insert_int_1(sc, UDL_BULK_SOC); + udl_cmd_insert_int_1(sc, UDL_BULK_CMD_EOC); + + bcopy(cb->buf, cx->buf, cb->off); + + len = cb->off; + error = usbd_bulk_transfer(cx->xfer, sc->sc_tx_pipeh, + USBD_NO_COPY | USBD_SHORT_XFER_OK, 1000, cx->buf, &len, + "udl_bulk_xmit"); + if (error != USBD_NORMAL_COMPLETION) { + printf("%s: %s: %s!\n", DN(sc), FUNC, usbd_errstr(error)); + /* we clear our buffer now to avoid growing out of bounds */ + goto fail; + } + DPRINTF(1, "%s: %s: sent %d of %d bytes\n", + DN(sc), FUNC, len, cb->off); +fail: + cb->off = 0; + + return (error); +} + +usbd_status +udl_cmd_send_async(struct udl_softc *sc) +{ + struct udl_cmd_buf *cb = &sc->sc_cmd_buf; + struct udl_cmd_xfer *cx; + usbd_status error; + int i, s; + + /* if the ring buffer is full, wait until it's flushed completely */ + if (sc->sc_cmd_xfer_cnt == UDL_CMD_XFER_COUNT) { + DPRINTF(1, "%s: %s: ring buffer full, wait until flushed\n", + DN(sc), FUNC); + /* + * XXX + * Yes, this is ugly. But since we can't tsleep() here, I + * have no better idea how we can delay rasops so it doesn't + * blow up our command buffer. + */ + while (sc->sc_cmd_xfer_cnt > 0) + delay(100); + } + + s = splusb(); /* no callbacks please until accounting is done */ + + /* find a free ring buffer */ + for (i = 0; i < UDL_CMD_XFER_COUNT; i++) { + if (sc->sc_cmd_xfer[i].busy == 0) + break; + } + if (i == UDL_CMD_XFER_COUNT) { + /* XXX this shouldn't happen */ + panic("udl_cmd_send_async: buffer full"); + } + cx = &sc->sc_cmd_xfer[i]; + + /* copy command buffer to xfer buffer */ + bcopy(cb->buf, cx->buf, cb->off); + + /* do xfer */ + usbd_setup_xfer(cx->xfer, sc->sc_tx_pipeh, cx, cx->buf, cb->off, + USBD_NO_COPY, 1000, udl_cmd_send_async_cb); + error = usbd_transfer(cx->xfer); + if (error != 0 && error != USBD_IN_PROGRESS) { + printf("%s: %s: %s!\n", DN(sc), FUNC, usbd_errstr(error)); + return (error); + } + DPRINTF(1, "%s: %s: sending %d bytes from buffer no. %d\n", + DN(sc), FUNC, cb->off, i); + + /* free command buffer, lock xfer buffer */ + cb->off = 0; + cx->busy = 1; + sc->sc_cmd_xfer_cnt++; + + splx(s); + + return (USBD_NORMAL_COMPLETION); +} + +void +udl_cmd_send_async_cb(usbd_xfer_handle xfer, usbd_private_handle priv, + usbd_status status) +{ + struct udl_cmd_xfer *cx = priv; + struct udl_softc *sc = cx->sc; + int len; + + if (status != USBD_NORMAL_COMPLETION) { + printf("%s: %s: %s!\n", DN(sc), FUNC, usbd_errstr(status)); + + if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) + return; + if (status == USBD_STALLED) + usbd_clear_endpoint_stall_async(sc->sc_tx_pipeh); + goto skip; + } + usbd_get_xfer_status(xfer, NULL, NULL, &len, NULL); + + DPRINTF(1, "%s: %s: sent %d bytes\n", DN(sc), FUNC, len); +skip: + /* free xfer buffer */ + cx->busy = 0; + sc->sc_cmd_xfer_cnt--; +} + +/* ---------- */ + +usbd_status +udl_init_chip(struct udl_softc *sc) +{ + uint8_t ui8; + uint32_t ui32; + int8_t edid[128]; + usbd_status error; + + error = udl_poll(sc, &ui32); + if (error != USBD_NORMAL_COMPLETION) + return (error); + DPRINTF(1, "%s: %s: poll=0x%08x\n", DN(sc), FUNC, ui32); + + error = udl_read_1(sc, 0xc484, &ui8); + if (error != USBD_NORMAL_COMPLETION) + return (error); + DPRINTF(1, "%s: %s: read 0x%02x from 0xc484\n", DN(sc), FUNC, ui8); + + error = udl_write_1(sc, 0xc41f, 0x01); + if (error != USBD_NORMAL_COMPLETION) + return (error); + DPRINTF(1, "%s: %s: write 0x01 to 0xc41f\n", DN(sc), FUNC); + + error = udl_read_edid(sc, edid); + if (error != USBD_NORMAL_COMPLETION) + return (error); + DPRINTF(1, "%s: %s: read EDID=\n", DN(sc), FUNC); +#ifdef UDL_DEBUG + udl_hexdump(edid, sizeof(edid), 0); +#endif + error = udl_set_enc_key(sc, udl_null_key_1, sizeof(udl_null_key_1)); + if (error != USBD_NORMAL_COMPLETION) + return (error); + DPRINTF(1, "%s: %s: set encryption key\n", DN(sc), FUNC); + + error = udl_write_1(sc, 0xc40b, 0x00); + if (error != USBD_NORMAL_COMPLETION) + return (error); + DPRINTF(1, "%s: %s: write 0x00 to 0xc40b\n", DN(sc), FUNC, ui8); + + error = udl_set_decomp_table(sc, udl_decomp_table, + sizeof(udl_decomp_table)); + if (error != USBD_NORMAL_COMPLETION) + return (error); + DPRINTF(1, "%s: %s: set decompression table\n", DN(sc), FUNC); + + return (USBD_NORMAL_COMPLETION); +} + +void +udl_init_fb_offsets(struct udl_softc *sc, uint32_t start16, uint32_t stride16, + uint32_t start8, uint32_t stride8) +{ + udl_cmd_write_reg_1(sc, UDL_REG_SYNC, 0x00); + udl_cmd_write_reg_3(sc, UDL_REG_ADDR_START16, start16); + udl_cmd_write_reg_3(sc, UDL_REG_ADDR_STRIDE16, stride16); + udl_cmd_write_reg_3(sc, UDL_REG_ADDR_START8, start8); + udl_cmd_write_reg_3(sc, UDL_REG_ADDR_STRIDE8, stride8); + udl_cmd_write_reg_1(sc, UDL_REG_SYNC, 0xff); +} + +usbd_status +udl_init_resolution(struct udl_softc *sc, uint8_t *buf, uint8_t len) +{ + int i; + usbd_status error; + + /* write resolution values and set video memory offsets */ + udl_cmd_write_reg_1(sc, UDL_REG_SYNC, 0x00); + for (i = 0; i < len; i++) + udl_cmd_write_reg_1(sc, i, buf[i]); + udl_cmd_write_reg_1(sc, UDL_REG_SYNC, 0xff); + + udl_init_fb_offsets(sc, 0x000000, 0x000a00, 0x555555, 0x000500); + error = udl_cmd_send(sc); + if (error != USBD_NORMAL_COMPLETION) + return (error); + + /* clear screen */ + udl_fb_blk_write(sc, 0x0000, 0, 0, sc->sc_width, sc->sc_height); + error = udl_cmd_send(sc); + if (error != USBD_NORMAL_COMPLETION) + return (error); + + /* show framebuffer content */ + udl_cmd_write_reg_1(sc, UDL_REG_BLANK_SCREEN, 0x00); + udl_cmd_write_reg_1(sc, UDL_REG_SYNC, 0xff); + error = udl_cmd_send(sc); + if (error != USBD_NORMAL_COMPLETION) + return (error); + + return (USBD_NORMAL_COMPLETION); +} + +void +udl_fb_off_write(struct udl_softc *sc, uint16_t rgb16, uint32_t off, + uint8_t width) +{ + uint8_t buf[UDL_CMD_MAX_DATA_SIZE]; + uint16_t lwidth, lrgb16; + uint32_t loff; + int i; + + loff = off * 2; + lwidth = width * 2; + + udl_cmd_insert_int_1(sc, UDL_BULK_SOC); + udl_cmd_insert_int_1(sc, UDL_BULK_CMD_FB_WRITE | UDL_BULK_CMD_FB_WORD); + udl_cmd_insert_int_3(sc, loff); + udl_cmd_insert_int_1(sc, width); + + for (i = 0; i < lwidth; i += 2) { + lrgb16 = htobe16(rgb16); + bcopy(&lrgb16, buf + i, 2); + } + + udl_cmd_insert_buf(sc, buf, lwidth); +} + +void +udl_fb_pos_write(struct udl_softc *sc, uint16_t rgb16, uint32_t x, + uint32_t y, uint32_t width) +{ + uint32_t off, block; + + off = (y * sc->sc_width) + x; + + while (width) { + if (width > UDL_CMD_MAX_PIXEL_COUNT) + block = UDL_CMD_MAX_PIXEL_COUNT; + else + block = width; + + udl_fb_off_write(sc, rgb16, off, block); + + off += block; + width -= block; + } +} + +void +udl_fb_blk_write(struct udl_softc *sc, uint16_t rgb16, uint32_t x, + uint32_t y, uint32_t width, uint32_t height) +{ + uint32_t i; + + for (i = 0; i < height; i++) + udl_fb_pos_write(sc, rgb16, x, y + i, width); +} + +void +udl_fb_off_copy(struct udl_softc *sc, uint32_t src_off, uint32_t dst_off, + uint8_t width) +{ + uint32_t ldst_off, lsrc_off; + + ldst_off = dst_off * 2; + lsrc_off = src_off * 2; + + udl_cmd_insert_int_1(sc, UDL_BULK_SOC); + udl_cmd_insert_int_1(sc, UDL_BULK_CMD_FB_COPY | UDL_BULK_CMD_FB_WORD); + udl_cmd_insert_int_3(sc, ldst_off); + udl_cmd_insert_int_1(sc, width); + udl_cmd_insert_int_3(sc, lsrc_off); +} + +void +udl_fb_pos_copy(struct udl_softc *sc, uint32_t src_x, uint32_t src_y, + uint32_t dst_x, uint32_t dst_y, uint32_t width) +{ + uint32_t src_off, dst_off, block; + + src_off = (src_y * sc->sc_width) + src_x; + dst_off = (dst_y * sc->sc_width) + dst_x; + + while (width) { + if (width > UDL_CMD_MAX_PIXEL_COUNT) + block = UDL_CMD_MAX_PIXEL_COUNT; + else + block = width; + + udl_fb_off_copy(sc, src_off, dst_off, block); + + src_off += block; + dst_off += block; + width -= block; + } +} + +void +udl_fb_blk_copy(struct udl_softc *sc, uint32_t src_x, uint32_t src_y, + uint32_t dst_x, uint32_t dst_y, uint32_t width, uint32_t height) +{ + int i; + + for (i = 0; i < height; i++) + udl_fb_pos_copy(sc, src_x, src_y + i, dst_x, dst_y + i, width); +} + +void +udl_draw_char(struct udl_softc *sc, uint32_t x, uint32_t y, + uint16_t fg, uint16_t bg, u_int uc) +{ + int i, j, lx, ly; + uint8_t *fontchar, fontbits, luc; + struct wsdisplay_font *font = sc->sc_ri.ri_font; + + /* draw the characters background first */ + udl_fb_blk_write(sc, bg, x, y, font->fontwidth, font->fontheight); + + fontchar = (uint8_t *)(font->data + (uc - font->firstchar) * + sc->sc_ri.ri_fontscale); + + lx = x; + ly = y; + for (i = 0; i < font->fontheight; i++) { + fontbits = *fontchar; + + for (j = 7; j != -1; j--) { + luc = 1 << j; + if (fontbits & luc) + udl_fb_pos_write(sc, fg, lx, ly, 1); + lx++; + } + lx = x; + ly++; + + fontchar += font->stride; + } +} + +/* ---------- */ +#ifdef UDL_DEBUG +void +udl_hexdump(void *buf, int len, int quiet) +{ + int i; + + for (i = 0; i < len; i++) { + if (quiet == 0) { + if (i % 16 == 0) + printf("%s%5i:", i ? "\n" : "", i); + if (i % 4 == 0) + printf(" "); + } + printf("%02x", (int)*((u_char *)buf + i)); + } + printf("\n"); +} + +usbd_status +udl_init_test(struct udl_softc *sc) +{ + int i, j, parts, loops; + uint16_t color; + uint16_t rgb24[3] = { 0xf800, 0x07e0, 0x001f }; + + loops = sc->sc_width * sc->sc_height / UDL_CMD_MAX_PIXEL_COUNT; + parts = loops / 3; + color = rgb24[0]; + + j = 1; + for (i = 0; i < loops; i++) { + if (i == parts) { + color = rgb24[j]; + parts += parts; + j++; + } + udl_fb_off_write(sc, color, i * UDL_CMD_MAX_PIXEL_COUNT, + UDL_CMD_MAX_PIXEL_COUNT); + } + (void)udl_cmd_send(sc); + + return (USBD_NORMAL_COMPLETION); +} +#endif diff --git a/sys/dev/usb/udl.h b/sys/dev/usb/udl.h new file mode 100644 index 00000000000..bda07c5c71a --- /dev/null +++ b/sys/dev/usb/udl.h @@ -0,0 +1,641 @@ +/* $OpenBSD: udl.h,v 1.1 2009/05/09 19:23:07 mglocker Exp $ */ + +/* + * Copyright (c) 2009 Marcus Glocker <mglocker@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. + */ + +/* + * Bulk command xfer structure. + */ +#define UDL_CMD_MAX_XFER_SIZE 1048576 +#define UDL_CMD_MAX_DATA_SIZE 256 +#define UDL_CMD_MAX_PIXEL_COUNT (UDL_CMD_MAX_DATA_SIZE / 2) + +struct udl_cmd_xfer { + struct udl_softc *sc; + usbd_xfer_handle xfer; + uint8_t busy; + uint8_t *buf; +}; + +struct udl_cmd_buf { + uint32_t off; + uint8_t *buf; +}; + +/* + * Our per device structure. + */ +struct udl_softc { + struct device sc_dev; + usbd_device_handle sc_udev; + usbd_interface_handle sc_iface; + usbd_pipe_handle sc_tx_pipeh; + + /* wsdisplay glue */ + struct device *sc_wsdisplay; + struct rasops_info sc_ri; + uint8_t sc_nscreens; + +#define UDL_CMD_XFER_COUNT 8 + int sc_cmd_xfer_cnt; + struct udl_cmd_xfer sc_cmd_xfer[UDL_CMD_XFER_COUNT]; + struct udl_cmd_buf sc_cmd_buf; + uint16_t sc_width; + uint16_t sc_height; + uint8_t sc_depth; + uint8_t sc_cursor_on; +}; + +/* + * Chip commands. + */ +#define UDL_CTRL_CMD_READ_EDID 0x02 +#define UDL_CTRL_CMD_WRITE_1 0x03 +#define UDL_CTRL_CMD_READ_1 0x04 +#define UDL_CTRL_CMD_POLL 0x06 +#define UDL_CTRL_CMD_SET_KEY 0x12 + +#define UDL_BULK_SOC 0xaf /* start of command token */ + +#define UDL_BULK_CMD_REG_WRITE_1 0x20 /* write 1 byte to register */ +#define UDL_BULK_CMD_EOC 0xa0 /* end of command stack */ +#define UDL_BULK_CMD_DECOMP 0xe0 /* send decompression table */ + +#define UDL_BULK_CMD_FB_BASE 0x60 +#define UDL_BULK_CMD_FB_WORD 0x08 +#define UDL_BULK_CMD_FB_WRITE (UDL_BULK_CMD_FB_BASE | 0x00) +#define UDL_BULK_CMD_FB_COPY (UDL_BULK_CMD_FB_BASE | 0x02) + +/* + * Chip registers. + */ +#define UDL_REG_ADDR_START16 0x20 +#define UDL_REG_ADDR_STRIDE16 0x23 +#define UDL_REG_ADDR_START8 0x26 +#define UDL_REG_ADDR_STRIDE8 0x29 + +#define UDL_REG_BLANK_SCREEN 0x1f +#define UDL_REG_SYNC 0xff + +/* + * Register values for screen resolution initialization. + */ +uint8_t udl_reg_vals_640[] = { + 0x00, 0x99, 0x30, 0x26, 0x94, 0x60, 0xa9, 0xce, 0x60, 0x07, 0xb3, 0x0f, + 0x79, 0xff, 0xff, 0x02, 0x80, 0x83, 0xbc, 0xff, 0xfc, 0xff, 0xff, 0x01, + 0xe0, 0x01, 0x02, 0xab, 0x13 +}; +uint8_t udl_reg_vals_800[] = { + 0x00, 0x20, 0x3c, 0x7a, 0xc9, 0x93, 0x60, 0xc8, 0xc7, 0x70, 0x53, 0xff, + 0xff, 0x21, 0x27, 0x03, 0x20, 0x91, 0x8f, 0xff, 0xff, 0xff, 0xf2, 0x02, + 0x58, 0x01, 0x02, 0x40, 0x1f +}; +uint8_t udl_reg_vals_1024[] = { + 0x00, 0x36, 0x18, 0xd5, 0x10, 0x60, 0xa9, 0x7b, 0x33, 0xa1, 0x2b, 0x27, + 0x32, 0xff, 0xff, 0x04, 0x00, 0xd9, 0x9a, 0xff, 0xca, 0xff, 0xff, 0x03, + 0x00, 0x04, 0x03, 0xc8, 0x32 +}; +uint8_t udl_reg_vals_1280[] = { + 0x00, 0x98, 0xf8, 0x0d, 0x57, 0x2a, 0x55, 0x4d, 0x54, 0xca, 0x0d, 0xff, + 0xff, 0x94, 0x43, 0x05, 0x00, 0x9a, 0xa8, 0xff, 0xff, 0xff, 0xf9, 0x04, + 0x00, 0x04, 0x02, 0x60, 0x54 +}; + +/* + * Encryption. + */ +uint8_t udl_null_key_1[] = { + 0x57, 0xcd, 0xdc, 0xa7, 0x1c, 0x88, 0x5e, 0x15, 0x60, 0xfe, 0xc6, 0x97, + 0x16, 0x3d, 0x47, 0xf2 +}; + +/* + * Compression. + */ +uint8_t udl_decomp_table[] = { + 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x01, 0x60, 0x01, 0x00, 0x00, 0x00, 0x61, + 0x00, 0x00, 0x00, 0x01, 0x23, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x01, 0x60, 0x05, 0x00, 0x00, 0x00, 0x61, + 0x00, 0x00, 0x00, 0x01, 0x67, 0x00, 0x01, 0x00, 0x01, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0x00, 0x00, 0x00, 0x01, 0x89, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x61, 0xab, 0x00, 0x00, 0x00, 0x61, + 0x00, 0x00, 0x00, 0x01, 0xcd, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x01, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x01, 0x60, 0x0f, 0x00, 0x00, 0x00, 0x61, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0x00, 0x00, 0x00, 0x02, 0x01, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x02, 0x01, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x01, 0x01, 0x22, 0x00, 0x00, 0x01, 0x02, + 0x00, 0x00, 0x00, 0x02, 0x33, 0x00, 0x01, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x02, 0x01, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x02, 0x44, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x02, 0x44, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x00, 0x01, 0x00, 0x05, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x02, 0x67, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x01, 0x00, 0x05, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x02, 0x67, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x02, 0x5b, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x01, 0x01, 0xc8, 0x00, 0x00, 0x01, 0x02, + 0x00, 0x00, 0x00, 0x02, 0x5b, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x02, 0x5b, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x02, 0x9a, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x02, 0x33, 0x00, 0x01, 0x00, 0x02, + 0x00, 0x00, 0x01, 0x01, 0x2b, 0x00, 0x00, 0x01, 0x02, + 0x00, 0x00, 0x00, 0x02, 0xcc, 0x00, 0x02, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x02, 0xdd, 0x00, 0x04, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x02, 0xef, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x03, 0x01, 0x00, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x00, 0x03, 0x23, 0x00, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x01, 0x01, 0xc4, 0x00, 0x00, 0x01, 0x03, + 0x00, 0x29, 0x01, 0x00, 0x05, 0x00, 0x00, 0x00, 0x03, + 0x00, 0xb7, 0x01, 0x00, 0x06, 0x00, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x00, 0x03, 0x78, 0x00, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x00, 0x03, 0x99, 0x00, 0x04, 0x00, 0x03, + 0x00, 0x00, 0x00, 0x03, 0xaa, 0x00, 0x08, 0x00, 0x03, + 0x00, 0x00, 0x00, 0x03, 0xbc, 0x00, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x00, 0x03, 0xde, 0x00, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x00, 0x03, 0xf0, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x04, 0x12, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x04, 0x34, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x04, 0x56, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x04, 0x78, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x04, 0x9a, 0x00, 0x00, 0x00, 0x04, + 0x00, 0xd7, 0x01, 0x00, 0x00, 0x00, 0x09, 0x01, 0x00, + 0x00, 0x00, 0x01, 0x01, 0x22, 0x00, 0x00, 0x02, 0x01, + 0x00, 0x00, 0x02, 0x04, 0xbb, 0x00, 0x00, 0x03, 0x04, + 0x00, 0x00, 0x00, 0x04, 0xcc, 0x00, 0x08, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x04, 0xdd, 0x00, 0x10, 0x00, 0x04, + 0x00, 0x20, 0x01, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x04, + 0x00, 0x00, 0x00, 0x04, 0xf0, 0x00, 0x00, 0x00, 0x05, + 0xff, 0xe0, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, + 0x00, 0x00, 0x00, 0x05, 0x23, 0x00, 0x00, 0x00, 0x05, + 0x08, 0x00, 0x01, 0x00, 0x00, 0x08, 0x20, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x05, 0x45, 0x00, 0x00, 0x00, 0x05, + 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x21, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x05, 0x67, 0x00, 0x00, 0x00, 0x05, + 0xf8, 0x00, 0x01, 0x00, 0x00, 0xf7, 0xe0, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x05, 0x89, 0x00, 0x00, 0x00, 0x05, + 0xff, 0xff, 0x01, 0x00, 0x00, 0xff, 0xdf, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x05, 0xab, 0x00, 0x00, 0x00, 0x05, + 0x00, 0x00, 0x01, 0x01, 0xcc, 0x00, 0x00, 0x02, 0x01, + 0x00, 0x00, 0x02, 0x05, 0xcc, 0x00, 0x00, 0x03, 0x05, + 0x00, 0x12, 0x01, 0x00, 0x00, 0x00, 0x32, 0x01, 0x00, + 0x00, 0xce, 0x01, 0x00, 0x00, 0x00, 0xae, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x05, 0xde, 0x00, 0x00, 0x00, 0x05, + 0x00, 0x00, 0x00, 0x05, 0xff, 0x00, 0x10, 0x00, 0x05, + 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x20, 0x00, 0x06, + 0x08, 0x41, 0x01, 0x00, 0x00, 0x08, 0x21, 0x01, 0x00, + 0x08, 0x61, 0x00, 0x06, 0x12, 0x00, 0x00, 0x00, 0x06, + 0x00, 0x00, 0x00, 0x06, 0x34, 0x00, 0x00, 0x00, 0x06, + 0xf7, 0xbf, 0x01, 0x00, 0x00, 0xf7, 0xdf, 0x01, 0x00, + 0xf7, 0x9f, 0x00, 0x06, 0x56, 0x00, 0x00, 0x00, 0x06, + 0x00, 0x00, 0x00, 0x06, 0x78, 0x00, 0x00, 0x00, 0x06, + 0x10, 0x61, 0x00, 0x06, 0x9a, 0x00, 0x00, 0x00, 0x06, + 0x00, 0x41, 0x00, 0x06, 0x9b, 0x00, 0x00, 0x00, 0x06, + 0x08, 0x62, 0x00, 0x06, 0x9c, 0x00, 0x00, 0x00, 0x06, + 0x08, 0x40, 0x00, 0x06, 0x9d, 0x00, 0x00, 0x00, 0x06, + 0xef, 0x9f, 0x00, 0x06, 0xef, 0x00, 0x00, 0x00, 0x06, + 0xff, 0xbf, 0x00, 0x06, 0xe0, 0x00, 0x00, 0x00, 0x07, + 0xf7, 0x9e, 0x00, 0x06, 0xe1, 0x00, 0x00, 0x00, 0x07, + 0xf7, 0xc0, 0x00, 0x06, 0xe2, 0x00, 0x00, 0x00, 0x07, + 0x00, 0x00, 0x00, 0x07, 0x34, 0x00, 0x00, 0x00, 0x07, + 0x00, 0x00, 0x01, 0x01, 0x22, 0x00, 0x00, 0x03, 0x01, + 0x00, 0x00, 0x04, 0x07, 0x55, 0x00, 0x00, 0x06, 0x07, + 0x00, 0x00, 0x00, 0x07, 0x66, 0x00, 0x20, 0x00, 0x07, + 0x00, 0x00, 0x00, 0x07, 0x77, 0x00, 0x40, 0x00, 0x07, + 0x00, 0x00, 0x00, 0x07, 0x88, 0x00, 0x20, 0x00, 0x07, + 0x08, 0x01, 0x01, 0x00, 0x09, 0x10, 0x02, 0x00, 0x07, + 0xef, 0xfe, 0x00, 0x07, 0xab, 0x00, 0x00, 0x00, 0x07, + 0x00, 0x00, 0x00, 0x07, 0xcf, 0xff, 0xff, 0xff, 0x7f, + 0x00, 0x00, 0x00, 0x07, 0xdd, 0xff, 0xe0, 0x00, 0x07, + 0xf7, 0xff, 0x01, 0x00, 0x0e, 0xef, 0xfe, 0x00, 0x07, + 0x10, 0x02, 0x00, 0x07, 0xf0, 0x00, 0x00, 0x00, 0x08, + 0x00, 0x00, 0x00, 0x08, 0x1f, 0xff, 0xff, 0xff, 0x7f, + 0x00, 0x00, 0x01, 0x00, 0x02, 0x08, 0x41, 0x00, 0x08, + 0x10, 0x41, 0x00, 0x06, 0x93, 0x00, 0x00, 0x00, 0x08, + 0x00, 0x00, 0x00, 0x08, 0x45, 0x00, 0x00, 0x00, 0x08, + 0x08, 0x42, 0x00, 0x06, 0x96, 0x00, 0x00, 0x00, 0x08, + 0x00, 0x00, 0x00, 0x08, 0x78, 0x00, 0x00, 0x00, 0x08, + 0x00, 0x00, 0x01, 0x00, 0x09, 0xf7, 0xbf, 0x00, 0x08, + 0xef, 0xbf, 0x00, 0x06, 0xea, 0x00, 0x00, 0x00, 0x08, + 0x00, 0x00, 0x00, 0x08, 0xbc, 0x00, 0x00, 0x00, 0x08, + 0xf7, 0xbe, 0x00, 0x06, 0xed, 0x00, 0x00, 0x00, 0x08, + 0x00, 0x00, 0x00, 0x08, 0xef, 0x00, 0x00, 0x00, 0x08, + 0x00, 0x00, 0x01, 0x01, 0xcc, 0x00, 0x00, 0x03, 0x01, + 0x00, 0x00, 0x04, 0x09, 0x00, 0x00, 0x00, 0x06, 0x09, + 0x00, 0x00, 0x00, 0x09, 0x12, 0x00, 0x00, 0x00, 0x09, + 0x00, 0x00, 0x00, 0x09, 0x33, 0x00, 0x40, 0x00, 0x09, + 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x80, 0x04, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x04, 0x08, 0x41, 0x00, 0x09, + 0x00, 0x00, 0x00, 0x09, 0x55, 0x08, 0x01, 0x00, 0x09, + 0x00, 0x00, 0x00, 0x09, 0x66, 0xf7, 0xff, 0x00, 0x09, + 0x10, 0x42, 0x00, 0x06, 0x99, 0x10, 0x62, 0x00, 0x06, + 0xf8, 0x1f, 0x00, 0x06, 0x99, 0x00, 0x40, 0x00, 0x06, + 0x00, 0x00, 0x01, 0x00, 0x07, 0xf7, 0xbf, 0x00, 0x09, + 0x00, 0x00, 0x00, 0x09, 0x88, 0xf7, 0xff, 0x00, 0x09, + 0x00, 0x00, 0x00, 0x09, 0x99, 0x08, 0x01, 0x00, 0x09, + 0xef, 0xbe, 0x00, 0x06, 0xee, 0xef, 0x9e, 0x00, 0x06, + 0x07, 0xe1, 0x00, 0x06, 0xee, 0xff, 0xc0, 0x00, 0x06, + 0x00, 0x00, 0x01, 0x00, 0x0a, 0x08, 0x41, 0x00, 0x09, + 0xf8, 0x20, 0x00, 0x06, 0x99, 0x07, 0xff, 0x00, 0x06, + 0x08, 0x1f, 0x00, 0x06, 0x9b, 0x00, 0x00, 0x00, 0x09, + 0x00, 0x00, 0x00, 0x09, 0xcd, 0x00, 0x00, 0x00, 0x09, + 0x00, 0x1f, 0x00, 0x06, 0x99, 0xf8, 0x01, 0x00, 0x06, + 0xf8, 0x21, 0x00, 0x06, 0x9e, 0x00, 0x00, 0x00, 0x09, + 0x00, 0x00, 0x00, 0x09, 0xf0, 0x00, 0x00, 0x00, 0x0a, + 0x00, 0x00, 0x01, 0x00, 0x01, 0xf7, 0xbf, 0x00, 0x0a, + 0x07, 0xe0, 0x00, 0x06, 0xee, 0xf8, 0x01, 0x00, 0x06, + 0xf7, 0xe1, 0x00, 0x06, 0xe2, 0x00, 0x00, 0x00, 0x0a, + 0x00, 0x00, 0x00, 0x0a, 0x34, 0x00, 0x00, 0x00, 0x0a, + 0xff, 0xe1, 0x00, 0x06, 0xee, 0x07, 0xff, 0x00, 0x06, + 0x07, 0xdf, 0x00, 0x06, 0xe5, 0x00, 0x00, 0x00, 0x0a, + 0x00, 0x00, 0x00, 0x0a, 0x67, 0x00, 0x00, 0x00, 0x0a, + 0x00, 0x00, 0x00, 0x0a, 0x89, 0x00, 0x00, 0x00, 0x0a, + 0x00, 0x00, 0x01, 0x01, 0x22, 0x00, 0x00, 0x05, 0x01, + 0x00, 0x00, 0x08, 0x0a, 0xaa, 0x00, 0x00, 0x0c, 0x0a, + 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x0a, 0xbb, 0x08, 0x41, 0x00, 0x0a, + 0x00, 0x00, 0x00, 0x0a, 0xcd, 0x10, 0x02, 0x00, 0x0a, + 0x00, 0x00, 0x00, 0x0a, 0xce, 0xef, 0xfe, 0x00, 0x0a, + 0x00, 0x00, 0x00, 0x0a, 0xff, 0xf7, 0xbf, 0x00, 0x0a, + 0x00, 0x00, 0x00, 0x0b, 0x01, 0xef, 0xfe, 0x00, 0x0b, + 0x00, 0x00, 0x00, 0x0b, 0x02, 0x10, 0x02, 0x00, 0x0b, + 0x00, 0x00, 0x01, 0x00, 0x03, 0x08, 0x41, 0x00, 0x0b, + 0x10, 0x21, 0x00, 0x06, 0x94, 0x00, 0x00, 0x00, 0x0b, + 0xef, 0xff, 0x00, 0x06, 0x95, 0x00, 0x00, 0x00, 0x0b, + 0x00, 0x00, 0x00, 0x0b, 0x66, 0x00, 0x20, 0x00, 0x0b, + 0x08, 0x22, 0x00, 0x06, 0x97, 0x00, 0x00, 0x00, 0x0b, + 0xf7, 0xfe, 0x00, 0x06, 0x98, 0x00, 0x00, 0x00, 0x0b, + 0x00, 0x00, 0x00, 0x0b, 0x99, 0x00, 0x20, 0x00, 0x0b, + 0x00, 0x00, 0x01, 0x00, 0x0a, 0xf7, 0xbf, 0x00, 0x0b, + 0xef, 0xdf, 0x00, 0x06, 0xeb, 0x00, 0x00, 0x00, 0x0b, + 0x10, 0x01, 0x00, 0x06, 0xec, 0x00, 0x00, 0x00, 0x0b, + 0x00, 0x00, 0x00, 0x0b, 0xdd, 0xff, 0xe0, 0x00, 0x0b, + 0xf7, 0xde, 0x00, 0x06, 0xee, 0x00, 0x00, 0x00, 0x0b, + 0x08, 0x02, 0x00, 0x06, 0xef, 0x00, 0x00, 0x00, 0x0b, + 0x00, 0x00, 0x00, 0x0c, 0x00, 0xff, 0xe0, 0x00, 0x0c, + 0x00, 0x00, 0x01, 0x01, 0xcc, 0x00, 0x00, 0x05, 0x01, + 0x00, 0x00, 0x08, 0x0c, 0x11, 0x00, 0x00, 0x0c, 0x0c, + 0x00, 0x00, 0x00, 0x0c, 0x23, 0x00, 0x00, 0x00, 0x0c, + 0x00, 0x00, 0x01, 0x00, 0x04, 0x10, 0x82, 0x00, 0x0c, + 0x00, 0x00, 0x00, 0x0c, 0x56, 0x00, 0x00, 0x00, 0x0c, + 0x00, 0x00, 0x00, 0x0c, 0x77, 0x10, 0x02, 0x00, 0x0c, + 0x00, 0x00, 0x00, 0x0c, 0x88, 0xef, 0xfe, 0x00, 0x0c, + 0x00, 0x00, 0x01, 0x00, 0x09, 0xef, 0x7e, 0x00, 0x0c, + 0x00, 0x00, 0x00, 0x0c, 0xab, 0x00, 0x00, 0x00, 0x0c, + 0x00, 0x00, 0x00, 0x0c, 0xcc, 0xef, 0xfe, 0x00, 0x0c, + 0x00, 0x00, 0x00, 0x0c, 0xdd, 0x10, 0x02, 0x00, 0x0c, + 0x00, 0x00, 0x01, 0x00, 0x0e, 0x08, 0x41, 0x00, 0x0c, + 0x10, 0x01, 0x00, 0x06, 0x99, 0xf0, 0x1f, 0x00, 0x06, + 0x10, 0x00, 0x00, 0x0a, 0xcc, 0xf0, 0x00, 0x00, 0x0a, + 0x00, 0x00, 0x00, 0x0c, 0xf0, 0x08, 0x41, 0x00, 0x0d, + 0x08, 0x02, 0x00, 0x06, 0x99, 0xf8, 0x1e, 0x00, 0x06, + 0x00, 0x02, 0x00, 0x0a, 0xcc, 0xff, 0xfe, 0x00, 0x0a, + 0x00, 0x00, 0x00, 0x0d, 0x12, 0x08, 0x41, 0x00, 0x0d, + 0x00, 0x00, 0x01, 0x00, 0x03, 0xf7, 0xbf, 0x00, 0x0d, + 0xef, 0xff, 0x00, 0x06, 0xee, 0x0f, 0xe1, 0x00, 0x06, + 0xf0, 0x00, 0x00, 0x0b, 0x00, 0x10, 0x00, 0x00, 0x0b, + 0x00, 0x00, 0x00, 0x0d, 0x45, 0xf7, 0xbf, 0x00, 0x0d, + 0xf7, 0xfe, 0x00, 0x06, 0xee, 0x07, 0xe2, 0x00, 0x06, + 0xff, 0xfe, 0x00, 0x0b, 0x00, 0x00, 0x02, 0x00, 0x0b, + 0x00, 0x00, 0x00, 0x0d, 0x67, 0xf7, 0xbf, 0x00, 0x0d, + 0x00, 0x00, 0x00, 0x0d, 0x89, 0x00, 0x00, 0x00, 0x0d, + 0x00, 0x00, 0x01, 0x01, 0x22, 0x00, 0x00, 0x09, 0x01, + 0x00, 0x00, 0x10, 0x0d, 0xaa, 0x00, 0x00, 0x18, 0x0d, + 0x00, 0x00, 0x00, 0x0d, 0xbb, 0x10, 0x82, 0x00, 0x0d, + 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x20, 0x01, 0x00, + 0x08, 0x41, 0x00, 0x09, 0x44, 0x08, 0x61, 0x00, 0x09, + 0x00, 0x00, 0x00, 0x0a, 0xcc, 0x20, 0x04, 0x00, 0x0d, + 0x00, 0x00, 0x00, 0x0a, 0xcd, 0xdf, 0xfc, 0x00, 0x0d, + 0x00, 0x00, 0x00, 0x0d, 0xee, 0xef, 0x7e, 0x00, 0x0d, + 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0xe0, 0x01, 0x00, + 0xf7, 0xbf, 0x00, 0x09, 0x77, 0xf7, 0x9f, 0x00, 0x09, + 0x00, 0x00, 0x00, 0x0b, 0x0f, 0xdf, 0xfc, 0x00, 0x0d, + 0x00, 0x00, 0x00, 0x0b, 0x00, 0x20, 0x04, 0x00, 0x0e, + 0x00, 0x00, 0x01, 0x00, 0x01, 0x08, 0x41, 0x00, 0x0e, + 0x00, 0x00, 0x00, 0x0e, 0x23, 0x00, 0x00, 0x00, 0x0e, + 0x00, 0x00, 0x00, 0x0e, 0x44, 0x08, 0x41, 0x00, 0x0e, + 0x00, 0x00, 0x00, 0x0e, 0x56, 0x00, 0x00, 0x00, 0x0e, + 0x00, 0x00, 0x00, 0x0e, 0x77, 0x08, 0x41, 0x00, 0x0e, + 0x00, 0x00, 0x01, 0x00, 0x08, 0xf7, 0xbf, 0x00, 0x0e, + 0x00, 0x00, 0x00, 0x0e, 0x9a, 0x00, 0x00, 0x00, 0x0e, + 0x00, 0x00, 0x00, 0x0e, 0xbb, 0xf7, 0xbf, 0x00, 0x0e, + 0x00, 0x00, 0x00, 0x0e, 0xcd, 0x00, 0x00, 0x00, 0x0e, + 0x00, 0x00, 0x00, 0x0e, 0xee, 0xf7, 0xbf, 0x00, 0x0e, + 0x00, 0x00, 0x01, 0x01, 0xcc, 0x00, 0x00, 0x09, 0x01, + 0x00, 0x00, 0x10, 0x0e, 0xff, 0x00, 0x00, 0x18, 0x0e, + 0x00, 0x00, 0x00, 0x0f, 0x01, 0x00, 0x00, 0x00, 0x0f, + 0x00, 0x00, 0x01, 0x00, 0x02, 0x21, 0x04, 0x00, 0x0f, + 0x00, 0x00, 0x00, 0x0a, 0xc3, 0x00, 0x00, 0x00, 0x0f, + 0x00, 0x00, 0x00, 0x0a, 0xc4, 0x00, 0x00, 0x00, 0x0f, + 0x00, 0x00, 0x01, 0x00, 0x05, 0xde, 0xfc, 0x00, 0x0f, + 0x00, 0x00, 0x00, 0x0b, 0x06, 0x00, 0x00, 0x00, 0x0f, + 0x00, 0x00, 0x00, 0x0b, 0x07, 0x00, 0x00, 0x00, 0x0f, + 0x00, 0x00, 0x01, 0x00, 0x08, 0x08, 0x41, 0x00, 0x0f, + 0x08, 0x00, 0x00, 0x0f, 0x9a, 0x0f, 0xff, 0x00, 0x0f, + 0xf8, 0x00, 0x00, 0x0f, 0xbc, 0xf0, 0x01, 0x00, 0x0f, + 0x00, 0x00, 0x00, 0x0c, 0xfd, 0x10, 0x82, 0x00, 0x0f, + 0x00, 0x01, 0x00, 0x0f, 0xec, 0xf8, 0x02, 0x00, 0x0f, + 0xff, 0xff, 0x00, 0x0f, 0xfa, 0x07, 0xfe, 0x00, 0x0f, + 0x00, 0x00, 0x00, 0x0d, 0x10, 0x10, 0x82, 0x00, 0x10, + 0x00, 0x00, 0x01, 0x00, 0x01, 0xf7, 0xbf, 0x00, 0x10, + 0xf8, 0x00, 0x00, 0x0f, 0xb2, 0xf0, 0x01, 0x00, 0x10, + 0x08, 0x00, 0x00, 0x0f, 0x93, 0x0f, 0xff, 0x00, 0x10, + 0x00, 0x00, 0x00, 0x0d, 0x44, 0xef, 0x7e, 0x00, 0x10, + 0xff, 0xff, 0x00, 0x0f, 0xf3, 0x07, 0xfe, 0x00, 0x10, + 0x00, 0x01, 0x00, 0x0f, 0xe2, 0xf8, 0x02, 0x00, 0x10, + 0x00, 0x00, 0x00, 0x0d, 0x65, 0xef, 0x7e, 0x00, 0x10, + 0x00, 0x00, 0x00, 0x10, 0x67, 0x00, 0x00, 0x00, 0x10, + 0x00, 0x00, 0x01, 0x01, 0x22, 0x00, 0x00, 0x11, 0x01, + 0x00, 0x00, 0x20, 0x10, 0x88, 0x00, 0x00, 0x30, 0x10, + 0x00, 0x00, 0x01, 0x00, 0x09, 0x00, 0x00, 0x00, 0x10, + 0x20, 0x04, 0x00, 0x0a, 0xcc, 0x40, 0x08, 0x00, 0x0a, + 0xdf, 0xfc, 0x00, 0x0a, 0xcc, 0xbf, 0xf8, 0x00, 0x0a, + 0x00, 0x00, 0x01, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x10, + 0xdf, 0xfc, 0x00, 0x0b, 0x00, 0xbf, 0xf8, 0x00, 0x0b, + 0x20, 0x04, 0x00, 0x0b, 0x00, 0x40, 0x08, 0x00, 0x0b, + 0x00, 0x00, 0x01, 0x00, 0x0b, 0x08, 0x41, 0x00, 0x10, + 0x00, 0x00, 0x00, 0x10, 0xcc, 0x08, 0x01, 0x00, 0x10, + 0x00, 0x00, 0x00, 0x10, 0xdd, 0x08, 0x00, 0x00, 0x10, + 0x00, 0x00, 0x00, 0x10, 0xee, 0xf7, 0xff, 0x00, 0x10, + 0x00, 0x00, 0x00, 0x10, 0xff, 0x00, 0x01, 0x00, 0x10, + 0x00, 0x00, 0x00, 0x11, 0x00, 0x10, 0x82, 0x00, 0x11, + 0x00, 0x00, 0x00, 0x11, 0x11, 0x08, 0x01, 0x00, 0x11, + 0x00, 0x00, 0x00, 0x11, 0x22, 0xf7, 0xff, 0x00, 0x11, + 0x00, 0x00, 0x00, 0x11, 0x33, 0x10, 0x82, 0x00, 0x11, + 0x00, 0x00, 0x01, 0x00, 0x04, 0xf7, 0xbf, 0x00, 0x11, + 0x00, 0x00, 0x00, 0x11, 0x55, 0xf8, 0x00, 0x00, 0x11, + 0x00, 0x00, 0x00, 0x11, 0x66, 0xff, 0xff, 0x00, 0x11, + 0x00, 0x00, 0x00, 0x11, 0x77, 0xef, 0x7e, 0x00, 0x11, + 0x00, 0x00, 0x00, 0x11, 0x88, 0xef, 0x7e, 0x00, 0x11, + 0x00, 0x00, 0x01, 0x01, 0xcc, 0x00, 0x00, 0x11, 0x01, + 0x00, 0x00, 0x20, 0x11, 0x99, 0x00, 0x00, 0x30, 0x11, + 0x00, 0x00, 0x00, 0x11, 0xab, 0x00, 0x00, 0x00, 0x11, + 0x21, 0x04, 0x01, 0x00, 0x00, 0x42, 0x08, 0x01, 0x00, + 0xde, 0xfc, 0x01, 0x00, 0x00, 0xbd, 0xf8, 0x01, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x0c, 0x08, 0x41, 0x00, 0x11, + 0x00, 0x00, 0x00, 0x11, 0xde, 0x10, 0x02, 0x00, 0x11, + 0x00, 0x00, 0x00, 0x11, 0xf0, 0x10, 0x00, 0x00, 0x12, + 0x00, 0x00, 0x00, 0x12, 0x12, 0xef, 0xfe, 0x00, 0x12, + 0x00, 0x00, 0x00, 0x12, 0x13, 0x00, 0x02, 0x00, 0x12, + 0x00, 0x00, 0x00, 0x0c, 0xf4, 0x21, 0x04, 0x00, 0x12, + 0x00, 0x00, 0x00, 0x12, 0x56, 0x10, 0x02, 0x00, 0x12, + 0x00, 0x00, 0x00, 0x11, 0xf7, 0xef, 0xfe, 0x00, 0x12, + 0x00, 0x00, 0x00, 0x0d, 0x18, 0x21, 0x04, 0x00, 0x12, + 0x00, 0x00, 0x01, 0x00, 0x09, 0xf7, 0xbf, 0x00, 0x12, + 0x00, 0x00, 0x00, 0x12, 0x5a, 0xf0, 0x00, 0x00, 0x12, + 0x00, 0x00, 0x00, 0x11, 0xdb, 0xff, 0xfe, 0x00, 0x12, + 0x00, 0x00, 0x00, 0x0d, 0x4c, 0xde, 0xfc, 0x00, 0x12, + 0x00, 0x00, 0x00, 0x0d, 0x6d, 0xde, 0xfc, 0x00, 0x12, + 0x00, 0x00, 0x00, 0x12, 0xef, 0x00, 0x00, 0x00, 0x12, + 0x00, 0x00, 0x01, 0x01, 0x22, 0x00, 0x00, 0x21, 0x01, + 0x00, 0x00, 0x40, 0x13, 0x00, 0x00, 0x00, 0x60, 0x13, + 0x00, 0x00, 0x01, 0x00, 0x01, 0x08, 0x41, 0x00, 0x13, + 0x00, 0x00, 0x00, 0x13, 0x22, 0x08, 0x00, 0x00, 0x13, + 0x00, 0x00, 0x00, 0x13, 0x33, 0x10, 0x02, 0x00, 0x13, + 0x00, 0x00, 0x00, 0x13, 0x44, 0xff, 0xff, 0x00, 0x13, + 0x00, 0x00, 0x00, 0x13, 0x55, 0x10, 0x00, 0x00, 0x13, + 0x00, 0x00, 0x00, 0x13, 0x66, 0xf8, 0x00, 0x00, 0x13, + 0x00, 0x00, 0x00, 0x13, 0x77, 0xef, 0xfe, 0x00, 0x13, + 0x00, 0x00, 0x00, 0x13, 0x88, 0x00, 0x02, 0x00, 0x13, + 0x00, 0x00, 0x00, 0x13, 0x99, 0x21, 0x04, 0x00, 0x13, + 0x00, 0x00, 0x00, 0x13, 0xaa, 0x00, 0x01, 0x00, 0x13, + 0x00, 0x00, 0x00, 0x13, 0xbb, 0x10, 0x02, 0x00, 0x13, + 0x00, 0x00, 0x00, 0x13, 0xcc, 0xef, 0xfe, 0x00, 0x13, + 0x00, 0x00, 0x00, 0x13, 0xdd, 0x21, 0x04, 0x00, 0x13, + 0x00, 0x00, 0x01, 0x00, 0x0e, 0xf7, 0xbf, 0x00, 0x13, + 0x00, 0x00, 0x00, 0x13, 0xff, 0xf0, 0x00, 0x00, 0x13, + 0x00, 0x00, 0x00, 0x14, 0x00, 0xff, 0xfe, 0x00, 0x14, + 0x00, 0x00, 0x00, 0x14, 0x11, 0xde, 0xfc, 0x00, 0x14, + 0x00, 0x00, 0x00, 0x14, 0x22, 0xde, 0xfc, 0x00, 0x14, + 0x00, 0x00, 0x01, 0x01, 0xcc, 0x00, 0x00, 0x21, 0x01, + 0x00, 0x00, 0x40, 0x14, 0x33, 0x00, 0x00, 0x60, 0x14, + 0x00, 0x00, 0x01, 0x01, 0x22, 0x00, 0x00, 0x41, 0x01, + 0x00, 0x00, 0x01, 0x00, 0x04, 0x08, 0x41, 0x00, 0x14, + 0x00, 0x00, 0x01, 0x00, 0x05, 0x10, 0x00, 0x00, 0x14, + 0x00, 0x00, 0x00, 0x11, 0xd6, 0x20, 0x04, 0x00, 0x14, + 0x00, 0x00, 0x01, 0x00, 0x07, 0xff, 0xfe, 0x00, 0x14, + 0x00, 0x00, 0x00, 0x11, 0xf8, 0x20, 0x00, 0x00, 0x14, + 0x00, 0x00, 0x01, 0x00, 0x09, 0xf0, 0x00, 0x00, 0x14, + 0x00, 0x00, 0x00, 0x12, 0x1a, 0xdf, 0xfc, 0x00, 0x14, + 0x00, 0x00, 0x00, 0x12, 0x1b, 0x00, 0x04, 0x00, 0x14, + 0x00, 0x00, 0x00, 0x0c, 0xfc, 0x42, 0x08, 0x00, 0x14, + 0x00, 0x00, 0x01, 0x00, 0x0d, 0x00, 0x02, 0x00, 0x14, + 0x00, 0x00, 0x00, 0x12, 0x5e, 0x20, 0x04, 0x00, 0x14, + 0x00, 0x00, 0x00, 0x11, 0xff, 0xdf, 0xfc, 0x00, 0x14, + 0x00, 0x00, 0x00, 0x0d, 0x10, 0x42, 0x08, 0x00, 0x15, + 0x00, 0x00, 0x01, 0x00, 0x01, 0xf7, 0xbf, 0x00, 0x15, + 0x00, 0x00, 0x00, 0x12, 0x52, 0xe0, 0x00, 0x00, 0x15, + 0x00, 0x00, 0x00, 0x11, 0xd3, 0xff, 0xfc, 0x00, 0x15, + 0x00, 0x00, 0x00, 0x0d, 0x44, 0xbd, 0xf8, 0x00, 0x15, + 0x00, 0x00, 0x00, 0x0d, 0x65, 0xbd, 0xf8, 0x00, 0x15, + 0x00, 0x00, 0x01, 0x01, 0xcc, 0x00, 0x00, 0x41, 0x01, + 0x00, 0x00, 0x01, 0x00, 0x06, 0x08, 0x41, 0x00, 0x15, + 0x00, 0x00, 0x00, 0x15, 0x77, 0x10, 0x00, 0x00, 0x15, + 0x00, 0x00, 0x00, 0x11, 0xd8, 0x00, 0x00, 0x00, 0x15, + 0x00, 0x00, 0x00, 0x15, 0x99, 0xff, 0xfe, 0x00, 0x15, + 0x00, 0x00, 0x00, 0x11, 0xfa, 0x00, 0x00, 0x00, 0x15, + 0x00, 0x00, 0x00, 0x15, 0xbb, 0xf0, 0x00, 0x00, 0x15, + 0x00, 0x00, 0x00, 0x12, 0x1c, 0x00, 0x00, 0x00, 0x15, + 0x00, 0x00, 0x00, 0x12, 0x1d, 0x00, 0x00, 0x00, 0x15, + 0x00, 0x00, 0x00, 0x0c, 0xfe, 0x00, 0x00, 0x00, 0x15, + 0x00, 0x00, 0x00, 0x15, 0xff, 0x00, 0x02, 0x00, 0x15, + 0x00, 0x00, 0x00, 0x12, 0x50, 0x00, 0x00, 0x00, 0x16, + 0x00, 0x00, 0x00, 0x11, 0xf1, 0x00, 0x00, 0x00, 0x16, + 0x00, 0x00, 0x00, 0x0d, 0x12, 0x00, 0x00, 0x00, 0x16, + 0x00, 0x00, 0x01, 0x00, 0x03, 0xf7, 0xbf, 0x00, 0x16, + 0x00, 0x00, 0x00, 0x12, 0x54, 0x00, 0x00, 0x00, 0x16, + 0x00, 0x00, 0x00, 0x11, 0xd5, 0x00, 0x00, 0x00, 0x16, + 0x00, 0x00, 0x00, 0x0d, 0x46, 0x00, 0x00, 0x00, 0x16, + 0x00, 0x00, 0x00, 0x0d, 0x67, 0x00, 0x00, 0x00, 0x16, + 0x00, 0x00, 0x01, 0x00, 0x08, 0x08, 0x41, 0x00, 0x16, + 0x00, 0x00, 0x01, 0x00, 0x09, 0x20, 0x00, 0x00, 0x16, + 0x20, 0x04, 0x00, 0x11, 0xdd, 0x40, 0x08, 0x00, 0x11, + 0x00, 0x00, 0x01, 0x00, 0x0a, 0xff, 0xfc, 0x00, 0x16, + 0x20, 0x00, 0x00, 0x11, 0xff, 0x40, 0x00, 0x00, 0x11, + 0x00, 0x00, 0x01, 0x00, 0x0b, 0xe0, 0x00, 0x00, 0x16, + 0xdf, 0xfc, 0x00, 0x12, 0x11, 0xbf, 0xf8, 0x00, 0x12, + 0x00, 0x04, 0x00, 0x12, 0x11, 0x00, 0x08, 0x00, 0x12, + 0x42, 0x08, 0x00, 0x0c, 0xff, 0x83, 0xf0, 0x00, 0x0c, + 0x00, 0x00, 0x01, 0x00, 0x0c, 0x00, 0x04, 0x00, 0x16, + 0x20, 0x04, 0x00, 0x12, 0x55, 0x40, 0x08, 0x00, 0x12, + 0xdf, 0xfc, 0x00, 0x11, 0xff, 0xbf, 0xf8, 0x00, 0x11, + 0x42, 0x08, 0x00, 0x0d, 0x11, 0x83, 0xf1, 0x00, 0x0d, + 0x00, 0x00, 0x01, 0x00, 0x0d, 0xf7, 0xbf, 0x00, 0x16, + 0xe0, 0x00, 0x00, 0x12, 0x55, 0xc0, 0x00, 0x00, 0x12, + 0xff, 0xfc, 0x00, 0x11, 0xdd, 0xff, 0xf8, 0x00, 0x11, + 0xbd, 0xf8, 0x00, 0x0d, 0x44, 0x7b, 0xf0, 0x00, 0x0d, + 0xbd, 0xf8, 0x00, 0x0d, 0x66, 0x74, 0x0f, 0x00, 0x0d, + 0x00, 0x00, 0x01, 0x00, 0x0e, 0x08, 0x41, 0x00, 0x16, + 0x00, 0x00, 0x01, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x16, + 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, + 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x17, + 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x17, + 0x00, 0x00, 0x01, 0x00, 0x03, 0xf7, 0xbf, 0x00, 0x17, + 0x00, 0x00, 0x01, 0x00, 0x04, 0x08, 0x41, 0x00, 0x17, + 0x20, 0x00, 0x01, 0x00, 0x00, 0x40, 0x00, 0x01, 0x00, + 0xff, 0xfc, 0x01, 0x00, 0x00, 0xff, 0xf8, 0x01, 0x00, + 0xe0, 0x00, 0x01, 0x00, 0x00, 0xc0, 0x00, 0x01, 0x00, + 0x00, 0x04, 0x01, 0x00, 0x00, 0x00, 0x08, 0x01, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x05, 0xf7, 0xbf, 0x00, 0x17, + 0x00, 0x00, 0x01, 0x00, 0x06, 0x08, 0x41, 0x00, 0x17, + 0x00, 0x00, 0x01, 0x00, 0x07, 0xf7, 0xbf, 0x00, 0x17, + 0x00, 0x00, 0x01, 0x00, 0x00, 0x08, 0x41, 0x01, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x00, 0xf7, 0xbf, 0x01, 0x00, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x7f +}; diff --git a/sys/dev/wscons/wsconsio.h b/sys/dev/wscons/wsconsio.h index e4ebe152ecd..1f7b473cbd8 100644 --- a/sys/dev/wscons/wsconsio.h +++ b/sys/dev/wscons/wsconsio.h @@ -1,4 +1,4 @@ -/* $OpenBSD: wsconsio.h,v 1.50 2009/03/12 19:10:22 kettenis Exp $ */ +/* $OpenBSD: wsconsio.h,v 1.51 2009/05/09 19:23:07 mglocker Exp $ */ /* $NetBSD: wsconsio.h,v 1.74 2005/04/28 07:15:44 martin Exp $ */ /* @@ -303,6 +303,7 @@ struct wsmouse_calibcoords { #define WSDISPLAY_TYPE_LEGSS 55 /* DEC LEGSS (VS35x0) */ #define WSDISPLAY_TYPE_IFB 56 /* Sun Expert3D{,-Lite} */ #define WSDISPLAY_TYPE_RAPTOR 57 /* Tech Source Raptor */ +#define WSDISPLAY_TYPE_DL 58 /* DisplayLink DL-120/DL-160 */ /* Basic display information. Not applicable to all display types. */ struct wsdisplay_fbinfo { |