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

📄 matroxfb_crtc2.c

📁 上传linux-jx2410的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
				ACCESS_FBINFO(primout)->compute(MINFO, &mt, hw);		}		if (ACCESS_FBINFO(output.sh) & MATROXFB_OUTPUT_CONN_SECONDARY) {			down_read(&ACCESS_FBINFO(altout.lock));			if (ACCESS_FBINFO(altout.output))				ACCESS_FBINFO(altout.output)->compute(ACCESS_FBINFO(altout.device), &mt, hw);			up_read(&ACCESS_FBINFO(altout.lock));		}		matroxfb_dh_restore(m2info, &mt, p, mode, pos);		DAC1064_global_restore(PMINFO hw);		if (ACCESS_FBINFO(output.sh) & MATROXFB_OUTPUT_CONN_PRIMARY) {			if (ACCESS_FBINFO(primout))				ACCESS_FBINFO(primout)->program(MINFO, hw);		}		if (ACCESS_FBINFO(output.sh) & MATROXFB_OUTPUT_CONN_SECONDARY) {			down_read(&ACCESS_FBINFO(altout.lock));			if (ACCESS_FBINFO(altout.output))				ACCESS_FBINFO(altout.output)->program(ACCESS_FBINFO(altout.device), hw);			up_read(&ACCESS_FBINFO(altout.lock));		}		if (ACCESS_FBINFO(output.sh) & MATROXFB_OUTPUT_CONN_PRIMARY) {			if (ACCESS_FBINFO(primout))				ACCESS_FBINFO(primout)->start(MINFO);		}		if (ACCESS_FBINFO(output.sh) & MATROXFB_OUTPUT_CONN_SECONDARY) {			down_read(&ACCESS_FBINFO(altout.lock));			if (ACCESS_FBINFO(altout.output))				ACCESS_FBINFO(altout.output)->start(ACCESS_FBINFO(altout.device));			up_read(&ACCESS_FBINFO(altout.lock));		}		matroxfb_dh_cfbX_init(m2info, p);		do_install_cmap(m2info, p);	}	return 0;#undef m2info}static int matroxfb_dh_get_cmap(struct fb_cmap* cmap, int kspc, int con,		struct fb_info* info) {#define m2info ((struct matroxfb_dh_fb_info*)info)	struct display* dsp;	if (con < 0)		dsp = m2info->fbcon.disp;	else		dsp = fb_display + con;	if (con == m2info->currcon)		return fb_get_cmap(cmap, kspc, matroxfb_dh_getcolreg, info);	else if (dsp->cmap.len)		fb_copy_cmap(&dsp->cmap, cmap, kspc ? 0 : 2);	else		fb_copy_cmap(fb_default_cmap(16), cmap, kspc ? 0 : 2);	return 0;#undef m2info}static int matroxfb_dh_set_cmap(struct fb_cmap* cmap, int kspc, int con,		struct fb_info* info) {#define m2info ((struct matroxfb_dh_fb_info*)info)	struct display* dsp;	if (con < 0)		dsp = m2info->fbcon.disp;	else		dsp = fb_display + con;	if (dsp->cmap.len != 16) {		int err;		err = fb_alloc_cmap(&dsp->cmap, 16, 0);		if (err)			return err;	}	if (con == m2info->currcon)		return fb_set_cmap(cmap, kspc, matroxfb_dh_setcolreg, info);	else		fb_copy_cmap(cmap, &dsp->cmap, kspc ? 0 : 1);	return 0;#undef m2info}static int matroxfb_dh_pan_display(struct fb_var_screeninfo* var, int con,		struct fb_info* info) {#define m2info ((struct matroxfb_dh_fb_info*)info)	if (var->xoffset + fb_display[con].var.xres > fb_display[con].var.xres_virtual ||	    var->yoffset + fb_display[con].var.yres > fb_display[con].var.yres_virtual)		return -EINVAL;	if (con == m2info->currcon)		matroxfb_dh_pan_var(m2info, var);	fb_display[con].var.xoffset = var->xoffset;	fb_display[con].var.yoffset = var->yoffset;	return 0;#undef m2info}static int matroxfb_dh_switch(int con, struct fb_info* info);static int matroxfb_dh_get_vblank(const struct matroxfb_dh_fb_info* m2info, struct fb_vblank* vblank) {	MINFO_FROM(m2info->primary_dev);	memset(vblank, 0, sizeof(*vblank));	vblank->flags = FB_VBLANK_HAVE_VCOUNT | FB_VBLANK_HAVE_VBLANK;	/* mask out reserved bits + field number (odd/even) */	vblank->vcount = mga_inl(0x3C48) & 0x000007FF;	/* compatibility stuff */	if (vblank->vcount >= m2info->currcon_display->var.yres)		vblank->flags |= FB_VBLANK_VBLANKING;	return 0;}static int matroxfb_dh_ioctl(struct inode* inode,		struct file* file,		unsigned int cmd,		unsigned long arg,		int con,		struct fb_info* info) {#define m2info ((struct matroxfb_dh_fb_info*)info)	MINFO_FROM(m2info->primary_dev);	DBG("matroxfb_crtc2_ioctl")	switch (cmd) {		case FBIOGET_VBLANK:			{				struct fb_vblank vblank;				int err;				err = matroxfb_dh_get_vblank(m2info, &vblank);				if (err)					return err;				if (copy_to_user((struct fb_vblank*)arg, &vblank, sizeof(vblank)))					return -EFAULT;				return 0;			}		case MATROXFB_SET_OUTPUT_MODE:		case MATROXFB_GET_OUTPUT_MODE:		case MATROXFB_GET_ALL_OUTPUTS:			{				return ACCESS_FBINFO(fbcon.fbops)->fb_ioctl(inode, file, cmd, arg, con, &ACCESS_FBINFO(fbcon));			}		case MATROXFB_SET_OUTPUT_CONNECTION:			{				u_int32_t tmp;				if (get_user(tmp, (u_int32_t*)arg))					return -EFAULT;				if (tmp & ~ACCESS_FBINFO(output.all))					return -EINVAL;				if (tmp & ACCESS_FBINFO(output.ph))					return -EINVAL;				if (tmp & MATROXFB_OUTPUT_CONN_DFP)					return -EINVAL;				if ((ACCESS_FBINFO(output.ph) & MATROXFB_OUTPUT_CONN_DFP) && tmp)					return -EINVAL;				if (tmp == ACCESS_FBINFO(output.sh))					return 0;				ACCESS_FBINFO(output.sh) = tmp;				matroxfb_dh_switch(m2info->currcon, info);				return 0;			}		case MATROXFB_GET_OUTPUT_CONNECTION:			{				if (put_user(ACCESS_FBINFO(output.sh), (u_int32_t*)arg))					return -EFAULT;				return 0;			}		case MATROXFB_GET_AVAILABLE_OUTPUTS:			{				u_int32_t tmp;				/* we do not support DFP from CRTC2 */				tmp = ACCESS_FBINFO(output.all) & ~ACCESS_FBINFO(output.ph) & ~MATROXFB_OUTPUT_CONN_DFP;				/* CRTC1 in DFP mode disables CRTC2 at all (I know, I'm lazy) */				if (ACCESS_FBINFO(output.ph) & MATROXFB_OUTPUT_CONN_DFP)					tmp = 0;				if (put_user(tmp, (u_int32_t*)arg))					return -EFAULT;				return 0;			}	}	return -EINVAL;#undef m2info}static struct fb_ops matroxfb_dh_ops = {	owner:		THIS_MODULE,	fb_open:	matroxfb_dh_open,	fb_release:	matroxfb_dh_release,	fb_get_fix:	matroxfb_dh_get_fix,	fb_get_var:	matroxfb_dh_get_var,	fb_set_var:	matroxfb_dh_set_var,	fb_get_cmap:	matroxfb_dh_get_cmap,	fb_set_cmap:	matroxfb_dh_set_cmap,	fb_pan_display:	matroxfb_dh_pan_display,	fb_ioctl:	matroxfb_dh_ioctl,};static int matroxfb_dh_switch(int con, struct fb_info* info) {#define m2info ((struct matroxfb_dh_fb_info*)info)	struct fb_cmap* cmap;	struct display* p;	if (m2info->currcon >= 0) {		cmap = &m2info->currcon_display->cmap;		if (cmap->len) {			fb_get_cmap(cmap, 1, matroxfb_dh_getcolreg, info);		}	}	m2info->currcon = con;	if (con < 0)		p = m2info->fbcon.disp;	else		p = fb_display + con;	m2info->currcon_display = p;	p->var.activate = FB_ACTIVATE_NOW;	matroxfb_dh_set_var(&p->var, con, info);	return 0;#undef m2info}static int matroxfb_dh_updatevar(int con, struct fb_info* info) {#define m2info ((struct matroxfb_dh_fb_info*)info)	matroxfb_dh_pan_var(m2info, &fb_display[con].var);	return 0;#undef m2info}static void matroxfb_dh_blank(int blank, struct fb_info* info) {#define m2info ((struct matroxfb_dh_fb_info*)info)	switch (blank) {		case 1:		case 2:		case 3:		case 4:		default:;	}	/* do something... */#undef m2info}static struct fb_var_screeninfo matroxfb_dh_defined = {		640,480,640,480,/* W,H, virtual W,H */		0,0,		/* offset */		32,		/* depth */		0,		/* gray */		{0,0,0},	/* R */		{0,0,0},	/* G */		{0,0,0},	/* B */		{0,0,0},	/* alpha */		0,		/* nonstd */		FB_ACTIVATE_NOW,		-1,-1,		/* display size */		0,		/* accel flags */		39721L,48L,16L,33L,10L,		96L,2,0,	/* no sync info */		FB_VMODE_NONINTERLACED,		{0,0,0,0,0,0}};static int matroxfb_dh_regit(CPMINFO struct matroxfb_dh_fb_info* m2info) {#define minfo (m2info->primary_dev)	struct display* d;	void* oldcrtc2;	d = kmalloc(sizeof(*d), GFP_KERNEL);	if (!d) {		return -ENOMEM;	}	memset(d, 0, sizeof(*d));	strcpy(m2info->fbcon.modename, "MATROX CRTC2");	m2info->fbcon.changevar = NULL;	m2info->fbcon.node = -1;	m2info->fbcon.fbops = &matroxfb_dh_ops;	m2info->fbcon.disp = d;	m2info->fbcon.switch_con = &matroxfb_dh_switch;	m2info->fbcon.updatevar = &matroxfb_dh_updatevar;	m2info->fbcon.blank = &matroxfb_dh_blank;	m2info->fbcon.flags = FBINFO_FLAG_DEFAULT;	m2info->currcon = -1;	m2info->currcon_display = d;	if (mem < 64)		mem *= 1024;	if (mem < 64*1024)		mem *= 1024;	mem &= ~0x00000FFF;	/* PAGE_MASK? */	if (ACCESS_FBINFO(video.len_usable) + mem <= ACCESS_FBINFO(video.len))		m2info->video.offbase = ACCESS_FBINFO(video.len) - mem;	else if (ACCESS_FBINFO(video.len) < mem) {		kfree(d);		return -ENOMEM;	} else { /* check yres on first head... */		m2info->video.borrowed = mem;		ACCESS_FBINFO(video.len_usable) -= mem;		m2info->video.offbase = ACCESS_FBINFO(video.len_usable);	}	m2info->video.base = ACCESS_FBINFO(video.base) + m2info->video.offbase;	m2info->video.len = m2info->video.len_usable = m2info->video.len_maximum = mem;	m2info->video.vbase.vaddr = vaddr_va(ACCESS_FBINFO(video.vbase)) + m2info->video.offbase;	m2info->mmio.base = ACCESS_FBINFO(mmio.base);	m2info->mmio.vbase = ACCESS_FBINFO(mmio.vbase);	m2info->mmio.len = ACCESS_FBINFO(mmio.len);	/*	 *  If we have unused output, connect CRTC2 to it...	 */	if ((ACCESS_FBINFO(output.all) & MATROXFB_OUTPUT_CONN_SECONDARY) && 	   !(ACCESS_FBINFO(output.ph) & MATROXFB_OUTPUT_CONN_SECONDARY) &&	   !(ACCESS_FBINFO(output.ph) & MATROXFB_OUTPUT_CONN_DFP)) {		ACCESS_FBINFO(output.sh) |= MATROXFB_OUTPUT_CONN_SECONDARY;		ACCESS_FBINFO(output.sh) &= ~MATROXFB_OUTPUT_CONN_DFP;	}	matroxfb_dh_set_var(&matroxfb_dh_defined, -2, &m2info->fbcon);	if (register_framebuffer(&m2info->fbcon)) {		kfree(d);		return -ENXIO;	}	if (m2info->currcon < 0) {		matroxfb_dh_set_var(&matroxfb_dh_defined, -1, &m2info->fbcon);	}	down_write(&ACCESS_FBINFO(crtc2.lock));	oldcrtc2 = ACCESS_FBINFO(crtc2.info);	ACCESS_FBINFO(crtc2.info) = &m2info->fbcon;	up_write(&ACCESS_FBINFO(crtc2.lock));	if (oldcrtc2) {		printk(KERN_ERR "matroxfb_crtc2: Internal consistency check failed: crtc2 already present: %p\n",			oldcrtc2);	}	return 0;#undef minfo}/* ************************** */static int matroxfb_dh_registerfb(struct matroxfb_dh_fb_info* m2info) {#define minfo (m2info->primary_dev)	if (matroxfb_dh_regit(PMINFO m2info)) {		printk(KERN_ERR "matroxfb_crtc2: secondary head failed to register\n");		return -1;	}	printk(KERN_INFO "matroxfb_crtc2: secondary head of fb%u was registered as fb%u\n",		GET_FB_IDX(ACCESS_FBINFO(fbcon.node)), GET_FB_IDX(m2info->fbcon.node));	m2info->fbcon_registered = 1;	return 0;#undef minfo}static void matroxfb_dh_deregisterfb(struct matroxfb_dh_fb_info* m2info) {#define minfo (m2info->primary_dev)	if (m2info->fbcon_registered) {		int id;		struct fb_info* crtc2;		down_write(&ACCESS_FBINFO(crtc2.lock));		crtc2 = ACCESS_FBINFO(crtc2.info);		if (crtc2 == &m2info->fbcon)			ACCESS_FBINFO(crtc2.info) = NULL;		up_write(&ACCESS_FBINFO(crtc2.lock));		if (crtc2 != &m2info->fbcon) {			printk(KERN_ERR "matroxfb_crtc2: Internal consistency check failed: crtc2 mismatch at unload: %p != %p\n",				crtc2, &m2info->fbcon);			printk(KERN_ERR "matroxfb_crtc2: Expect kernel crash after module unload.\n");			return;		}		id = GET_FB_IDX(m2info->fbcon.node);		unregister_framebuffer(&m2info->fbcon);		kfree(m2info->fbcon.disp);		/* return memory back to primary head */		ACCESS_FBINFO(video.len_usable) += m2info->video.borrowed;		printk(KERN_INFO "matroxfb_crtc2: fb%u unregistered\n", id);		m2info->fbcon_registered = 0;	}#undef minfo}static void* matroxfb_crtc2_probe(struct matrox_fb_info* minfo) {	struct matroxfb_dh_fb_info* m2info;	/* hardware is CRTC2 incapable... */	if (!ACCESS_FBINFO(devflags.crtc2))		return NULL;	m2info = (struct matroxfb_dh_fb_info*)kmalloc(sizeof(*m2info), GFP_KERNEL);	if (!m2info) {		printk(KERN_ERR "matroxfb_crtc2: Not enough memory for CRTC2 control structs\n");		return NULL;	}	memset(m2info, 0, sizeof(*m2info));	m2info->primary_dev = MINFO;	if (matroxfb_dh_registerfb(m2info)) {		kfree(m2info);		printk(KERN_ERR "matroxfb_crtc2: CRTC2 framebuffer failed to register\n");		return NULL;	}	return m2info;}static void matroxfb_crtc2_remove(struct matrox_fb_info* minfo, void* crtc2) {	matroxfb_dh_deregisterfb(crtc2);}static struct matroxfb_driver crtc2 = {		name:	"Matrox G400 CRTC2",		probe:	matroxfb_crtc2_probe,		remove:	matroxfb_crtc2_remove };static int matroxfb_crtc2_init(void) {	matroxfb_register_driver(&crtc2);	return 0;}static void matroxfb_crtc2_exit(void) {	matroxfb_unregister_driver(&crtc2);}MODULE_AUTHOR("(c) 1999-2001 Petr Vandrovec <vandrove@vc.cvut.cz>");MODULE_DESCRIPTION("Matrox G400 CRTC2 driver");MODULE_LICENSE("GPL");module_init(matroxfb_crtc2_init);module_exit(matroxfb_crtc2_exit);/* we do not have __setup() yet */

⌨️ 快捷键说明

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