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

📄 fbdev.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 2 页
字号:
	switch (var->bits_per_pixel) {	case 16:		var->red.offset = 11;		var->red.length = 5;		var->green.offset = 5;		var->green.length = 6;		var->blue.length = 5;		break;	case 32:		var->transp.offset = 24;		var->red.offset = 16;		var->green.offset = 8;		var->blue.offset = 0;		var->red.length = 8;		var->green.length = 8;		var->blue.length = 8;		var->transp.length = 8;		break;	}	/* Height/Width of picture in mm */	var->height = var->width = -1;	/* Timing information. All values are in picoseconds */	/* par->PIXCLK is in 100Hz units. Convert to picoseconds -	 * ensuring we do not exceed 32 bit precision	 */	/*	 * XXX: Enabling this really screws over the pixclock value when we	 * read it back with fbset. As such, leaving this commented out appears	 * to do the right thing (at least for now) .. bearing in mind that we	 * have infact already done the KHZ2PICOS conversion in both the modedb	 * and kyro_var. -- PFM.	 *///	var->pixclock = 1000000000 / (par->PIXCLK / 10);	/* the header file claims we should use picoseconds	 * - nobody else does though, the all use pixels and lines	 * of h and v sizes. Both options here.	 */	/*	 * If we're being called by __fb_try_mode(), then we don't want to	 * override any of the var settings that we've already parsed	 * from our modedb. -- PFM.	 */	if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_TEST)		return 0;	var->left_margin = par->HBP;	var->hsync_len = par->HST;	var->right_margin = par->HFP;	var->upper_margin = par->VBP;	var->vsync_len = par->VST;	var->lower_margin = par->VFP;	if (par->HSP == 1)		var->sync |= FB_SYNC_HOR_HIGH_ACT;	if (par->VSP == 1)		var->sync |= FB_SYNC_VERT_HIGH_ACT;	return 0;}static int kyrofb_set_par(struct fb_info *info){	struct kyrofb_info *par = (struct kyrofb_info *)info->par;	unsigned long lineclock;	unsigned long frameclock;	/* Actual resolution */	par->XRES = info->var.xres;	par->YRES = info->var.yres;	/* pixel depth */	par->PIXDEPTH = info->var.bits_per_pixel;	/* Refresh rate */	/* time for a line in ns */	lineclock = (info->var.pixclock * (info->var.xres +				    info->var.right_margin +				    info->var.hsync_len +				    info->var.left_margin)) / 1000;	/* time for a frame in ns (precision in 32bpp) */	frameclock = lineclock * (info->var.yres +				  info->var.lower_margin +				  info->var.vsync_len +				  info->var.upper_margin);	/* Calculate refresh rate and horrizontal clocks */	par->VFREQ = (1000000000 + (frameclock / 2)) / frameclock;	par->HCLK = (1000000000 + (lineclock / 2)) / lineclock;	par->PIXCLK = ((1000000000 + (info->var.pixclock / 2))					/ info->var.pixclock) * 10;	/* calculate horizontal timings */	par->HFP = info->var.right_margin;	par->HST = info->var.hsync_len;	par->HBP = info->var.left_margin;	par->HTot = par->XRES + par->HBP + par->HST + par->HFP;	/* calculate vertical timings */	par->VFP = info->var.lower_margin;	par->VST = info->var.vsync_len;	par->VBP = info->var.upper_margin;	par->VTot = par->YRES + par->VBP + par->VST + par->VFP;	par->HSP = (info->var.sync & FB_SYNC_HOR_HIGH_ACT) ? 1 : 0;	par->VSP = (info->var.sync & FB_SYNC_VERT_HIGH_ACT) ? 1 : 0;	kyro_dev_video_mode_set(info);	/* length of a line in bytes    */	info->fix.line_length = get_line_length(par->XRES, par->PIXDEPTH);	info->fix.visual = FB_VISUAL_TRUECOLOR;	return 0;}static int kyrofb_setcolreg(u_int regno, u_int red, u_int green,			    u_int blue, u_int transp, struct fb_info *info){	if (regno > 255)		return 1;	/* Invalid register */	if (regno < 16) {		switch (info->var.bits_per_pixel) {		case 16:			((u16*)(info->pseudo_palette))[regno] =			     (red   & 0xf800) |			    ((green & 0xfc00) >> 5) |			    ((blue  & 0xf800) >> 11);			break;		case 32:			red >>= 8; green >>= 8; blue >>= 8; transp >>= 8;			((u32*)(info->pseudo_palette))[regno] =			    (transp << 24) | (red << 16) | (green << 8) | blue;			break;		}	}	return 0;}#ifndef MODULEstatic int __init kyrofb_setup(char *options){	char *this_opt;	if (!options || !*options)		return 0;	while ((this_opt = strsep(&options, ","))) {		if (!*this_opt)			continue;		if (strcmp(this_opt, "nopan") == 0) {			nopan = 1;		} else if (strcmp(this_opt, "nowrap") == 0) {			nowrap = 1;#ifdef CONFIG_MTRR		} else if (strcmp(this_opt, "nomtrr") == 0) {			nomtrr = 1;#endif		} else {			mode_option = this_opt;		}	}	return 0;}#endifstatic int kyrofb_ioctl(struct inode *inode, struct file *file,			unsigned int cmd, unsigned long arg,			struct fb_info *info){	overlay_create ol_create;	overlay_viewport_set ol_viewport_set;	void __user *argp = (void __user *)arg;	switch (cmd) {	case KYRO_IOCTL_OVERLAY_CREATE:		if (copy_from_user(&ol_create, argp, sizeof(overlay_create)))			return -EFAULT;		if (kyro_dev_overlay_create(ol_create.ulWidth,					    ol_create.ulHeight, 0) < 0) {			printk(KERN_ERR "Kyro FB: failed to create overlay surface.\n");			return -EINVAL;		}		break;	case KYRO_IOCTL_OVERLAY_VIEWPORT_SET:		if (copy_from_user(&ol_viewport_set, argp,			       sizeof(overlay_viewport_set)))			return -EFAULT;		if (kyro_dev_overlay_viewport_set(ol_viewport_set.xOrgin,						  ol_viewport_set.yOrgin,						  ol_viewport_set.xSize,						  ol_viewport_set.ySize) != 0)		{			printk(KERN_ERR "Kyro FB: failed to create overlay viewport.\n");			return -EINVAL;		}		break;	case KYRO_IOCTL_SET_VIDEO_MODE:		{			printk(KERN_ERR "Kyro FB: KYRO_IOCTL_SET_VIDEO_MODE is"				"obsolete, use the appropriate fb_ioctl()"				"command instead.\n");			return -EINVAL;		}		break;	case KYRO_IOCTL_UVSTRIDE:		if (copy_to_user(argp, &deviceInfo.ulOverlayUVStride, sizeof(unsigned long)))			return -EFAULT;		break;	case KYRO_IOCTL_STRIDE:		if (copy_to_user(argp, &deviceInfo.ulOverlayStride, sizeof(unsigned long)))			return -EFAULT;		break;	case KYRO_IOCTL_OVERLAY_OFFSET:		if (copy_to_user(argp, &deviceInfo.ulOverlayOffset, sizeof(unsigned long)))			return -EFAULT;		break;	}	return 0;}static struct pci_device_id kyrofb_pci_tbl[] = {	{ PCI_VENDOR_ID_ST, PCI_DEVICE_ID_STG4000,	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },	{ 0, }};MODULE_DEVICE_TABLE(pci, kyrofb_pci_tbl);static struct pci_driver kyrofb_pci_driver = {	.name		= "kyrofb",	.id_table	= kyrofb_pci_tbl,	.probe		= kyrofb_probe,	.remove		= __devexit_p(kyrofb_remove),};static struct fb_ops kyrofb_ops = {	.owner		= THIS_MODULE,	.fb_check_var	= kyrofb_check_var,	.fb_set_par	= kyrofb_set_par,	.fb_setcolreg	= kyrofb_setcolreg,	.fb_ioctl	= kyrofb_ioctl,	.fb_fillrect	= cfb_fillrect,	.fb_copyarea	= cfb_copyarea,	.fb_imageblit	= cfb_imageblit,};static int __devinit kyrofb_probe(struct pci_dev *pdev,				  const struct pci_device_id *ent){	struct fb_info *info;	unsigned long size;	int err;	if ((err = pci_enable_device(pdev))) {		printk(KERN_WARNING "kyrofb: Can't enable pdev: %d\n", err);		return err;	}	size = sizeof(struct fb_info) + sizeof(struct kyrofb_info) + 16 * sizeof(u32);	info = kmalloc(size, GFP_KERNEL);	if (!info)		return -ENOMEM;	memset(info, 0, size);	currentpar = (struct kyrofb_info *)(info + 1);	kyro_fix.smem_start = pci_resource_start(pdev, 0);	kyro_fix.smem_len   = pci_resource_len(pdev, 0);	kyro_fix.mmio_start = pci_resource_start(pdev, 1);	kyro_fix.mmio_len   = pci_resource_len(pdev, 1);	currentpar->regbase = deviceInfo.pSTGReg =		ioremap_nocache(kyro_fix.mmio_start, kyro_fix.mmio_len);	info->screen_base = ioremap_nocache(kyro_fix.smem_start,					    kyro_fix.smem_len);#ifdef CONFIG_MTRR	if (!nomtrr)		currentpar->mtrr_handle =			mtrr_add(kyro_fix.smem_start,				 kyro_fix.smem_len,				 MTRR_TYPE_WRCOMB, 1);#endif	kyro_fix.ypanstep	= nopan ? 0 : 1;	kyro_fix.ywrapstep	= nowrap ? 0 : 1;	info->fbops		= &kyrofb_ops;	info->fix		= kyro_fix;	info->par		= currentpar;	info->pseudo_palette	= (void *)(currentpar + 1);	info->flags		= FBINFO_DEFAULT;	SetCoreClockPLL(deviceInfo.pSTGReg, pdev);	deviceInfo.ulNextFreeVidMem = 0;	deviceInfo.ulOverlayOffset = 0;	/* This should give a reasonable default video mode */	if (!fb_find_mode(&info->var, info, mode_option, kyro_modedb,			  NUM_TOTAL_MODES, &kyro_modedb[VMODE_1024_768_75], 32))		info->var = kyro_var;	fb_alloc_cmap(&info->cmap, 256, 0);	kyrofb_set_par(info);	kyrofb_check_var(&info->var, info);	size = get_line_length(info->var.xres_virtual,			       info->var.bits_per_pixel);	size *= info->var.yres_virtual;	fb_memset(info->screen_base, 0, size);	info->device = &pdev->dev;	if (register_framebuffer(info) < 0)		goto out_unmap;	printk("fb%d: %s frame buffer device, at %dx%d@%d using %ldk/%ldk of VRAM\n",	       info->node, info->fix.id, info->var.xres,	       info->var.yres, info->var.bits_per_pixel, size >> 10,	       (unsigned long)info->fix.smem_len >> 10);	pci_set_drvdata(pdev, info);	return 0;out_unmap:	iounmap(currentpar->regbase);	iounmap(info->screen_base);	kfree(info);	return -EINVAL;}static void __devexit kyrofb_remove(struct pci_dev *pdev){	struct fb_info *info = pci_get_drvdata(pdev);	struct kyrofb_info *par = (struct kyrofb_info *)info->par;	/* Reset the board */	StopVTG(deviceInfo.pSTGReg);	DisableRamdacOutput(deviceInfo.pSTGReg);	/* Sync up the PLL */	SetCoreClockPLL(deviceInfo.pSTGReg, pdev);	deviceInfo.ulNextFreeVidMem = 0;	deviceInfo.ulOverlayOffset = 0;	iounmap(info->screen_base);	iounmap(par->regbase);#ifdef CONFIG_MTRR	if (par->mtrr_handle)		mtrr_del(par->mtrr_handle,			 info->fix.smem_start,			 info->fix.smem_len);#endif	unregister_framebuffer(info);	pci_set_drvdata(pdev, NULL);	kfree(info);}static int __init kyrofb_init(void){#ifndef MODULE	char *option = NULL;	if (fb_get_options("kyrofb", &option))		return -ENODEV;	kyrofb_setup(option);#endif	return pci_register_driver(&kyrofb_pci_driver);}static void __exit kyrofb_exit(void){	pci_unregister_driver(&kyrofb_pci_driver);}module_init(kyrofb_init);#ifdef MODULEmodule_exit(kyrofb_exit);#endifMODULE_AUTHOR("STMicroelectronics; Paul Mundt <lethal@linux-sh.org>");MODULE_LICENSE("GPL");

⌨️ 快捷键说明

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