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

📄 fbdev.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
		/* Do we have to save the colormap? */		cmap = &(rivainfo->currcon_display->cmap);		DPRINTK ("switch1: con = %d, cmap.len = %d\n",			 rivainfo->currcon, cmap->len);		if (cmap->len) {			DPRINTK ("switch1a: %p %p %p %p\n", cmap->red,				 cmap->green, cmap->blue, cmap->transp);			fb_get_cmap (cmap, 1, riva_getcolreg, info);#ifdef DEBUG			if (cmap->red) {				DPRINTK ("switch1r: %X\n", cmap->red[0]);			}#endif		}	}	rivainfo->currcon = con;	rivainfo->currcon_display = dsp;	dsp->var.activate = FB_ACTIVATE_NOW;#ifdef riva_DEBUG	cmap = &dsp->cmap;	DPRINTK ("switch2: con = %d, cmap.len = %d\n", con, cmap->len);	DPRINTK ("switch2a: %p %p %p %p\n", cmap->red, cmap->green,		 cmap->blue, cmap->transp);	if (dsp->cmap.red) {		DPRINTK ("switch2r: %X\n", cmap->red[0]);	}#endif	rivafb_set_var (&dsp->var, con, info);#ifdef riva_DEBUG	DPRINTK ("switch3: con = %d, cmap.len = %d\n", con, cmap->len);	DPRINTK ("switch3a: %p %p %p %p\n", cmap->red, cmap->green,		 cmap->blue, cmap->transp);	if (dsp->cmap.red) {		DPRINTK ("switch3r: %X\n", cmap->red[0]);	}#endif	DPRINTK ("EXIT, returning 0\n");	return 0;}static int rivafb_updatevar (int con, struct fb_info *info){	int rc;	DPRINTK ("ENTER\n");	rc = (con <		0) ? -EINVAL : rivafb_pan_display (&fb_display[con].var,						   con, info);	DPRINTK ("EXIT, returning %d\n", rc);	return rc;}static void rivafb_blank (int blank, struct fb_info *info){	unsigned char tmp;	struct rivafb_info *rivainfo = (struct rivafb_info *) info;	DPRINTK ("ENTER\n");	assert (rivainfo != NULL);	tmp = vga_io_rseq (VGA_SEQ_CLOCK_MODE) & ~VGA_SR01_SCREEN_OFF;	if (blank)		tmp |= VGA_SR01_SCREEN_OFF;	vga_io_wseq (VGA_SEQ_CLOCK_MODE, tmp);	DPRINTK ("EXIT\n");}/* ------------------------------------------------------------------------- * * internal fb_ops helper functions * * ------------------------------------------------------------------------- *//** * riva_get_cmap_len * @var: * * DESCRIPTION: */static int riva_get_cmap_len (const struct fb_var_screeninfo *var){	int rc = 16;		/* reasonable default */	assert (var != NULL);	switch (var->bits_per_pixel) {#ifdef FBCON_HAS_CFB4	case 4:		rc = 16;	/* pseudocolor... 16 entries HW palette */		break;#endif#ifdef FBCON_HAS_CFB8	case 8:		rc = 256;	/* pseudocolor... 256 entries HW palette */		break;#endif#ifdef FBCON_HAS_CFB16	case 16:		rc = 16;	/* directcolor... 16 entries SW palette */		break;		/* Mystique: truecolor, 16 entries SW palette, HW palette hardwired into 1:1 mapping */#endif#ifdef FBCON_HAS_CFB32	case 32:		rc = 16;	/* directcolor... 16 entries SW palette */		break;		/* Mystique: truecolor, 16 entries SW palette, HW palette hardwired into 1:1 mapping */#endif	default:		assert (0);		/* should not occur */		break;	}	return rc;}/** * riva_getcolreg * @regno: * @red: * @green: * @blue: * @transp: * @info: pointer to rivafb_info object containing info for current riva board * * DESCRIPTION: * Read a single color register and split it into colors/transparent. * The return values must have a 16 bit magnitude. * Return != 0 for invalid regno. * * CALLED FROM: * fbcmap.c:fb_get_cmap() *	fbgen.c:fbgen_get_cmap() *	fbgen.c:fbgen_switch() */static int riva_getcolreg (unsigned regno, unsigned *red, unsigned *green,			   unsigned *blue, unsigned *transp,			   struct fb_info *info){	struct rivafb_info *rivainfo = (struct rivafb_info *) info;	if (regno >= riva_get_cmap_len(&rivainfo->currcon_display->var))		return 1;	*red = rivainfo->palette[regno].red;	*green = rivainfo->palette[regno].green;	*blue = rivainfo->palette[regno].blue;	*transp = 0;	return 0;}/** * riva_setcolreg * @regno: * @red: * @green: * @blue: * @transp: * @info: pointer to rivafb_info object containing info for current riva board * * DESCRIPTION: * Set a single color register. The values supplied have a 16 bit * magnitude. * Return != 0 for invalid regno. * * CALLED FROM: * fbcmap.c:fb_set_cmap() *	fbgen.c:fbgen_get_cmap() *	fbgen.c:fbgen_install_cmap() *		fbgen.c:fbgen_set_var() *		fbgen.c:fbgen_switch() *		fbgen.c:fbgen_blank() *	fbgen.c:fbgen_blank() */static int riva_setcolreg (unsigned regno, unsigned red, unsigned green,			   unsigned blue, unsigned transp,			   struct fb_info *info){	struct rivafb_info *rivainfo = (struct rivafb_info *) info;	struct display *p;	unsigned shift = 8;	DPRINTK ("ENTER\n");	assert (rivainfo != NULL);	assert (rivainfo->currcon_display != NULL);	p = rivainfo->currcon_display;	if (regno >= riva_get_cmap_len(&p->var))		return -EINVAL;	rivainfo->palette[regno].red = red;	rivainfo->palette[regno].green = green;	rivainfo->palette[regno].blue = blue;	if (p->var.grayscale) {		/* gray = 0.30*R + 0.59*G + 0.11*B */		red = green = blue =		    (red * 77 + green * 151 + blue * 28) >> 8;	}	switch (rivainfo->riva.Architecture) {	case 3:		shift = 10;		break;	case 4:	case 5:		shift = 8;		break;	}	switch (p->var.bits_per_pixel) {#ifdef FBCON_HAS_CFB8	case 8:		/* "transparent" stuff is completely ignored. */		riva_wclut (regno, red >> shift, green >> shift, blue >> shift);		break;#endif				/* FBCON_HAS_CFB8 */#ifdef FBCON_HAS_CFB16	case 16:		assert (regno < 16);#ifdef CONFIG_PREP		rivainfo->con_cmap.cfb16[regno] =		    ((red & 0xf800) >> 9) |		    ((green & 0xf800) >> 14) |		    ((green & 0xf800) << 2) | ((blue & 0xf800) >> 3);#else		rivainfo->con_cmap.cfb16[regno] =		    ((red & 0xf800) >> 1) |		    ((green & 0xf800) >> 6) | ((blue & 0xf800) >> 11);#endif		break;#endif				/* FBCON_HAS_CFB16 */#ifdef FBCON_HAS_CFB32	case 32:		assert (regno < 16);#ifdef CONFIG_PREP		rivainfo->con_cmap.cfb32[regno] =		    ((red & 0xff00)) |		    ((green & 0xff00) << 8) | ((blue & 0xff00) << 16);#else		rivainfo->con_cmap.cfb32[regno] =		    ((red & 0xff00) << 8) |		    ((green & 0xff00)) | ((blue & 0xff00) >> 8);#endif		break;#endif				/* FBCON_HAS_CFB32 */	default:		/* do nothing */		break;	}	return 0;}/* * riva_load_video_mode() * * calculate some timings and then send em off to riva_load_state() */static void riva_load_video_mode (struct rivafb_info *rinfo,				  struct fb_var_screeninfo *video_mode){	struct riva_regs newmode;	int bpp, width, hDisplaySize, hDisplay, hStart,	    hEnd, hTotal, height, vDisplay, vStart, vEnd, vTotal, dotClock;	/* time to calculate */	bpp = video_mode->bits_per_pixel;	width = hDisplaySize = video_mode->xres;	hDisplay = (hDisplaySize / 8) - 1;	hStart = (hDisplaySize + video_mode->right_margin) / 8 + 2;	hEnd = (hDisplaySize + video_mode->right_margin +		video_mode->hsync_len) / 8 - 1;	hTotal = (hDisplaySize + video_mode->right_margin +		  video_mode->hsync_len + video_mode->left_margin) / 8 - 1;	height = video_mode->yres;	vDisplay = video_mode->yres - 1;	vStart = video_mode->yres + video_mode->lower_margin - 1;	vEnd = video_mode->yres + video_mode->lower_margin +	    video_mode->vsync_len - 1;	vTotal = video_mode->yres + video_mode->lower_margin +	    video_mode->vsync_len + video_mode->upper_margin + 2;	dotClock = 1000000000 / video_mode->pixclock;	memcpy (&newmode, &reg_template, sizeof (struct riva_regs));	newmode.crtc[0x0] = Set8Bits (hTotal - 4);	newmode.crtc[0x1] = Set8Bits (hDisplay);	newmode.crtc[0x2] = Set8Bits (hDisplay);	newmode.crtc[0x3] = SetBitField (hTotal, 4: 0, 4:0) | SetBit (7);	newmode.crtc[0x4] = Set8Bits (hStart);	newmode.crtc[0x5] = SetBitField (hTotal, 5: 5, 7:7)		| SetBitField (hEnd, 4: 0, 4:0);	newmode.crtc[0x6] = SetBitField (vTotal, 7: 0, 7:0);	newmode.crtc[0x7] = SetBitField (vTotal, 8: 8, 0:0)		| SetBitField (vDisplay, 8: 8, 1:1)		| SetBitField (vStart, 8: 8, 2:2)		| SetBitField (vDisplay, 8: 8, 3:3)		| SetBit (4)		| SetBitField (vTotal, 9: 9, 5:5)		| SetBitField (vDisplay, 9: 9, 6:6)		| SetBitField (vStart, 9: 9, 7:7);	newmode.crtc[0x9] = SetBitField (vDisplay, 9: 9, 5:5)		| SetBit (6);	newmode.crtc[0x10] = Set8Bits (vStart);	newmode.crtc[0x11] = SetBitField (vEnd, 3: 0, 3:0)		| SetBit (5);	newmode.crtc[0x12] = Set8Bits (vDisplay);	newmode.crtc[0x13] = ((width / 8) * (bpp / 8)) & 0xFF;	newmode.crtc[0x15] = Set8Bits (vDisplay);	newmode.crtc[0x16] = Set8Bits (vTotal + 1);	newmode.ext.bpp = bpp;	newmode.ext.width = width;	newmode.ext.height = height;	rinfo->riva.CalcStateExt (&rinfo->riva, &newmode.ext, bpp, width,				  hDisplaySize, hDisplay, hStart, hEnd,				  hTotal, height, vDisplay, vStart, vEnd,				  vTotal, dotClock);	rinfo->initial_state = newmode;	riva_load_state (rinfo, &newmode);}/* ------------------------------------------------------------------------- */    /*     *  Modularization     */static struct pci_driver rivafb_driver = {	name:		"rivafb",	id_table:	rivafb_pci_tbl,	probe:		rivafb_init_one,	remove:		rivafb_remove_one,};int __init rivafb_init (void){	return pci_module_init (&rivafb_driver);}static void __exit rivafb_exit (void){	pci_unregister_driver (&rivafb_driver);}#ifdef MODULEmodule_init(rivafb_init);#endif				/* MODULE */module_exit(rivafb_exit);MODULE_AUTHOR("Ani Joshi, maintainer");MODULE_DESCRIPTION("Framebuffer driver for nVidia Riva 128, TNT, TNT2");/* from GGI */static void riva_save_state (struct rivafb_info *rinfo, struct riva_regs *regs){	int i;	outb (rinfo->riva.LockUnlockIndex, rinfo->riva.LockUnlockIO);	outb (0x57, rinfo->riva.LockUnlockIO + 1);	rinfo->riva.UnloadStateExt (&rinfo->riva, &regs->ext);	regs->misc_output = io_in8 (0x3CC);	for (i = 0; i < NUM_CRT_REGS; i++) {		io_out8 (i, 0x3D4);		regs->crtc[i] = io_in8 (0x3D5);	}	for (i = 0; i < NUM_ATC_REGS; i++) {		io_out8 (i, 0x3C0);		regs->attr[i] = io_in8 (0x3C1);	}	for (i = 0; i < NUM_GRC_REGS; i++) {		io_out8 (i, 0x3CE);		regs->gra[i] = io_in8 (0x3CF);	}	for (i = 0; i < NUM_SEQ_REGS; i++) {		io_out8 (i, 0x3C4);		regs->seq[i] = io_in8 (0x3C5);	}}/* from GGI */staticvoid riva_load_state (struct rivafb_info *rinfo, struct riva_regs *regs){	int i;	RIVA_HW_STATE *state = &regs->ext;	io_out8 (0x11, 0x3D4);	io_out8 (0x00, 0x3D5);	outb (rinfo->riva.LockUnlockIndex, rinfo->riva.LockUnlockIO);	outb (0x57, rinfo->riva.LockUnlockIO + 1);	rinfo->riva.LoadStateExt (&rinfo->riva, state);	io_out8 (regs->misc_output, 0x3C2);	for (i = 0; i < NUM_CRT_REGS; i++) {		if (i < 0x19) {			io_out8 (i, 0x3D4);			io_out8 (regs->crtc[i], 0x3D5);		} else {			switch (i) {			case 0x19:			case 0x20:			case 0x21:			case 0x22:			case 0x23:			case 0x24:			case 0x25:			case 0x26:			case 0x27:			case 0x28:			case 0x29:			case 0x2a:			case 0x2b:			case 0x2c:			case 0x2d:			case 0x2e:			case 0x2f:			case 0x30:			case 0x31:			case 0x32:			case 0x33:			case 0x34:			case 0x35:			case 0x36:			case 0x37:			case 0x38:			case 0x39:			case 0x3a:			case 0x3b:			case 0x3c:			case 0x3d:			case 0x3e:			case 0x3f:			case 0x40:				break;			default:				io_out8 (i, 0x3D4);				io_out8 (regs->crtc[i], 0x3D5);			}		}	}	for (i = 0; i < NUM_ATC_REGS; i++) {		io_out8 (i, 0x3C0);		io_out8 (regs->attr[i], 0x3C0);	}	for (i = 0; i < NUM_GRC_REGS; i++) {		io_out8 (i, 0x3CE);		io_out8 (regs->gra[i], 0x3CF);	}	for (i = 0; i < NUM_SEQ_REGS; i++) {		io_out8 (i, 0x3C4);		io_out8 (regs->seq[i], 0x3C5);	}}/** * riva_board_list_add * @board_list: Root node of list of boards * @new_node: New node to be added * * DESCRIPTION: * Adds @new_node to the list referenced by @board_list * * RETURNS: * New root node */staticstruct rivafb_info *riva_board_list_add (struct rivafb_info *board_list,					 struct rivafb_info *new_node){	struct rivafb_info *i_p = board_list;	new_node->next = NULL;	if (board_list == NULL)		return new_node;	while (i_p->next != NULL)		i_p = i_p->next;	i_p->next = new_node;	return board_list;}/** * riva_board_list_del * @board_list: Root node of list of boards * @del_node: Node to be removed * * DESCRIPTION: * Removes @del_node from the list referenced by @board_list * * RETURNS: * New root node */staticstruct rivafb_info *riva_board_list_del (struct rivafb_info *board_list,					 struct rivafb_info *del_node){	struct rivafb_info *i_p = board_list;	if (board_list == del_node)		return del_node->next;	while (i_p->next != del_node)		i_p = i_p->next;	i_p->next = del_node->next;	return board_list;}

⌨️ 快捷键说明

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