⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fbcon.c

📁 S3C44B0X下的LCD (framebuffer)驱动资料与相关代码
💻 C
📖 第 1 页 / 共 5 页
字号:
/* *  linux/drivers/video/fbcon.c -- Low level frame buffer based console driver * *	Copyright (C) 1995 Geert Uytterhoeven * * *  This file is based on the original Amiga console driver (amicon.c): * *	Copyright (C) 1993 Hamish Macdonald *			   Greg Harp *	Copyright (C) 1994 David Carter [carter@compsci.bristol.ac.uk] * *	      with work by William Rucklidge (wjr@cs.cornell.edu) *			   Geert Uytterhoeven *			   Jes Sorensen (jds@kom.auc.dk) *			   Martin Apel * *  and on the original Atari console driver (atacon.c): * *	Copyright (C) 1993 Bjoern Brauel *			   Roman Hodek * *	      with work by Guenther Kelleter *			   Martin Schaller *			   Andreas Schwab * *  Hardware cursor support added by Emmanuel Marty (core@ggi-project.org) *  Smart redraw scrolling, arbitrary font width support, 512char font support *  and software scrollback added by  *                         Jakub Jelinek (jj@ultra.linux.cz) * *  Random hacking by Martin Mares <mj@ucw.cz> * *	2001 - Documented with DocBook *	- Brad Douglas <brad@neruo.com> * *  The low level operations for the various display memory organizations are *  now in separate source files. * *  Currently the following organizations are supported: * *    o afb			Amiga bitplanes *    o cfb{2,4,8,16,24,32}	Packed pixels *    o ilbm			Amiga interleaved bitplanes *    o iplan2p[248]		Atari interleaved bitplanes *    o mfb			Monochrome *    o vga			VGA characters/attributes * *  To do: * *    - Implement 16 plane mode (iplan2p16) * * *  This file is subject to the terms and conditions of the GNU General Public *  License.  See the file COPYING in the main directory of this archive for *  more details. */#undef FBCONDEBUG#include <linux/config.h>#include <linux/module.h>#include <linux/types.h>#include <linux/sched.h>#include <linux/fs.h>#include <linux/kernel.h>#include <linux/delay.h>	/* MSch: for IRQ probe */#include <linux/tty.h>#include <linux/console.h>#include <linux/string.h>#include <linux/kd.h>#include <linux/slab.h>#include <linux/fb.h>#include <linux/vt_kern.h>#include <linux/selection.h>#include <linux/smp.h>#include <linux/init.h>#include <linux/pm.h>#include <asm/irq.h>#include <asm/system.h>#include <asm/uaccess.h>#ifdef CONFIG_AMIGA#include <asm/amigahw.h>#include <asm/amigaints.h>#endif /* CONFIG_AMIGA */#ifdef CONFIG_ATARI#include <asm/atariints.h>#endif#ifdef CONFIG_MAC#include <asm/macints.h>#endif#if defined(__mc68000__) || defined(CONFIG_APUS)#include <asm/machdep.h>#include <asm/setup.h>#endif#ifdef CONFIG_FBCON_VGA_PLANES#include <asm/io.h>#endif#define INCLUDE_LINUX_LOGO_DATA/*  * The #include <asm/linux_logo.h> didn't seem to work for us. * so I use #include <linux/linux_logo.h> if compiling for * our board * (20030314 - hede)  */#if defined(CONFIG_FB_COBRA5272) || defined (CONFIG_DRAGEN2)#include <linux/linux_logo.h>#else#include <asm/linux_logo.h>#endif#include <video/fbcon.h>#include <video/fbcon-mac.h>	/* for 6x11 font on mac */#include <video/font.h>#ifdef FBCONDEBUG#  define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __FUNCTION__ , ## args)#else#  define DPRINTK(fmt, args...)#endif#define LOGO_H			80#define LOGO_W			80#define LOGO_LINE	(LOGO_W/8)struct display fb_display[MAX_NR_CONSOLES];char con2fb_map[MAX_NR_CONSOLES];static int logo_lines;static int logo_shown = -1;/* Software scrollback */int fbcon_softback_size = 32768;static unsigned long softback_buf, softback_curr;static unsigned long softback_in;static unsigned long softback_top, softback_end;static int softback_lines;#define REFCOUNT(fd)	(((int *)(fd))[-1])#define FNTSIZE(fd)	(((int *)(fd))[-2])#define FNTCHARCNT(fd)	(((int *)(fd))[-3])#define FNTSUM(fd)	(((int *)(fd))[-4])#define FONT_EXTRA_WORDS 4#define CM_SOFTBACK	(8)#define advance_row(p, delta) (unsigned short *)((unsigned long)(p) + (delta) * conp->vc_size_row)static void fbcon_free_font(struct display *);static int fbcon_set_origin(struct vc_data *);#ifdef CONFIG_PMstatic int pm_fbcon_request(struct pm_dev *dev, pm_request_t rqst, void *data);static struct pm_dev *pm_fbcon;static int fbcon_sleeping;#endif/* * Emmanuel: fbcon will now use a hardware cursor if the * low-level driver provides a non-NULL dispsw->cursor pointer, * in which case the hardware should do blinking, etc. * * if dispsw->cursor is NULL, use Atari alike software cursor */static int cursor_drawn;#define CURSOR_DRAW_DELAY		(1)/* # VBL ints between cursor state changes */#define ARM_CURSOR_BLINK_RATE		(10)#define AMIGA_CURSOR_BLINK_RATE		(20)#define ATARI_CURSOR_BLINK_RATE		(42)#define MAC_CURSOR_BLINK_RATE		(32)#define DEFAULT_CURSOR_BLINK_RATE	(20)static int vbl_cursor_cnt;static int cursor_on;static int cursor_blink_rate;static inline void cursor_undrawn(void){    vbl_cursor_cnt = 0;    cursor_drawn = 0;}#define divides(a, b)	((!(a) || (b)%(a)) ? 0 : 1)/* *  Interface used by the world */static const char *fbcon_startup(void);static void fbcon_init(struct vc_data *conp, int init);static void fbcon_deinit(struct vc_data *conp);static int fbcon_changevar(int con);static void fbcon_clear(struct vc_data *conp, int sy, int sx, int height,		       int width);static void fbcon_putc(struct vc_data *conp, int c, int ypos, int xpos);static void fbcon_putcs(struct vc_data *conp, const unsigned short *s, int count,			int ypos, int xpos);static void fbcon_cursor(struct vc_data *conp, int mode);static int fbcon_scroll(struct vc_data *conp, int t, int b, int dir,			 int count);static void fbcon_bmove(struct vc_data *conp, int sy, int sx, int dy, int dx,			int height, int width);static int fbcon_switch(struct vc_data *conp);static int fbcon_blank(struct vc_data *conp, int blank);static int fbcon_font_op(struct vc_data *conp, struct console_font_op *op);static int fbcon_set_palette(struct vc_data *conp, unsigned char *table);static int fbcon_scrolldelta(struct vc_data *conp, int lines);/* *  Internal routines */static void fbcon_setup(int con, int init, int logo);static __inline__ int real_y(struct display *p, int ypos);static void fbcon_vbl_handler(int irq, void *dummy, struct pt_regs *fp);static __inline__ void updatescrollmode(struct display *p);static __inline__ void ywrap_up(int unit, struct vc_data *conp,				struct display *p, int count);static __inline__ void ywrap_down(int unit, struct vc_data *conp,				  struct display *p, int count);static __inline__ void ypan_up(int unit, struct vc_data *conp,			       struct display *p, int count);static __inline__ void ypan_down(int unit, struct vc_data *conp,				 struct display *p, int count);static void fbcon_bmove_rec(struct display *p, int sy, int sx, int dy, int dx,			    int height, int width, u_int y_break);static int fbcon_show_logo(void);#ifdef CONFIG_MAC/* * On the Macintoy, there may or may not be a working VBL int. We need to probe */static int vbl_detected;static void fbcon_vbl_detect(int irq, void *dummy, struct pt_regs *fp){      vbl_detected++;}#endifstatic void cursor_timer_handler(unsigned long dev_addr);static struct timer_list cursor_timer = {    function: cursor_timer_handler};static int use_timer_cursor;static void cursor_timer_handler(unsigned long dev_addr){      fbcon_vbl_handler(0, NULL, NULL);      cursor_timer.expires = jiffies+HZ/50;      add_timer(&cursor_timer);}/** *	PROC_CONSOLE - find the attached tty or visible console *	@info: frame buffer info structure * *	Finds the tty attached to the process or visible console if *	the process is not directly attached to a tty (e.g. remote *	user) for device @info. * *	Returns -1 errno on error, or tty/visible console number *	on success. * */int PROC_CONSOLE(const struct fb_info *info){        int fgc;	if (info->display_fg == NULL)		return -1;        if (!current->tty ||	    current->tty->driver.type != TTY_DRIVER_TYPE_CONSOLE ||	    MINOR(current->tty->device) < 1)		fgc = info->display_fg->vc_num;	else		fgc = MINOR(current->tty->device)-1;	/* Does this virtual console belong to the specified fbdev? */	if (fb_display[fgc].fb_info != info)		return -1;	return fgc;}/** *	set_all_vcs - set all virtual consoles to match *	@fbidx: frame buffer index (e.g. fb0, fb1, ...) *	@fb: frame buffer ops structure *	@var: frame buffer screen structure to set *	@info: frame buffer info structure * *	Set all virtual consoles to match screen info set in @var *	for device @info. * *	Returns negative errno on error, or zero on success. * */int set_all_vcs(int fbidx, struct fb_ops *fb, struct fb_var_screeninfo *var,                struct fb_info *info){    int unit, err;    var->activate |= FB_ACTIVATE_TEST;    err = fb->fb_set_var(var, PROC_CONSOLE(info), info);    var->activate &= ~FB_ACTIVATE_TEST;    if (err)            return err;    for (unit = 0; unit < MAX_NR_CONSOLES; unit++)            if (fb_display[unit].conp && con2fb_map[unit] == fbidx)                    fb->fb_set_var(var, unit, info);    return 0;}/** *	set_con2fb_map - map console to frame buffer device *	@unit: virtual console number to map *	@newidx: frame buffer index to map virtual console to * *	Maps a virtual console @unit to a frame buffer device *	@newidx. * */void set_con2fb_map(int unit, int newidx){    int oldidx = con2fb_map[unit];    struct fb_info *oldfb, *newfb;    struct vc_data *conp;    char *fontdata;    unsigned short fontwidth, fontheight, fontwidthlog, fontheightlog;    int userfont;    if (newidx != con2fb_map[unit]) {       oldfb = registered_fb[oldidx];       newfb = registered_fb[newidx];	if (newfb->fbops->owner)		__MOD_INC_USE_COUNT(newfb->fbops->owner);	if (newfb->fbops->fb_open && newfb->fbops->fb_open(newfb,0)) {		if (newfb->fbops->owner)			__MOD_DEC_USE_COUNT(newfb->fbops->owner);		return;	}	if (oldfb->fbops->fb_release)		oldfb->fbops->fb_release(oldfb,0);	if (oldfb->fbops->owner)		__MOD_DEC_USE_COUNT(oldfb->fbops->owner);       conp = fb_display[unit].conp;       fontdata = fb_display[unit].fontdata;       fontwidth = fb_display[unit]._fontwidth;       fontheight = fb_display[unit]._fontheight;       fontwidthlog = fb_display[unit]._fontwidthlog;       fontheightlog = fb_display[unit]._fontheightlog;       userfont = fb_display[unit].userfont;       con2fb_map[unit] = newidx;       fb_display[unit] = *(newfb->disp);       fb_display[unit].conp = conp;       fb_display[unit].fontdata = fontdata;       fb_display[unit]._fontwidth = fontwidth;       fb_display[unit]._fontheight = fontheight;       fb_display[unit]._fontwidthlog = fontwidthlog;       fb_display[unit]._fontheightlog = fontheightlog;       fb_display[unit].userfont = userfont;       fb_display[unit].fb_info = newfb;       if (conp)	   conp->vc_display_fg = &newfb->display_fg;       if (!newfb->display_fg)	   newfb->display_fg = conp;       if (!newfb->changevar)           newfb->changevar = oldfb->changevar;       /* tell console var has changed */       if (newfb->changevar)           newfb->changevar(unit);   }}/* *  Low Level Operations */struct display_switch fbcon_dummy;/* NOTE: fbcon cannot be __init: it may be called from take_over_console later */static const char *fbcon_startup(void){    const char *display_desc = "frame buffer device";    int irqres = 1;    static int done = 0;    /*     *  If num_registered_fb is zero, this is a call for the dummy part.     *  The frame buffer devices weren't initialized yet.     */    if (!num_registered_fb || done)	return display_desc;    done = 1;#ifdef CONFIG_AMIGA    if (MACH_IS_AMIGA) {	cursor_blink_rate = AMIGA_CURSOR_BLINK_RATE;	irqres = request_irq(IRQ_AMIGA_VERTB, fbcon_vbl_handler, 0,			     "console/cursor", fbcon_vbl_handler);    }#endif /* CONFIG_AMIGA */#ifdef CONFIG_ATARI    if (MACH_IS_ATARI) {	cursor_blink_rate = ATARI_CURSOR_BLINK_RATE;	irqres = request_irq(IRQ_AUTO_4, fbcon_vbl_handler, IRQ_TYPE_PRIO,			     "console/cursor", fbcon_vbl_handler);    }#endif /* CONFIG_ATARI */#ifdef CONFIG_MAC    /*     * On a Macintoy, the VBL interrupt may or may not be active.      * As interrupt based cursor is more reliable and race free, we      * probe for VBL interrupts.     */    if (MACH_IS_MAC) {	int ct = 0;	/*	 * Probe for VBL: set temp. handler ...	 */	irqres = request_irq(IRQ_MAC_VBL, fbcon_vbl_detect, 0,			     "console/cursor", fbcon_vbl_detect);	vbl_detected = 0;	/*	 * ... and spin for 20 ms ...	 */	while (!vbl_detected && ++ct<1000)	    udelay(20); 	if(ct==1000)	    printk("fbcon_startup: No VBL detected, using timer based cursor.\n"); 	free_irq(IRQ_MAC_VBL, fbcon_vbl_detect);	if (vbl_detected) {	    /*	     * interrupt based cursor ok	     */	    cursor_blink_rate = MAC_CURSOR_BLINK_RATE;	    irqres = request_irq(IRQ_MAC_VBL, fbcon_vbl_handler, 0,				 "console/cursor", fbcon_vbl_handler);	} else {	    /*	     * VBL not detected: fall through, use timer based cursor	     */	    irqres = 1;	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -