📄 dragonfb.c
字号:
switch (default_var.bits_per_pixel) { /* maybe I should pass a var and use it here */#ifdef FBCON_HAS_MFB case 1: printk(KERN_INFO "Using fbcon_mfb\n"); disp->dispsw = &fbcon_mfb; break;#endif#ifdef FBCON_HAS_CFB2 case 2: printk(KERN_INFO "Using fbcon_CFB2\n"); disp->dispsw = &fbcon_cfb2; break;#endif#ifdef FBCON_HAS_CFB4 case 4: disp->dispsw = &fbcon_cfb4; break;#endif#ifdef FBCON_HAS_CFB8 case 8: disp->dispsw = &fbcon_cfb8; break;#endif#ifdef FBCON_HAS_CFB16 case 16: disp->dispsw = &fbcon_cfb16; disp->dispsw_data = fbcon_cmap.cfb16; break;#endif#ifdef FBCON_HAS_CFB24 case 24: disp->dispsw = &fbcon_cfb24; disp->dispsw_data = fbcon_cmap.cfb24; break;#endif#ifdef FBCON_HAS_CFB32 case 32: disp->dispsw = &fbcon_cfb32; disp->dispsw_data = fbcon_cmap.cfb32; break;#endif default: disp->dispsw = &fbcon_dummy; break; } //disp->dispsw = &fbcon_dummy; disp->visual = current_fix.visual; disp->type = current_fix.type; disp->type_aux = current_fix.type_aux; disp->type_aux = current_fix.type_aux; disp->ypanstep = current_fix.ypanstep; disp->ywrapstep = current_fix.ywrapstep; disp->line_length = current_fix.line_length; disp->can_soft_blank = 1; disp->inverse = 0; memcpy(&disp->var, &default_var, sizeof(struct fb_var_screeninfo));}/* ------------ Hardware Independent Functions ------------ */ /* * Setup */int __init dragon_fb_setup(char *options){#if defined(DEBUG) printk(KERN_DEBUG "fb%d: start: dragon_fb_setup\n", GET_FB_IDX(fb_info.node));#endif /* Parse user speficied options (`video=dragon_fb:') */ /* no parsing yet */ return 0;}/* ------------------------------------------------------------------------- */ /* * Frame buffer operations *//* If all you need is that - just don't define ->fb_open *//*static int dragon_fb_open(const struct fb_info *info, int user){ return 0;}*//* If all you need is that - just don't define ->fb_release *//*static int dragon_fb_release(const struct fb_info *info, int user){ return 0;}*/ /* * Get the Fixed Part of the Display */static int dragon_get_fix(struct fb_fix_screeninfo *fix, int con, struct fb_info *info){#if defined(DEBUG) printk(KERN_DEBUG "fb%d: start: dragon_get_fix\n", GET_FB_IDX(fb_info.node));#endif /* we only have one mode, so our fix_screeninfo struct always has the same values, just throw it back to the user current_fix was initialized earlier in init */#if defined(DEBUG) printk(KERN_DEBUG "fb: info: getting fix for console %d\n", con);#endif memcpy(fix, ¤t_fix, sizeof(struct fb_fix_screeninfo)); return 0;} /* * Get the User Defined Part of the Display */static int dragon_get_var(struct fb_var_screeninfo *var, int con, struct fb_info *info){#if defined(DEBUG) printk(KERN_DEBUG "fb%d: start: dragon_get_var\n", GET_FB_IDX(fb_info.node)); printk(KERN_DEBUG "fb: info: getting var for console %d\n", con);#endif if (con == -1) *var = default_var; else *var = fb_display[con].var; set_color_bitfields(var); return 0;} /* * Set the User Defined Part of the Display */static int dragon_set_var(struct fb_var_screeninfo *var, int con, struct fb_info *info){ int activate = var->activate; struct display *display;#if defined(DEBUG) printk(KERN_DEBUG "fb%d: start: dragon_set_var\n", GET_FB_IDX(fb_info.node));#endif if (con >= 0) { display = &fb_display[con]; /* this is the mechanism I use to initialize the display structures. You should have noticed that I assume that fbcon will call set_var at least once before using the display, I need to verify that */ if (!display_initialized[con]) { dragon_initialize_display(display); display_initialized[con] = 1; } } else display = &disp; /* used during initialization */ /* * We are working with an LCD, which means that we * can't allow for modifications of many of the screen's * usually updateable parameters */ /** I wonder if the first time a display is initialized, this method is called by fbcon to initialize the display struct, I should test this, VERY SERIOUS my temp solution has been to */ if (var->xres != display->var.xres || var->yres != display->var.yres || var->xres_virtual != var->xres || /* virtual is not supported yet */ var->yres_virtual != var->yres || (var->xoffset != 0 && !(var->vmode & FB_VMODE_CONUPDATE)) || (var->yoffset != 0 && !(var->vmode & FB_VMODE_CONUPDATE)) || (var->bits_per_pixel != display->var.bits_per_pixel)) { return -EINVAL; } set_color_bitfields(var); /* I don't really know what this does yet, I'll have to work on it */ /* Since we don't allow anything to change anyways, there's no need to update the display var, makes our lifes much easier :-)*/ return 0;} /* * In most cases the `generic' routines (fbgen_*) should be satisfactory. * However, you're free to fill in your own replacements. */static struct fb_ops dragonfb_ops = { owner: THIS_MODULE, fb_get_fix: dragon_get_fix, fb_get_var: dragon_get_var, fb_set_var: dragon_set_var, fb_get_cmap: dragon_get_cmap, fb_set_cmap: dragon_set_cmap,}; /* * Initialization */void dragon_lcd_init(){ int i = 0; int translation; /* used to translate some settings to their register values */#if defined(DEBUG) printk(KERN_DEBUG "fb: start: dragon_lcd_init\n"); printk(KERN_DEBUG "fb: debug: dragon_lcd_init: Setting LSSA to %08x\n", (int) &__vram_start);#endif// The order the initialisation is performed, is very important. The board may crash!!!#if defined(CONFIG_M68EZ328) // Set Controller io pins according to the interface used #if BUSWIDTH_LPICF == 0x00 PCSEL&=~0xf1; // PCPDEN&=~0xf1; // We don't need pull-ups for those pins #elif BUSWIDTH_LPICF == 0x04 PCSEL&=~0xf3; PCPDEN&=~0xf3; // We don't need pull-ups for those pins #elif BUSWIDTH_LPICF == 0x08 PCSEL&=~0xff; PCPDEN&=~0xff; // We don't need pull-ups for those pins #endif LSSA = &__vram_start; /* the LCD Screen Starting Address Register should point at vram */ LXMAX = X_RES; LYMAX = Y_RES-1; // see 8.3.4 of the manual, size is +1 LVPW = X_RES>>(4-GRAY_LPICF); LPICF = BUSWIDTH_LPICF|GRAY_LPICF; LPOLCF = POLARITY; LACDRC = ACRATE; LPXCD = PIXRATE; LRRA = REFRATE; LCKCON = 0x80; // Fixme change this when you use a dedicated SRAM or ROM LPOSR = 0x00; LGPMR = GRAYSCALE;#elif defined(CONFIG_M68VZ328) // Set Controller io pins according to the interface used #if BUSWIDTH_LPICF == 0x00 PCSEL&=~0xf1; // PCPDEN&=~0xf1; // We don't need pull-ups for those pins #elif BUSWIDTH_LPICF == 0x04 PCSEL&=~0xf3; PCPDEN&=~0xf3; // We don't need pull-ups for those pins #elif BUSWIDTH_LPICF == 0x08 PCSEL&=~0xff; PCPDEN&=~0xff; // We don't need pull-ups for those pins #elif BUSWIDTH_LPICF == 0xc0 PCSEL&=~0xff; PCPDEN&=~0xff; // We don't need pull-ups for those pins PKSEL&=~0xf0; PKPUEN&=~0xf0; // We don't need pull-ups for those pins #endif LSSA = &__vram_start; /* the LCD Screen Starting Address Register should point at vram */ LXMAX = X_RES; LYMAX = Y_RES-1; // see 8.3.4 of the manual, size is +1 LVPW = X_RES>>(4-GRAY_LPICF); LPICF = BUSWIDTH_LPICF|GRAY_LPICF; LPOLCF = POLARITY; LACDRC = ACRATE; LPXCD = PIXRATE; LRRA = REFRATE; LCKCON = 0x80; LPOSR = 0x00; LGPMR = GRAYSCALE; RMCR=0; DMACR=0x62;#endif#if defined(DEBUG) /* for testing purposes */ for (i = 0; i < Y_RES; i+= 10) { memset(((char *)(&__vram_start)) + i * X_RES * BPP / 8, 0xff, 2 * X_RES * BPP / 8); memset(((char *)(&__vram_start)) + (i + 2) * X_RES * BPP / 8, 0, 8 * X_RES * BPP / 8); }#endif /* Add your custom display initialisation code here */#if defined(CONFIG_DRAGONIXVZ) PBSEL|=0xc0; // TIN/OUT is nDISPEN and PWMO1 is nBLEN PBPUEN|=0xc0; // Enable pullups PBDIR|=0xc0; // Outputs PBDATA=(PBDATA&~0x80)|0x40; // Display on, backlight on#endif}int __init dragon_fb_init(void){#if defined(DEBUG) printk(KERN_DEBUG "fb: start: dragon_fb_init\n");#endif /* then we initialize our lcd */ dragon_lcd_init(); /* then our structures */ fb_info.changevar = NULL; fb_info.node = -1; fb_info.fbops = &dragonfb_ops; fb_info.disp = &disp; fb_info.switch_con = &dragoncon_switch; fb_info.updatevar = &dragoncon_updatevar; fb_info.blank = &dragoncon_blank; fb_info.flags = FBINFO_FLAG_DEFAULT; fb_info.screen_base = (char *)__vram_start; dragon_initialize_display(&disp); if (register_framebuffer(&fb_info) < 0) { return -EINVAL; } printk(KERN_INFO "fb%d: end: Virtual frame buffer device initialized\n", GET_FB_IDX(fb_info.node)); printk(KERN_INFO "(C) 2001 by Khaled Hassounah <khassounah@mediumware.net>\n"); /* uncomment this if your driver cannot be unloaded */ /* MOD_INC_USE_COUNT; */ return 0;} /* * Cleanup */void dragon_fb_cleanup(struct fb_info *info){#if defined(DEBUG) printk(KERN_DEBUG "fb%d: start: dragon_fb_cleanup\n", GET_FB_IDX(fb_info.node));#endif /* * If your driver supports multiple boards, you should unregister and * clean up all instances. */ unregister_framebuffer(&fb_info);}/* ------------------------------------------------------------------------- */ /* * Modularization */#ifdef MODULEMODULE_LICENSE("GPL");int init_module(void){ return dragon_fb_init();}void cleanup_module(void){ dragon_fb_cleanup(void);}#endif /* MODULE */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -