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

📄 arcfb.c

📁 Linux环境下视频显示卡设备的驱动程序源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
	}}/* * here we start the process of spliting out the fb update into * individual blocks of pixels. we end up spliting into 64x64 blocks * and finally down to 64x8 pages. */static void arcfb_lcd_update(struct arcfb_par *par, unsigned int dx,			unsigned int dy, unsigned int w, unsigned int h){	unsigned int left, right, distance, y;	/* align the request first */	y = floor8(dy);	h += dy - y;	h = iceil8(h);	distance = w;	left = dx;	right = min(left + w - 1, ceil64(left));	while (distance > 0) {		arcfb_lcd_update_horiz(par, left, right, y, h);		distance -= ((right - left) + 1);		left = right + 1;		right = min(left + distance - 1, ceil64(left));	}}static void arcfb_fillrect(struct fb_info *info,			   const struct fb_fillrect *rect){	struct arcfb_par *par = info->par;	sys_fillrect(info, rect);	/* update the physical lcd */	arcfb_lcd_update(par, rect->dx, rect->dy, rect->width, rect->height);}static void arcfb_copyarea(struct fb_info *info,			   const struct fb_copyarea *area){	struct arcfb_par *par = info->par;	sys_copyarea(info, area);	/* update the physical lcd */	arcfb_lcd_update(par, area->dx, area->dy, area->width, area->height);}static void arcfb_imageblit(struct fb_info *info, const struct fb_image *image){	struct arcfb_par *par = info->par;	sys_imageblit(info, image);	/* update the physical lcd */	arcfb_lcd_update(par, image->dx, image->dy, image->width,				image->height);}static int arcfb_ioctl(struct fb_info *info,			  unsigned int cmd, unsigned long arg){	void __user *argp = (void __user *)arg;	struct arcfb_par *par = info->par;	unsigned long flags;	switch (cmd) {		case FBIO_WAITEVENT:		{			DEFINE_WAIT(wait);			/* illegal to wait on arc if no irq will occur */			if (!par->irq)				return -EINVAL;			/* wait until the Arc has generated an interrupt			 * which will wake us up */			spin_lock_irqsave(&par->lock, flags);			prepare_to_wait(&arcfb_waitq, &wait,					TASK_INTERRUPTIBLE);			spin_unlock_irqrestore(&par->lock, flags);			schedule();			finish_wait(&arcfb_waitq, &wait);		}		case FBIO_GETCONTROL2:		{			unsigned char ctl2;			ctl2 = ks108_readb_ctl2(info->par);			if (copy_to_user(argp, &ctl2, sizeof(ctl2)))				return -EFAULT;			return 0;		}		default:			return -EINVAL;	}}/* * this is the access path from userspace. they can seek and write to * the fb. it's inefficient for them to do anything less than 64*8 * writes since we update the lcd in each write() anyway. */static ssize_t arcfb_write(struct fb_info *info, const char __user *buf,			   size_t count, loff_t *ppos){	/* modded from epson 1355 */	unsigned long p;	int err=-EINVAL;	unsigned int fbmemlength,x,y,w,h, bitppos, startpos, endpos, bitcount;	struct arcfb_par *par;	unsigned int xres;	p = *ppos;	par = info->par;	xres = info->var.xres;	fbmemlength = (xres * info->var.yres)/8;	if (p > fbmemlength)		return -ENOSPC;	err = 0;	if ((count + p) > fbmemlength) {		count = fbmemlength - p;		err = -ENOSPC;	}	if (count) {		char *base_addr;		base_addr = (char __force *)info->screen_base;		count -= copy_from_user(base_addr + p, buf, count);		*ppos += count;		err = -EFAULT;	}	bitppos = p*8;	startpos = floorXres(bitppos, xres);	endpos = ceilXres((bitppos + (count*8)), xres);	bitcount = endpos - startpos;	x = startpos % xres;	y = startpos / xres;	w = xres;	h = bitcount / xres;	arcfb_lcd_update(par, x, y, w, h);	if (count)		return count;	return err;}static struct fb_ops arcfb_ops = {	.owner		= THIS_MODULE,	.fb_open	= arcfb_open,	.fb_read        = fb_sys_read,	.fb_write	= arcfb_write,	.fb_release	= arcfb_release,	.fb_pan_display	= arcfb_pan_display,	.fb_fillrect	= arcfb_fillrect,	.fb_copyarea	= arcfb_copyarea,	.fb_imageblit	= arcfb_imageblit,	.fb_ioctl 	= arcfb_ioctl,};static int __init arcfb_probe(struct platform_device *dev){	struct fb_info *info;	int retval = -ENOMEM;	int videomemorysize;	unsigned char *videomemory;	struct arcfb_par *par;	int i;	videomemorysize = (((64*64)*num_cols)*num_rows)/8;	/* We need a flat backing store for the Arc's	   less-flat actual paged framebuffer */	if (!(videomemory = vmalloc(videomemorysize)))		return retval;	memset(videomemory, 0, videomemorysize);	info = framebuffer_alloc(sizeof(struct arcfb_par), &dev->dev);	if (!info)		goto err;	info->screen_base = (char __iomem *)videomemory;	info->fbops = &arcfb_ops;	info->var = arcfb_var;	info->fix = arcfb_fix;	par = info->par;	par->info = info;	if (!dio_addr || !cio_addr || !c2io_addr) {		printk(KERN_WARNING "no IO addresses supplied\n");		goto err1;	}	par->dio_addr = dio_addr;	par->cio_addr = cio_addr;	par->c2io_addr = c2io_addr;	par->cslut[0] = 0x00;	par->cslut[1] = 0x06;	info->flags = FBINFO_FLAG_DEFAULT;	spin_lock_init(&par->lock);	retval = register_framebuffer(info);	if (retval < 0)		goto err1;	platform_set_drvdata(dev, info);	if (irq) {		par->irq = irq;		if (request_irq(par->irq, &arcfb_interrupt, IRQF_SHARED,				"arcfb", info)) {			printk(KERN_INFO				"arcfb: Failed req IRQ %d\n", par->irq);			goto err1;		}	}	printk(KERN_INFO	       "fb%d: Arc frame buffer device, using %dK of video memory\n",	       info->node, videomemorysize >> 10);	/* this inits the lcd but doesn't clear dirty pixels */	for (i = 0; i < num_cols * num_rows; i++) {		ks108_writeb_ctl(par, i, KS_DPY_OFF);		ks108_set_start_line(par, i, 0);		ks108_set_yaddr(par, i, 0);		ks108_set_xaddr(par, i, 0);		ks108_writeb_ctl(par, i, KS_DPY_ON);	}	/* if we were told to splash the screen, we just clear it */	if (!nosplash) {		for (i = 0; i < num_cols * num_rows; i++) {			printk(KERN_INFO "fb%d: splashing lcd %d\n",				info->node, i);			ks108_set_start_line(par, i, 0);			ks108_clear_lcd(par, i);		}	}	return 0;err1:	framebuffer_release(info);err:	vfree(videomemory);	return retval;}static int arcfb_remove(struct platform_device *dev){	struct fb_info *info = platform_get_drvdata(dev);	if (info) {		unregister_framebuffer(info);		vfree((void __force *)info->screen_base);		framebuffer_release(info);	}	return 0;}static struct platform_driver arcfb_driver = {	.probe	= arcfb_probe,	.remove = arcfb_remove,	.driver	= {		.name	= "arcfb",	},};static struct platform_device *arcfb_device;static int __init arcfb_init(void){	int ret;	if (!arcfb_enable)		return -ENXIO;	ret = platform_driver_register(&arcfb_driver);	if (!ret) {		arcfb_device = platform_device_alloc("arcfb", 0);		if (arcfb_device) {			ret = platform_device_add(arcfb_device);		} else {			ret = -ENOMEM;		}		if (ret) {			platform_device_put(arcfb_device);			platform_driver_unregister(&arcfb_driver);		}	}	return ret;}static void __exit arcfb_exit(void){	platform_device_unregister(arcfb_device);	platform_driver_unregister(&arcfb_driver);}module_param(num_cols, ulong, 0);MODULE_PARM_DESC(num_cols, "Num horiz panels, eg: 2 = 128 bit wide");module_param(num_rows, ulong, 0);MODULE_PARM_DESC(num_rows, "Num vert panels, eg: 1 = 64 bit high");module_param(nosplash, uint, 0);MODULE_PARM_DESC(nosplash, "Disable doing the splash screen");module_param(arcfb_enable, uint, 0);MODULE_PARM_DESC(arcfb_enable, "Enable communication with Arc board");module_param(dio_addr, ulong, 0);MODULE_PARM_DESC(dio_addr, "IO address for data, eg: 0x480");module_param(cio_addr, ulong, 0);MODULE_PARM_DESC(cio_addr, "IO address for control, eg: 0x400");module_param(c2io_addr, ulong, 0);MODULE_PARM_DESC(c2io_addr, "IO address for secondary control, eg: 0x408");module_param(splashval, ulong, 0);MODULE_PARM_DESC(splashval, "Splash pattern: 0xFF is black, 0x00 is green");module_param(tuhold, ulong, 0);MODULE_PARM_DESC(tuhold, "Time to hold between strobing data to Arc board");module_param(irq, uint, 0);MODULE_PARM_DESC(irq, "IRQ for the Arc board");module_init(arcfb_init);module_exit(arcfb_exit);MODULE_DESCRIPTION("fbdev driver for Arc monochrome LCD board");MODULE_AUTHOR("Jaya Kumar");MODULE_LICENSE("GPL");

⌨️ 快捷键说明

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