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

📄 tmiofb.c

📁 Linux环境下视频显示卡设备的驱动程序源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
	case FBIO_TMIO_ACC_SYNC:		tmiofb_sync(fbi);		return 0;	case FBIO_TMIO_ACC_WRITE: {		u32 __user *argp = (void __user *) arg;		u32 len;		u32 acc[16];		if (get_user(len, argp))			return -EFAULT;		if (len > ARRAY_SIZE(acc))			return -EINVAL;		if (copy_from_user(acc, argp + 1, sizeof(u32) * len))			return -EFAULT;		return tmiofb_acc_write(fbi, acc, len);	}#endif	}	return -ENOTTY;}/*--------------------------------------------------------------------------*//* Select the smallest mode that allows the desired resolution to be * displayed.  If desired, the x and y parameters can be rounded up to * match the selected mode. */static struct fb_videomode *tmiofb_find_mode(struct fb_info *info, struct fb_var_screeninfo *var){	struct mfd_cell *cell =		info->device->platform_data;	struct tmio_fb_data *data = cell->driver_data;	struct fb_videomode *best = NULL;	int i;	for (i = 0; i < data->num_modes; i++) {		struct fb_videomode *mode = data->modes + i;		if (mode->xres >= var->xres && mode->yres >= var->yres				&& (!best || (mode->xres < best->xres					   && mode->yres < best->yres)))			best = mode;	}	return best;}static int tmiofb_check_var(struct fb_var_screeninfo *var, struct fb_info *info){	struct fb_videomode *mode;	struct mfd_cell *cell =		info->device->platform_data;	struct tmio_fb_data *data = cell->driver_data;	mode = tmiofb_find_mode(info, var);	if (!mode || var->bits_per_pixel > 16)		return -EINVAL;	fb_videomode_to_var(var, mode);	var->xres_virtual = mode->xres;	var->yres_virtual = info->screen_size / (mode->xres * 2);	if (var->yres_virtual < var->yres)		return -EINVAL;	var->xoffset = 0;	var->yoffset = 0;	var->bits_per_pixel = 16;	var->grayscale = 0;	var->red.offset = 11;	var->red.length = 5;	var->green.offset = 5;	var->green.length = 6;	var->blue.offset = 0;	var->blue.length = 5;	var->transp.offset = 0;	var->transp.length = 0;	var->nonstd = 0;	var->height = data->height; /* mm */	var->width = data->width; /* mm */	var->rotate = 0;	return 0;}static int tmiofb_set_par(struct fb_info *info){	struct fb_var_screeninfo *var = &info->var;	struct fb_videomode *mode;	mode = tmiofb_find_mode(info, var);	if (!mode)		return -EINVAL;	info->mode = mode;	info->fix.line_length = info->mode->xres *			var->bits_per_pixel / 8;	tmiofb_hw_mode(to_platform_device(info->device));	tmiofb_clearscreen(info);	return 0;}static int tmiofb_setcolreg(unsigned regno, unsigned red, unsigned green,			   unsigned blue, unsigned transp,			   struct fb_info *info){	struct tmiofb_par *par = info->par;	if (regno < ARRAY_SIZE(par->pseudo_palette)) {		par->pseudo_palette[regno] =			((red & 0xf800)) |			((green & 0xfc00) >>  5) |			((blue & 0xf800) >> 11);		return 0;	}	return -EINVAL;}static int tmiofb_blank(int blank, struct fb_info *info){	/*	 * everything is done in lcd/bl drivers.	 * this is purely to make sysfs happy and work.	 */	return 0;}static struct fb_ops tmiofb_ops = {	.owner		= THIS_MODULE,	.fb_ioctl	= tmiofb_ioctl,	.fb_check_var	= tmiofb_check_var,	.fb_set_par	= tmiofb_set_par,	.fb_setcolreg	= tmiofb_setcolreg,	.fb_blank	= tmiofb_blank,	.fb_imageblit	= cfb_imageblit,#ifdef CONFIG_FB_TMIO_ACCELL	.fb_sync	= tmiofb_sync,	.fb_fillrect	= tmiofb_fillrect,	.fb_copyarea	= tmiofb_copyarea,#else	.fb_fillrect	= cfb_fillrect,	.fb_copyarea	= cfb_copyarea,#endif};/*--------------------------------------------------------------------------*/static int __devinit tmiofb_probe(struct platform_device *dev){	struct mfd_cell *cell = dev->dev.platform_data;	struct tmio_fb_data *data = cell->driver_data;	struct resource *ccr = platform_get_resource(dev, IORESOURCE_MEM, 1);	struct resource *lcr = platform_get_resource(dev, IORESOURCE_MEM, 0);	struct resource *vram = platform_get_resource(dev, IORESOURCE_MEM, 2);	int irq = platform_get_irq(dev, 0);	struct fb_info *info;	struct tmiofb_par *par;	int retval;	/*	 * This is the only way ATM to disable the fb	 */	if (data == NULL) {		dev_err(&dev->dev, "NULL platform data!\n");		return -EINVAL;	}	info = framebuffer_alloc(sizeof(struct tmiofb_par), &dev->dev);	if (!info)		return -ENOMEM;	par = info->par;#ifdef CONFIG_FB_TMIO_ACCELL	init_waitqueue_head(&par->wait_acc);	par->use_polling = true;	info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_COPYAREA			| FBINFO_HWACCEL_FILLRECT;#else	info->flags = FBINFO_DEFAULT;#endif	info->fbops = &tmiofb_ops;	strcpy(info->fix.id, "tmio-fb");	info->fix.smem_start = vram->start;	info->fix.smem_len = resource_size(vram);	info->fix.type = FB_TYPE_PACKED_PIXELS;	info->fix.visual = FB_VISUAL_TRUECOLOR;	info->fix.mmio_start = lcr->start;	info->fix.mmio_len = resource_size(lcr);	info->fix.accel = FB_ACCEL_NONE;	info->screen_size = info->fix.smem_len - (4 * TMIOFB_FIFO_SIZE);	info->pseudo_palette = par->pseudo_palette;	par->ccr = ioremap(ccr->start, resource_size(ccr));	if (!par->ccr) {		retval = -ENOMEM;		goto err_ioremap_ccr;	}	par->lcr = ioremap(info->fix.mmio_start, info->fix.mmio_len);	if (!par->lcr) {		retval = -ENOMEM;		goto err_ioremap_lcr;	}	info->screen_base = ioremap(info->fix.smem_start, info->fix.smem_len);	if (!info->screen_base) {		retval = -ENOMEM;		goto err_ioremap_vram;	}	retval = request_irq(irq, &tmiofb_irq, IRQF_DISABLED,					dev->dev.bus_id, info);	if (retval)		goto err_request_irq;	platform_set_drvdata(dev, info);	retval = fb_find_mode(&info->var, info, mode_option,			data->modes, data->num_modes,			data->modes, 16);	if (!retval) {		retval = -EINVAL;		goto err_find_mode;	}	if (cell->enable) {		retval = cell->enable(dev);		if (retval)			goto err_enable;	}	retval = tmiofb_hw_init(dev);	if (retval)		goto err_hw_init;	fb_videomode_to_modelist(data->modes, data->num_modes,				 &info->modelist);	retval = register_framebuffer(info);	if (retval < 0)		goto err_register_framebuffer;	printk(KERN_INFO "fb%d: %s frame buffer device\n",				info->node, info->fix.id);	return 0;err_register_framebuffer:/*err_set_par:*/	tmiofb_hw_stop(dev);err_hw_init:	if (cell->disable)		cell->disable(dev);err_enable:err_find_mode:	platform_set_drvdata(dev, NULL);	free_irq(irq, info);err_request_irq:	iounmap(info->screen_base);err_ioremap_vram:	iounmap(par->lcr);err_ioremap_lcr:	iounmap(par->ccr);err_ioremap_ccr:	framebuffer_release(info);	return retval;}static int __devexit tmiofb_remove(struct platform_device *dev){	struct mfd_cell *cell = dev->dev.platform_data;	struct fb_info *info = platform_get_drvdata(dev);	int irq = platform_get_irq(dev, 0);	struct tmiofb_par *par;	if (info) {		par = info->par;		unregister_framebuffer(info);		tmiofb_hw_stop(dev);		if (cell->disable)			cell->disable(dev);		platform_set_drvdata(dev, NULL);		free_irq(irq, info);		iounmap(info->screen_base);		iounmap(par->lcr);		iounmap(par->ccr);		framebuffer_release(info);	}	return 0;}#ifdef DEBUGstatic void tmiofb_dump_regs(struct platform_device *dev){	struct fb_info *info = platform_get_drvdata(dev);	struct tmiofb_par *par = info->par;	printk(KERN_DEBUG "lhccr:\n");#define CCR_PR(n)	printk(KERN_DEBUG "\t" #n " = \t%04x\n",\		tmio_ioread16(par->ccr + CCR_ ## n));	CCR_PR(CMD);	CCR_PR(REVID);	CCR_PR(BASEL);	CCR_PR(BASEH);	CCR_PR(UGCC);	CCR_PR(GCC);	CCR_PR(USC);	CCR_PR(VRAMRTC);	CCR_PR(VRAMSAC);	CCR_PR(VRAMBC);#undef CCR_PR	printk(KERN_DEBUG "lcr: \n");#define LCR_PR(n)	printk(KERN_DEBUG "\t" #n " = \t%04x\n",\		tmio_ioread16(par->lcr + LCR_ ## n));	LCR_PR(UIS);	LCR_PR(VHPN);	LCR_PR(CFSAL);	LCR_PR(CFSAH);	LCR_PR(CFS);	LCR_PR(CFWS);	LCR_PR(BBIE);	LCR_PR(BBISC);	LCR_PR(CCS);	LCR_PR(BBES);	LCR_PR(CMDL);	LCR_PR(CMDH);	LCR_PR(CFC);	LCR_PR(CCIFC);	LCR_PR(HWT);	LCR_PR(LCDCCRC);	LCR_PR(LCDCC);	LCR_PR(LCDCOPC);	LCR_PR(LCDIS);	LCR_PR(LCDIM);	LCR_PR(LCDIE);	LCR_PR(GDSAL);	LCR_PR(GDSAH);	LCR_PR(VHPCL);	LCR_PR(VHPCH);	LCR_PR(GM);	LCR_PR(HT);	LCR_PR(HDS);	LCR_PR(HSS);	LCR_PR(HSE);	LCR_PR(HNP);	LCR_PR(VT);	LCR_PR(VDS);	LCR_PR(VSS);	LCR_PR(VSE);	LCR_PR(CDLN);	LCR_PR(ILN);	LCR_PR(SP);	LCR_PR(MISC);	LCR_PR(VIHSS);	LCR_PR(VIVS);	LCR_PR(VIVE);	LCR_PR(VIVSS);	LCR_PR(VCCIS);	LCR_PR(VIDWSAL);	LCR_PR(VIDWSAH);	LCR_PR(VIDRSAL);	LCR_PR(VIDRSAH);	LCR_PR(VIPDDST);	LCR_PR(VIPDDET);	LCR_PR(VIE);	LCR_PR(VCS);	LCR_PR(VPHWC);	LCR_PR(VPHS);	LCR_PR(VPVWC);	LCR_PR(VPVS);	LCR_PR(PLHPIX);	LCR_PR(XS);	LCR_PR(XCKHW);	LCR_PR(STHS);	LCR_PR(VT2);	LCR_PR(YCKSW);	LCR_PR(YSTS);	LCR_PR(PPOLS);	LCR_PR(PRECW);	LCR_PR(VCLKHW);	LCR_PR(OC);#undef LCR_PR}#endif#ifdef CONFIG_PMstatic int tmiofb_suspend(struct platform_device *dev, pm_message_t state){	struct fb_info *info = platform_get_drvdata(dev);#ifdef CONFIG_FB_TMIO_ACCELL	struct tmiofb_par *par = info->par;#endif	struct mfd_cell *cell = dev->dev.platform_data;	int retval = 0;	acquire_console_sem();	fb_set_suspend(info, 1);	if (info->fbops->fb_sync)		info->fbops->fb_sync(info);#ifdef CONFIG_FB_TMIO_ACCELL	/*	 * The fb should be usable even if interrupts are disabled (and they are	 * during suspend/resume). Switch temporary to forced polling.	 */	printk(KERN_INFO "tmiofb: switching to polling\n");	par->use_polling = true;#endif	tmiofb_hw_stop(dev);	if (cell->suspend)		retval = cell->suspend(dev);	release_console_sem();	return retval;}static int tmiofb_resume(struct platform_device *dev){	struct fb_info *info = platform_get_drvdata(dev);	struct mfd_cell *cell = dev->dev.platform_data;	int retval;	acquire_console_sem();	if (cell->resume) {		retval = cell->resume(dev);		if (retval)			goto out;	}	tmiofb_irq(-1, info);	tmiofb_hw_init(dev);	tmiofb_hw_mode(dev);	fb_set_suspend(info, 0);out:	release_console_sem();	return retval;}#else#define tmiofb_suspend	NULL#define tmiofb_resume	NULL#endifstatic struct platform_driver tmiofb_driver = {	.driver.name	= "tmio-fb",	.driver.owner	= THIS_MODULE,	.probe		= tmiofb_probe,	.remove		= __devexit_p(tmiofb_remove),	.suspend	= tmiofb_suspend,	.resume		= tmiofb_resume,};/*--------------------------------------------------------------------------*/#ifndef MODULEstatic void __init tmiofb_setup(char *options){	char *this_opt;	if (!options || !*options)		return;	while ((this_opt = strsep(&options, ",")) != NULL) {		if (!*this_opt)			continue;		/*		 * FIXME		 */	}}#endifstatic int __init tmiofb_init(void){#ifndef MODULE	char *option = NULL;	if (fb_get_options("tmiofb", &option))		return -ENODEV;	tmiofb_setup(option);#endif	return platform_driver_register(&tmiofb_driver);}static void __exit tmiofb_cleanup(void){	platform_driver_unregister(&tmiofb_driver);}module_init(tmiofb_init);module_exit(tmiofb_cleanup);MODULE_DESCRIPTION("TMIO framebuffer driver");MODULE_AUTHOR("Chris Humbert, Dirk Opfer, Dmitry Baryshkov");MODULE_LICENSE("GPL");

⌨️ 快捷键说明

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