/* $Id: jfb.c,v 1.1.1.1 2008/03/04 16:09:01 nbrk Exp $ */ /* * Jornada framebuffer. * 640x240 @16bpp */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include "wsdisplay.h" #define JFB_DFLTWIDTH 640 #define JFB_DFLTHEIGHT 240 #define JFB_DFLTBPP 16 struct jfb_softc { struct device sc_dev; bus_space_tag_t sc_bust; bus_space_handle_t sc_bush; uint8_t *sc_bits; int sc_width; int sc_height; int sc_depth; int sc_linebytes; int sc_rows; int sc_cols; struct rasops_info sc_ri; struct wsscreen_descr sc_wsd; struct wsscreen_list sc_wsl; struct wsscreen_descr *sc_scrlist[1]; }; int jfb_match(struct device *parent, void *cf, void *aux); void jfb_attach(struct device *parent, struct device *self, void *aux); void jfbfakecnattach(bus_addr_t addr); void jfb_rasopsinit(struct jfb_softc *sc); void jfb_setcmap(struct rasops_info *ri); struct jfb_softc jfb_sc; int jfb_initted = 0; /* autoconf stuff */ struct cfattach jfb_ca = { sizeof(struct jfb_softc), jfb_match, jfb_attach, NULL, NULL }; struct cfdriver jfb_cd = { NULL, "jfb", DV_DULL }; int jfb_match(struct device *parent, void *cf, void *aux) { return(1); } void jfb_attach(struct device *parent, struct device *self, void *aux) { struct jfb_softc *sc = (void *)self; struct saip_attach_args *saa = aux; struct wsemuldisplaydev_attach_args waa; sc->sc_bust = saa->sai_iot; /* use bootstrap softc if it is already configured */ // if (jfb_initted) // *sc = jfb_sc; if (bus_space_map(sc->sc_bust, saa->sai_addr, JFB_SIZE , BUS_SPACE_MAP_LINEAR, &sc->sc_bush)) { printf(": can't map i/o space\n"); return; } sc->sc_bits = (uint8_t *)sc->sc_bush; /* TODO use flags for mode selection */ sc->sc_width = JFB_DFLTWIDTH; sc->sc_height = JFB_DFLTHEIGHT; sc->sc_depth = JFB_DFLTBPP; sc->sc_linebytes = sc->sc_width * (sc->sc_depth / 8); sc->sc_cols = 80; sc->sc_rows = 24; jfb_rasopsinit(sc); printf(": Jornada framebuffer (%dx%d @%dbpp)\n", sc->sc_width, sc->sc_height, sc->sc_depth); sc->sc_scrlist[0] = &sc->sc_wsd; sc->sc_wsl.nscreens = 1; sc->sc_wsl.screens = (const struct wsscreen_descr **)sc->sc_scrlist; waa.scrdata = &sc->sc_wsl; waa.accesscookie = sc; waa.defaultscreens = 0; config_found((struct device *)sc, &waa, wsemuldisplaydevprint); return; } void jfbfakecnattach(bus_addr_t addr) { struct jfb_softc *sc = &jfb_sc; sc->sc_bits = (uint8_t *)addr; if (jfb_initted == 0) { /* * First attachment. * Initialize with defaults. */ /* clear the screen */ sc->sc_ri.ri_flg = RI_CLEAR | RI_FULLCLEAR; sc->sc_width = JFB_DFLTWIDTH; sc->sc_height = JFB_DFLTHEIGHT; sc->sc_depth = JFB_DFLTBPP; sc->sc_linebytes = sc->sc_width * (sc->sc_depth / 8); sc->sc_cols = 80; sc->sc_rows = 24; /* set up rasops */ jfb_rasopsinit(sc); jfb_initted = 1; wsdisplay_cnattach(&sc->sc_wsd, &sc->sc_ri, 0, 0, 0); } else { /* * Already attached. * Tweak some settings and reconfigure rasops. */ /* reset ri_bits */ sc->sc_ri.ri_flg &= ~RI_CFGDONE; sc->sc_ri.ri_bits = sc->sc_bits; /* do not clear the screen */ sc->sc_ri.ri_flg &= ~RI_CLEAR; rasops_reconfig(&sc->sc_ri, 160, 160); } } void jfb_rasopsinit(struct jfb_softc *sc) { struct rasops_info *ri = &sc->sc_ri; struct wsscreen_descr *wsd = &sc->sc_wsd; extern struct wsdisplay_font vt220l8x10; ri->ri_hw = sc; ri->ri_bits = sc->sc_bits; /* claim minimal colour capabilities */ ri->ri_caps = WSSCREEN_WSCOLORS; ri->ri_depth = sc->sc_depth; ri->ri_width = sc->sc_width; ri->ri_height = sc->sc_height; ri->ri_stride = sc->sc_linebytes; /* FIXME: see how colors are packed in 16bits/pixel ? */ ri->ri_rnum = 5; ri->ri_gnum = 6; ri->ri_bnum = 5; ri->ri_rpos = 11; ri->ri_gpos = 5; ri->ri_bpos = 0; ri->ri_font = &vt220l8x10; /* XXX XXX please tell me why? */ /* rasops_init(ri, sc->sc_cols, sc->sc_rows); */ rasops_init(ri, 160, 160); /* tune colours */ jfb_setcmap(ri); /* initialize wsscreen_descr */ strlcpy(wsd->name, "std", sizeof(wsd->name)); wsd->ncols = sc->sc_cols; wsd->nrows = sc->sc_rows; wsd->capabilities = ri->ri_caps; wsd->textops = &ri->ri_ops; } void jfb_setcmap(struct rasops_info *ri) { /* more intensive white */ ri->ri_devcmap[WSCOL_WHITE] = 0xffff; }