📄 retz3fb.c
字号:
static void do_install_cmap(int con, struct fb_info *info){ struct retz3_fb_info *zinfo = retz3info(info); if (con != zinfo->currcon) return; if (fb_display[con].cmap.len) fb_set_cmap(&fb_display[con].cmap, 1, retz3_setcolreg, info); else fb_set_cmap(fb_default_cmap(1<<fb_display[con].var.bits_per_pixel), 1, retz3_setcolreg, info);}/* * Get the Fixed Part of the Display */static int retz3fb_get_fix(struct fb_fix_screeninfo *fix, int con, struct fb_info *info){ struct retz3fb_par par; int error = 0; if (con == -1) retz3fb_get_par(info, &par); else error = retz3_decode_var(&fb_display[con].var, &par); return(error ? error : retz3_encode_fix(info, fix, &par));}/* * Get the User Defined Part of the Display */static int retz3fb_get_var(struct fb_var_screeninfo *var, int con, struct fb_info *info){ struct retz3fb_par par; int error = 0; if (con == -1) { retz3fb_get_par(info, &par); error = retz3_encode_var(var, &par); } else *var = fb_display[con].var; return error;}static void retz3fb_set_disp(int con, struct fb_info *info){ struct fb_fix_screeninfo fix; struct display *display; struct retz3_fb_info *zinfo = retz3info(info); if (con >= 0) display = &fb_display[con]; else display = &zinfo->disp; /* used during initialization */ retz3fb_get_fix(&fix, con, info); if (con == -1) con = 0; display->screen_base = zinfo->fbmem; display->visual = fix.visual; display->type = fix.type; display->type_aux = fix.type_aux; display->ypanstep = fix.ypanstep; display->ywrapstep = fix.ywrapstep; display->can_soft_blank = 1; display->inverse = z3fb_inverse; /* * This seems to be about 20% faster. */ display->scrollmode = SCROLL_YREDRAW; switch (display->var.bits_per_pixel) {#ifdef FBCON_HAS_CFB8 case 8: if (display->var.accel_flags & FB_ACCELF_TEXT) { display->dispsw = &fbcon_retz3_8; retz3_set_video(info, &display->var, &zinfo->current_par); } else display->dispsw = &fbcon_cfb8; break;#endif#ifdef FBCON_HAS_CFB16 case 16: display->dispsw = &fbcon_cfb16; break;#endif default: display->dispsw = &fbcon_dummy; break; }}/* * Set the User Defined Part of the Display */static int retz3fb_set_var(struct fb_var_screeninfo *var, int con, struct fb_info *info){ int err, oldxres, oldyres, oldvxres, oldvyres, oldbpp, oldaccel; struct display *display; struct retz3_fb_info *zinfo = retz3info(info); if (con >= 0) display = &fb_display[con]; else display = &zinfo->disp; /* used during initialization */ if ((err = do_fb_set_var(info, var, con == zinfo->currcon))) return err; if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) { oldxres = display->var.xres; oldyres = display->var.yres; oldvxres = display->var.xres_virtual; oldvyres = display->var.yres_virtual; oldbpp = display->var.bits_per_pixel; oldaccel = display->var.accel_flags; display->var = *var; if (oldxres != var->xres || oldyres != var->yres || oldvxres != var->xres_virtual || oldvyres != var->yres_virtual || oldbpp != var->bits_per_pixel || oldaccel != var->accel_flags) { struct fb_fix_screeninfo fix; retz3fb_get_fix(&fix, con, info); display->screen_base = zinfo->fbmem; display->visual = fix.visual; display->type = fix.type; display->type_aux = fix.type_aux; display->ypanstep = fix.ypanstep; display->ywrapstep = fix.ywrapstep; display->line_length = fix.line_length; display->can_soft_blank = 1; display->inverse = z3fb_inverse; switch (display->var.bits_per_pixel) {#ifdef FBCON_HAS_CFB8 case 8: if (var->accel_flags & FB_ACCELF_TEXT) { display->dispsw = &fbcon_retz3_8; } else display->dispsw = &fbcon_cfb8; break;#endif#ifdef FBCON_HAS_CFB16 case 16: display->dispsw = &fbcon_cfb16; break;#endif default: display->dispsw = &fbcon_dummy; break; } /* * We still need to find a way to tell the X * server that the video mem has been fiddled with * so it redraws the entire screen when switching * between X and a text console. */ retz3_set_video(info, var, &zinfo->current_par); if (info->changevar) (*info->changevar)(con); } if (oldbpp != var->bits_per_pixel) { if ((err = fb_alloc_cmap(&display->cmap, 0, 0))) return err; do_install_cmap(con, info); } } return 0;}/* * Get the Colormap */static int retz3fb_get_cmap(struct fb_cmap *cmap, int kspc, int con, struct fb_info *info){ struct retz3_fb_info *zinfo = retz3info(info); if (con == zinfo->currcon) /* current console? */ return(fb_get_cmap(cmap, kspc, retz3_getcolreg, info)); else if (fb_display[con].cmap.len) /* non default colormap? */ fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2); else fb_copy_cmap(fb_default_cmap(1<<fb_display[con].var.bits_per_pixel), cmap, kspc ? 0 : 2); return 0;}/* * Set the Colormap */static int retz3fb_set_cmap(struct fb_cmap *cmap, int kspc, int con, struct fb_info *info){ int err; struct retz3_fb_info *zinfo = retz3info(info); if (!fb_display[con].cmap.len) { /* no colormap allocated? */ if ((err = fb_alloc_cmap(&fb_display[con].cmap, 1<<fb_display[con].var.bits_per_pixel, 0))) return err; } if (con == zinfo->currcon) /* current console? */ return(fb_set_cmap(cmap, kspc, retz3_setcolreg, info)); else fb_copy_cmap(cmap, &fb_display[con].cmap, kspc ? 0 : 1); return 0;}static struct fb_ops retz3fb_ops = { owner: THIS_MODULE, fb_get_fix: retz3fb_get_fix, fb_get_var: retz3fb_get_var, fb_set_var: retz3fb_set_var, fb_get_cmap: retz3fb_get_cmap, fb_set_cmap: retz3fb_set_cmap,};int __init retz3fb_setup(char *options){ char *this_opt; if (!options || !*options) return 0; while ((this_opt = strsep(&options, ",")) != NULL) { if (!*this_opt) continue; if (!strcmp(this_opt, "inverse")) { z3fb_inverse = 1; fb_invert_cmaps(); } else if (!strncmp(this_opt, "font:", 5)) { strncpy(fontname, this_opt+5, 39); fontname[39] = '\0'; } else z3fb_mode = get_video_mode(this_opt); } return 0;}/* * Initialization */int __init retz3fb_init(void){ unsigned long board_addr, board_size; struct zorro_dev *z = NULL; volatile unsigned char *regs; struct retz3fb_par par; struct retz3_fb_info *zinfo; struct fb_info *fb_info; short i; int res = -ENXIO; while ((z = zorro_find_device(ZORRO_PROD_MACROSYSTEMS_RETINA_Z3, z))) { board_addr = z->resource.start; board_size = z->resource.end-z->resource.start+1; if (!request_mem_region(board_addr, 0x0c00000, "ncr77c32blt")) { continue; if (!request_mem_region(board_addr+VIDEO_MEM_OFFSET, 0x00400000, "RAM")) release_mem_region(board_addr, 0x00c00000); continue; } if (!(zinfo = kmalloc(sizeof(struct retz3_fb_info), GFP_KERNEL))) return -ENOMEM; memset(zinfo, 0, sizeof(struct retz3_fb_info)); zinfo->base = ioremap(board_addr, board_size); zinfo->regs = zinfo->base; zinfo->fbmem = zinfo->base + VIDEO_MEM_OFFSET; /* Get memory size - for now we asume its a 4MB board */ zinfo->fbsize = 0x00400000; /* 4 MB */ zinfo->physregs = board_addr; zinfo->physfbmem = board_addr + VIDEO_MEM_OFFSET; fb_info = fbinfo(zinfo); for (i = 0; i < 256; i++){ for (i = 0; i < 256; i++){ zinfo->color_table[i][0] = i; zinfo->color_table[i][1] = i; zinfo->color_table[i][2] = i; } } regs = zinfo->regs; /* Disable hardware cursor */ seq_w(regs, SEQ_CURSOR_Y_INDEX, 0x00); retz3_setcolreg (255, 56<<8, 100<<8, 160<<8, 0, fb_info); retz3_setcolreg (254, 0, 0, 0, 0, fb_info); strcpy(fb_info->modename, retz3fb_name); fb_info->changevar = NULL; fb_info->node = -1; fb_info->fbops = &retz3fb_ops; fb_info->disp = &zinfo->disp; fb_info->switch_con = &z3fb_switch; fb_info->updatevar = &z3fb_updatevar; fb_info->blank = &z3fb_blank; fb_info->flags = FBINFO_FLAG_DEFAULT; strncpy(fb_info->fontname, fontname, 40); if (z3fb_mode == -1) retz3fb_default = retz3fb_predefined[0].var; retz3_decode_var(&retz3fb_default, &par); retz3_encode_var(&retz3fb_default, &par); do_fb_set_var(fb_info, &retz3fb_default, 0); retz3fb_get_var(&zinfo->disp.var, -1, fb_info); retz3fb_set_disp(-1, fb_info); do_install_cmap(0, fb_info); if (register_framebuffer(fb_info) < 0) return -EINVAL; printk(KERN_INFO "fb%d: %s frame buffer device, using %ldK of " "video memory\n", GET_FB_IDX(fb_info->node), fb_info->modename, zinfo->fbsize>>10); /* FIXME: This driver cannot be unloaded yet */ MOD_INC_USE_COUNT; res = 0; } return res;}static int z3fb_switch(int con, struct fb_info *info){ struct retz3_fb_info *zinfo = retz3info(info); /* Do we have to save the colormap? */ if (fb_display[zinfo->currcon].cmap.len) fb_get_cmap(&fb_display[zinfo->currcon].cmap, 1, retz3_getcolreg, info); do_fb_set_var(info, &fb_display[con].var, 1); zinfo->currcon = con; /* Install new colormap */ do_install_cmap(con, info); return 0;}/* * Update the `var' structure (called by fbcon.c) * * This call looks only at yoffset and the FB_VMODE_YWRAP flag in `var'. * Since it's called by a kernel driver, no range checking is done. */static int z3fb_updatevar(int con, struct fb_info *info){ return 0;}/* * Blank the display. */static void z3fb_blank(int blank, struct fb_info *info){ struct retz3_fb_info *zinfo = retz3info(info); volatile unsigned char *regs = retz3info(info)->regs; short i; if (blank) for (i = 0; i < 256; i++){ reg_w(regs, VDAC_ADDRESS_W, i); reg_w(regs, VDAC_DATA, 0); reg_w(regs, VDAC_DATA, 0); reg_w(regs, VDAC_DATA, 0); } else for (i = 0; i < 256; i++){ reg_w(regs, VDAC_ADDRESS_W, i); reg_w(regs, VDAC_DATA, zinfo->color_table[i][0]); reg_w(regs, VDAC_DATA, zinfo->color_table[i][1]); reg_w(regs, VDAC_DATA, zinfo->color_table[i][2]); }}/* * Get a Video Mode */static int __init get_video_mode(const char *name){ short i; for (i = 0; i < NUM_TOTAL_MODES; i++) if (!strcmp(name, retz3fb_predefined[i].name)){ retz3fb_default = retz3fb_predefined[i].var; return i; } return -1;}#ifdef MODULEMODULE_LICENSE("GPL");int init_module(void){ return retz3fb_init();}void cleanup_module(void){ /* * Not reached because the usecount will never * be decremented to zero * * FIXME: clean up ... * */}#endif/* * Text console acceleration */#ifdef FBCON_HAS_CFB8static void retz3_8_bmove(struct display *p, int sy, int sx, int dy, int dx, int height, int width){ int fontwidth = fontwidth(p); sx *= fontwidth; dx *= fontwidth; width *= fontwidth; retz3_bitblt(p, (unsigned short)sx, (unsigned short)(sy*fontheight(p)), (unsigned short)dx, (unsigned short)(dy*fontheight(p)), (unsigned short)width, (unsigned short)(height*fontheight(p)), Z3BLTcopy, 0xffff);}static void retz3_8_clear(struct vc_data *conp, struct display *p, int sy, int sx, int height, int width){ unsigned short col; int fontwidth = fontwidth(p); sx *= fontwidth; width *= fontwidth; col = attr_bgcol_ec(p, conp); col &= 0xff; col |= (col << 8); retz3_bitblt(p, (unsigned short)sx, (unsigned short)(sy*fontheight(p)), (unsigned short)sx, (unsigned short)(sy*fontheight(p)), (unsigned short)width, (unsigned short)(height*fontheight(p)), Z3BLTset, col);}static void retz3_putc(struct vc_data *conp, struct display *p, int c, int yy, int xx){ retz3_busy(p); fbcon_cfb8_putc(conp, p, c, yy, xx);}static void retz3_putcs(struct vc_data *conp, struct display *p, const unsigned short *s, int count, int yy, int xx){ retz3_busy(p); fbcon_cfb8_putcs(conp, p, s, count, yy, xx);}static void retz3_revc(struct display *p, int xx, int yy){ retz3_busy(p); fbcon_cfb8_revc(p, xx, yy);}static void retz3_clear_margins(struct vc_data* conp, struct display* p, int bottom_only){ retz3_busy(p); fbcon_cfb8_clear_margins(conp, p, bottom_only);}static struct display_switch fbcon_retz3_8 = { setup: fbcon_cfb8_setup, bmove: retz3_8_bmove, clear: retz3_8_clear, putc: retz3_putc, putcs: retz3_putcs, revc: retz3_revc, clear_margins: retz3_clear_margins, fontwidthmask: FONTWIDTH(8)};#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -