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

📄 controlfb.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
/* *  controlfb.c -- frame buffer device for the PowerMac 'control' display * *  Created 12 July 1998 by Dan Jacobowitz <dan@debian.org> *  Copyright (C) 1998 Dan Jacobowitz * *  Frame buffer structure from: *    drivers/video/chipsfb.c -- frame buffer device for *    Chips & Technologies 65550 chip. * *    Copyright (C) 1998 Paul Mackerras * *    This file is derived from the Powermac "chips" driver: *    Copyright (C) 1997 Fabio Riccardi. *    And from the frame buffer device for Open Firmware-initialized devices: *    Copyright (C) 1997 Geert Uytterhoeven. * *  Hardware information from: *    control.c: Console support for PowerMac "control" display adaptor. *    Copyright (C) 1996 Paul Mackerras * *  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. */#include <linux/config.h>#include <linux/module.h>#include <linux/kernel.h>#include <linux/errno.h>#include <linux/string.h>#include <linux/mm.h>#include <linux/tty.h>#include <linux/malloc.h>#include <linux/vmalloc.h>#include <linux/delay.h>#include <linux/interrupt.h>#include <linux/fb.h>#include <linux/selection.h>#include <linux/init.h>#include <linux/pci.h>#include <linux/nvram.h>#ifdef CONFIG_FB_COMPAT_XPMAC#include <asm/vc_ioctl.h>#endif#include <linux/adb.h>#include <linux/cuda.h>#include <asm/io.h>#include <asm/prom.h>#include <asm/pgtable.h>#include <video/fbcon.h>#include <video/fbcon-cfb8.h>#include <video/fbcon-cfb16.h>#include <video/fbcon-cfb32.h>#include <video/macmodes.h>#include "controlfb.h"struct fb_par_control {	int	vmode, cmode;	int	xres, yres;	int	vxres, vyres;	int	xoffset, yoffset;};#define DIRTY(z) ((x)->z != (y)->z)static inline int PAR_EQUAL(struct fb_par_control *x, struct fb_par_control *y){	return (!DIRTY(vmode) && !DIRTY(cmode) && !DIRTY(xres)		&& !DIRTY(yres) && !DIRTY(vxres) && !DIRTY(vyres)		&& !DIRTY(xoffset) && !DIRTY(yoffset));}static inline int VAR_MATCH(struct fb_var_screeninfo *x, struct fb_var_screeninfo *y){	return (!DIRTY(bits_per_pixel) && !DIRTY(xres)		&& !DIRTY(yres) && !DIRTY(xres_virtual)		&& !DIRTY(yres_virtual));}struct fb_info_control {	struct fb_info			info;/*	struct fb_fix_screeninfo	fix;	struct fb_var_screeninfo	var;*/	struct display			display;	struct fb_par_control		par;	struct {		__u8 red, green, blue;	}			palette[256];		struct cmap_regs	*cmap_regs;	unsigned long		cmap_regs_phys;		struct control_regs	*control_regs;	unsigned long		control_regs_phys;		__u8			*frame_buffer;	unsigned long		frame_buffer_phys;		int			sense, control_use_bank2;	unsigned long		total_vram;	union {#ifdef FBCON_HAS_CFB16		u16 cfb16[16];#endif#ifdef FBCON_HAS_CFB32		u32 cfb32[16];#endif	} fbcon_cmap;};/******************** Prototypes for exported functions ********************/static int control_get_fix(struct fb_fix_screeninfo *fix, int con,			 struct fb_info *info);static int control_get_var(struct fb_var_screeninfo *var, int con,			 struct fb_info *info);static int control_set_var(struct fb_var_screeninfo *var, int con,			 struct fb_info *info);static int control_pan_display(struct fb_var_screeninfo *var, int con,			     struct fb_info *info);static int control_get_cmap(struct fb_cmap *cmap, int kspc, int con,			  struct fb_info *info);static int control_set_cmap(struct fb_cmap *cmap, int kspc, int con,			  struct fb_info *info);static int control_mmap(struct fb_info *info, struct file *file,                         struct vm_area_struct *vma);static int controlfb_getcolreg(u_int regno, u_int *red, u_int *green,			     u_int *blue, u_int *transp, struct fb_info *info);static int controlfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,			     u_int transp, struct fb_info *info);/******************** Prototypes for internal functions ********************/static void control_par_to_fix(struct fb_par_control *par, struct fb_fix_screeninfo *fix,	struct fb_info_control *p);static void do_install_cmap(int con, struct fb_info *info);static void control_set_dispsw(struct display *disp, int cmode, struct fb_info_control *p);/************************* Internal variables *****************************/static int currcon = 0;static int par_set = 0;static char fontname[40] __initdata = { 0 };static int default_vmode = VMODE_NVRAM;static int default_cmode = CMODE_NVRAM;/* * Exported functions */int control_init(void);void control_setup(char *);static void control_of_init(struct device_node *dp);static int read_control_sense(struct fb_info_control *p);static inline int control_vram_reqd(int video_mode, int color_mode);static void set_control_clock(unsigned char *params);static void control_set_hardware(struct fb_info_control *p, struct fb_par_control *par);static inline void control_par_to_var(struct fb_par_control *par, struct fb_var_screeninfo *var);static int control_var_to_par(struct fb_var_screeninfo *var,	struct fb_par_control *par, const struct fb_info *fb_info);static void control_init_info(struct fb_info *info, struct fb_info_control *p);static void control_par_to_display(struct fb_par_control *par,  struct display *disp, struct fb_fix_screeninfo *fix, struct fb_info_control *p);static int controlfb_updatevar(int con, struct fb_info *info);static struct fb_ops controlfb_ops = {	owner:		THIS_MODULE,	fb_get_fix:	control_get_fix,	fb_get_var:	control_get_var,	fb_set_var:	control_set_var,	fb_get_cmap:	control_get_cmap,	fb_set_cmap:	control_set_cmap,	fb_pan_display:	control_pan_display,	fb_mmap:	control_mmap,};/********************  The functions for controlfb_ops ********************/#ifdef MODULEint init_module(void){	struct device_node *dp;	printk("Loading...\n");	dp = find_devices("control");	if (dp != 0)		control_of_init(dp);	else		printk("Failed.\n");	printk("Done.\n");}void cleanup_module(void){	/* FIXME: clean up and release regions */}#endif/*********** Providing our information to the user ************/static int control_get_fix(struct fb_fix_screeninfo *fix, int con,			 struct fb_info *info){	struct fb_info_control *p = (struct fb_info_control *) info;	if(!par_set)		printk(KERN_ERR "control_get_fix called with unset par!\n");	if(con == -1) {		control_par_to_fix(&p->par, fix, p);	} else {		struct fb_par_control par;				control_var_to_par(&fb_display[con].var, &par, info);		control_par_to_fix(&par, fix, p);	}	return 0;}static int control_get_var(struct fb_var_screeninfo *var, int con,			 struct fb_info *info){	struct fb_info_control *p = (struct fb_info_control *) info;	if(!par_set)		printk(KERN_ERR "control_get_var called with unset par!\n");	if(con == -1) {		control_par_to_var(&p->par, var);	} else {		*var = fb_display[con].var;	}	return 0;}/* Sets everything according to var *//* No longer safe for use in console switching */static int control_set_var(struct fb_var_screeninfo *var, int con,			 struct fb_info *info){	struct fb_info_control *p = (struct fb_info_control *) info;	struct display *disp;	struct fb_par_control par;	int depthchange, err;	int activate = var->activate;	disp = (con >= 0) ? &fb_display[con] : info->disp;	if((err = control_var_to_par(var, &par, info))) {		printk (KERN_ERR "control_set_var: error calling control_var_to_par: %d.\n", err);		return err;	}		control_par_to_var(&par, var);		if ((activate & FB_ACTIVATE_MASK) != FB_ACTIVATE_NOW)		return 0;/* I know, we want to use fb_display[con], but grab certain info from p->var instead. *//* [above no longer true] */	depthchange = (disp->var.bits_per_pixel != var->bits_per_pixel);	if(!VAR_MATCH(&disp->var, var)) {		struct fb_fix_screeninfo	fix;		control_par_to_fix(&par, &fix, p);		control_par_to_display(&par, disp, &fix, p);		if(info->changevar)			(*info->changevar)(con);	} else		disp->var = *var;	/*p->disp = *disp;*/		if(con == currcon || con == -1) {		control_set_hardware(p, &par);	}	if(depthchange) {		if((err = fb_alloc_cmap(&disp->cmap, 0, 0)))			return err;		do_install_cmap(con, info);	}	return 0;}static int control_pan_display(struct fb_var_screeninfo *var, int con,			     struct fb_info *info){	struct fb_info_control *p = (struct fb_info_control *)info;	struct fb_par_control *par = &p->par;		if (var->xoffset != 0 || var->yoffset+var->yres > var->yres_virtual)		return -EINVAL;	fb_display[con].var.yoffset =  par->yoffset = var->yoffset;	if(con == currcon)		out_le32(&p->control_regs->start_addr.r,		    par->yoffset * (par->vxres << par->cmode));	return 0;}static int control_get_cmap(struct fb_cmap *cmap, int kspc, int con,			  struct fb_info *info){	if (con == currcon)		/* current console? */		return fb_get_cmap(cmap, kspc, controlfb_getcolreg, info);	if (fb_display[con].cmap.len)	/* non default colormap? */		fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0: 2);	else {		int size = fb_display[con].var.bits_per_pixel == 16 ? 32 : 256;		fb_copy_cmap(fb_default_cmap(size), cmap, kspc ? 0 : 2);	}	return 0;}static int control_set_cmap(struct fb_cmap *cmap, int kspc, int con,			 struct fb_info *info){	struct display *disp = &fb_display[con];	int err;	if (disp->cmap.len == 0) {		int size = disp->var.bits_per_pixel == 16 ? 32 : 256;		err = fb_alloc_cmap(&disp->cmap, size, 0);		if (err)			return err;	}	if (con == currcon)		return fb_set_cmap(cmap, kspc, controlfb_setcolreg, info);	fb_copy_cmap(cmap, &disp->cmap, kspc ? 0 : 1);	return 0;}/* Private mmap since we want to have a different caching on the framebuffer * for controlfb. * Note there's no locking in here; it's done in fb_mmap() in fbmem.c. */static int control_mmap(struct fb_info *info, struct file *file,                       struct vm_area_struct *vma){       struct fb_ops *fb = info->fbops;       struct fb_fix_screeninfo fix;       struct fb_var_screeninfo var;       unsigned long off, start;       u32 len;       fb->fb_get_fix(&fix, PROC_CONSOLE(info), info);       off = vma->vm_pgoff << PAGE_SHIFT;       /* frame buffer memory */       start = fix.smem_start;       len = PAGE_ALIGN((start & ~PAGE_MASK)+fix.smem_len);       if (off >= len) {               /* memory mapped io */               off -= len;               fb->fb_get_var(&var, PROC_CONSOLE(info), info);               if (var.accel_flags)                       return -EINVAL;               start = fix.mmio_start;               len = PAGE_ALIGN((start & ~PAGE_MASK)+fix.mmio_len);               pgprot_val(vma->vm_page_prot) |= _PAGE_NO_CACHE|_PAGE_GUARDED;       } else {               /* framebuffer */               pgprot_val(vma->vm_page_prot) |= _PAGE_WRITETHRU;       }       start &= PAGE_MASK;       vma->vm_pgoff = off >> PAGE_SHIFT;       if (io_remap_page_range(vma->vm_start, off,           vma->vm_end - vma->vm_start, vma->vm_page_prot))               return -EAGAIN;       return 0;}/********************  End of controlfb_ops implementation  ********************//* (new one that is) */static int controlfb_switch(int con, struct fb_info *info){	struct fb_info_control	*p = (struct fb_info_control *)info;	struct fb_par_control	par;	int oldcon = currcon;	if (fb_display[currcon].cmap.len)		fb_get_cmap(&fb_display[currcon].cmap, 1, controlfb_getcolreg,			    info);	currcon = con;	control_var_to_par(&fb_display[con].var, &par, info);	control_set_hardware(p, &par);	control_set_dispsw(&fb_display[con], par.cmode, p);	if(fb_display[oldcon].var.yoffset != fb_display[con].var.yoffset)		controlfb_updatevar(con, info);	do_install_cmap(con, info);	return 1;}static int controlfb_updatevar(int con, struct fb_info *info){	struct fb_info_control	*p = (struct fb_info_control *)info;	if(con != currcon)		return 0;	/* imsttfb blanks the unused bottom of the screen here...hmm. */	out_le32(&p->control_regs->start_addr.r,	    fb_display[con].var.yoffset * fb_display[con].line_length);		return 0;}static void controlfb_blank(int blank_mode, struct fb_info *info){/* *  Blank the screen if blank_mode != 0, else unblank. If blank == NULL *  then the caller blanks by setting the CLUT (Color Look Up Table) to all *  black. Return 0 if blanking succeeded, != 0 if un-/blanking failed due *  to e.g. a video mode which doesn't support it. Implements VESA suspend *  and powerdown modes on hardware that supports disabling hsync/vsync: *    blank_mode == 2: suspend vsync *    blank_mode == 3: suspend hsync *    blank_mode == 4: powerdown

⌨️ 快捷键说明

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