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

📄 sunxvr2500.c

📁 Linux环境下视频显示卡设备的驱动程序源代码
💻 C
字号:
/* s3d.c: Sun 3DLABS XVR-2500 et al. driver for sparc64 systems * * Copyright (C) 2007 David S. Miller (davem@davemloft.net) */#include <linux/module.h>#include <linux/kernel.h>#include <linux/slab.h>#include <linux/fb.h>#include <linux/pci.h>#include <linux/init.h>#include <linux/of_device.h>#include <asm/io.h>struct s3d_info {	struct fb_info		*info;	struct pci_dev		*pdev;	char __iomem		*fb_base;	unsigned long		fb_base_phys;	struct device_node	*of_node;	unsigned int		width;	unsigned int		height;	unsigned int		depth;	unsigned int		fb_size;	u32			pseudo_palette[16];};static int __devinit s3d_get_props(struct s3d_info *sp){	sp->width = of_getintprop_default(sp->of_node, "width", 0);	sp->height = of_getintprop_default(sp->of_node, "height", 0);	sp->depth = of_getintprop_default(sp->of_node, "depth", 8);	if (!sp->width || !sp->height) {		printk(KERN_ERR "s3d: Critical properties missing for %s\n",		       pci_name(sp->pdev));		return -EINVAL;	}	return 0;}static int s3d_setcolreg(unsigned regno,			 unsigned red, unsigned green, unsigned blue,			 unsigned transp, struct fb_info *info){	u32 value;	if (regno < 16) {		red >>= 8;		green >>= 8;		blue >>= 8;		value = (blue << 24) | (green << 16) | (red << 8);		((u32 *)info->pseudo_palette)[regno] = value;	}	return 0;}static struct fb_ops s3d_ops = {	.owner			= THIS_MODULE,	.fb_setcolreg		= s3d_setcolreg,	.fb_fillrect		= cfb_fillrect,	.fb_copyarea		= cfb_copyarea,	.fb_imageblit		= cfb_imageblit,};static int __devinit s3d_set_fbinfo(struct s3d_info *sp){	struct fb_info *info = sp->info;	struct fb_var_screeninfo *var = &info->var;	info->flags = FBINFO_DEFAULT;	info->fbops = &s3d_ops;	info->screen_base = sp->fb_base;	info->screen_size = sp->fb_size;	info->pseudo_palette = sp->pseudo_palette;	/* Fill fix common fields */	strlcpy(info->fix.id, "s3d", sizeof(info->fix.id));        info->fix.smem_start = sp->fb_base_phys;        info->fix.smem_len = sp->fb_size;        info->fix.type = FB_TYPE_PACKED_PIXELS;	if (sp->depth == 32 || sp->depth == 24)		info->fix.visual = FB_VISUAL_TRUECOLOR;	else		info->fix.visual = FB_VISUAL_PSEUDOCOLOR;	var->xres = sp->width;	var->yres = sp->height;	var->xres_virtual = var->xres;	var->yres_virtual = var->yres;	var->bits_per_pixel = sp->depth;	var->red.offset = 8;	var->red.length = 8;	var->green.offset = 16;	var->green.length = 8;	var->blue.offset = 24;	var->blue.length = 8;	var->transp.offset = 0;	var->transp.length = 0;	if (fb_alloc_cmap(&info->cmap, 256, 0)) {		printk(KERN_ERR "s3d: Cannot allocate color map.\n");		return -ENOMEM;	}        return 0;}static int __devinit s3d_pci_register(struct pci_dev *pdev,				      const struct pci_device_id *ent){	struct fb_info *info;	struct s3d_info *sp;	int err;	err = pci_enable_device(pdev);	if (err < 0) {		printk(KERN_ERR "s3d: Cannot enable PCI device %s\n",		       pci_name(pdev));		goto err_out;	}	info = framebuffer_alloc(sizeof(struct s3d_info), &pdev->dev);	if (!info) {		printk(KERN_ERR "s3d: Cannot allocate fb_info\n");		err = -ENOMEM;		goto err_disable;	}	sp = info->par;	sp->info = info;	sp->pdev = pdev;	sp->of_node = pci_device_to_OF_node(pdev);	if (!sp->of_node) {		printk(KERN_ERR "s3d: Cannot find OF node of %s\n",		       pci_name(pdev));		err = -ENODEV;		goto err_release_fb;	}	sp->fb_base_phys = pci_resource_start (pdev, 1);	err = pci_request_region(pdev, 1, "s3d framebuffer");	if (err < 0) {		printk("s3d: Cannot request region 1 for %s\n",		       pci_name(pdev));		goto err_release_fb;	}	err = s3d_get_props(sp);	if (err)		goto err_release_pci;	/* XXX 'linebytes' is often wrong, it is equal to the width	 * XXX with depth of 32 on my XVR-2500 which is clearly not	 * XXX right.  So we don't try to use it.	 */	switch (sp->depth) {	case 8:		info->fix.line_length = sp->width;		break;	case 16:		info->fix.line_length = sp->width * 2;		break;	case 24:		info->fix.line_length = sp->width * 3;		break;	case 32:		info->fix.line_length = sp->width * 4;		break;	}	sp->fb_size = info->fix.line_length * sp->height;	sp->fb_base = ioremap(sp->fb_base_phys, sp->fb_size);	if (!sp->fb_base)		goto err_release_pci;	err = s3d_set_fbinfo(sp);	if (err)		goto err_unmap_fb;	pci_set_drvdata(pdev, info);	printk("s3d: Found device at %s\n", pci_name(pdev));	err = register_framebuffer(info);	if (err < 0) {		printk(KERN_ERR "s3d: Could not register framebuffer %s\n",		       pci_name(pdev));		goto err_unmap_fb;	}	return 0;err_unmap_fb:	iounmap(sp->fb_base);err_release_pci:	pci_release_region(pdev, 1);err_release_fb:        framebuffer_release(info);err_disable:	pci_disable_device(pdev);err_out:	return err;}static void __devexit s3d_pci_unregister(struct pci_dev *pdev){	struct fb_info *info = pci_get_drvdata(pdev);	struct s3d_info *sp = info->par;	unregister_framebuffer(info);	iounmap(sp->fb_base);	pci_release_region(pdev, 1);        framebuffer_release(info);	pci_disable_device(pdev);}static struct pci_device_id s3d_pci_table[] = {	{	PCI_DEVICE(PCI_VENDOR_ID_3DLABS, 0x002c),	},	{	PCI_DEVICE(PCI_VENDOR_ID_3DLABS, 0x002d),	},	{	PCI_DEVICE(PCI_VENDOR_ID_3DLABS, 0x002e),	},	{	PCI_DEVICE(PCI_VENDOR_ID_3DLABS, 0x002f),	},	{	PCI_DEVICE(PCI_VENDOR_ID_3DLABS, 0x0030),	},	{	PCI_DEVICE(PCI_VENDOR_ID_3DLABS, 0x0031),	},	{	PCI_DEVICE(PCI_VENDOR_ID_3DLABS, 0x0032),	},	{	PCI_DEVICE(PCI_VENDOR_ID_3DLABS, 0x0033),	},	{ 0, }};static struct pci_driver s3d_driver = {	.name		= "s3d",	.id_table	= s3d_pci_table,	.probe		= s3d_pci_register,	.remove		= __devexit_p(s3d_pci_unregister),};static int __init s3d_init(void){	if (fb_get_options("s3d", NULL))		return -ENODEV;	return pci_register_driver(&s3d_driver);}static void __exit s3d_exit(void){	pci_unregister_driver(&s3d_driver);}module_init(s3d_init);module_exit(s3d_exit);MODULE_DESCRIPTION("framebuffer driver for Sun XVR-2500 graphics");MODULE_AUTHOR("David S. Miller <davem@davemloft.net>");MODULE_VERSION("1.0");MODULE_LICENSE("GPL");

⌨️ 快捷键说明

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