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

📄 lxfb_core.c

📁 Linux环境下视频显示卡设备的驱动程序源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
	if (ret)		return ret;	ret = pci_request_region(dev, 0, "lxfb-framebuffer");	if (ret)		return ret;	ret = pci_request_region(dev, 1, "lxfb-gp");	if (ret)		return ret;	ret = pci_request_region(dev, 2, "lxfb-vg");	if (ret)		return ret;	ret = pci_request_region(dev, 3, "lxfb-vp");	if (ret)		return ret;	info->fix.smem_start = pci_resource_start(dev, 0);	info->fix.smem_len = vram ? vram : lx_framebuffer_size();	info->screen_base = ioremap(info->fix.smem_start, info->fix.smem_len);	ret = -ENOMEM;	if (info->screen_base == NULL)		return ret;	par->gp_regs = pci_ioremap_bar(dev, 1);	if (par->gp_regs == NULL)		return ret;	par->dc_regs = pci_ioremap_bar(dev, 2);	if (par->dc_regs == NULL)		return ret;	par->vp_regs = pci_ioremap_bar(dev, 3);	if (par->vp_regs == NULL)		return ret;	write_dc(par, DC_UNLOCK, DC_UNLOCK_UNLOCK);	write_dc(par, DC_GLIU0_MEM_OFFSET, info->fix.smem_start & 0xFF000000);	write_dc(par, DC_UNLOCK, DC_UNLOCK_LOCK);	dev_info(&dev->dev, "%d KB of video memory at 0x%lx\n",		 info->fix.smem_len / 1024, info->fix.smem_start);	return 0;}static struct fb_ops lxfb_ops = {	.owner		= THIS_MODULE,	.fb_check_var	= lxfb_check_var,	.fb_set_par	= lxfb_set_par,	.fb_setcolreg	= lxfb_setcolreg,	.fb_blank       = lxfb_blank,	/* No HW acceleration for now. */	.fb_fillrect	= cfb_fillrect,	.fb_copyarea	= cfb_copyarea,	.fb_imageblit	= cfb_imageblit,};static struct fb_info * __init lxfb_init_fbinfo(struct device *dev){	struct lxfb_par *par;	struct fb_info *info;	/* Alloc enough space for the pseudo palette. */	info = framebuffer_alloc(sizeof(struct lxfb_par) + sizeof(u32) * 16,				 dev);	if (!info)		return NULL;	par = info->par;	strcpy(info->fix.id, "Geode LX");	info->fix.type		= FB_TYPE_PACKED_PIXELS;	info->fix.type_aux	= 0;	info->fix.xpanstep	= 0;	info->fix.ypanstep	= 0;	info->fix.ywrapstep	= 0;	info->fix.accel		= FB_ACCEL_NONE;	info->var.nonstd	= 0;	info->var.activate	= FB_ACTIVATE_NOW;	info->var.height	= -1;	info->var.width	= -1;	info->var.accel_flags = 0;	info->var.vmode	= FB_VMODE_NONINTERLACED;	info->fbops		= &lxfb_ops;	info->flags		= FBINFO_DEFAULT;	info->node		= -1;	info->pseudo_palette	= (void *)par + sizeof(struct lxfb_par);	if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) {		framebuffer_release(info);		return NULL;	}	info->var.grayscale	= 0;	return info;}#ifdef CONFIG_PMstatic int lxfb_suspend(struct pci_dev *pdev, pm_message_t state){	struct fb_info *info = pci_get_drvdata(pdev);	if (state.event == PM_EVENT_SUSPEND) {		acquire_console_sem();		lx_powerdown(info);		fb_set_suspend(info, 1);		release_console_sem();	}	/* there's no point in setting PCI states; we emulate PCI, so	 * we don't end up getting power savings anyways */	return 0;}static int lxfb_resume(struct pci_dev *pdev){	struct fb_info *info = pci_get_drvdata(pdev);	int ret;	acquire_console_sem();	ret = lx_powerup(info);	if (ret) {		printk(KERN_ERR "lxfb:  power up failed!\n");		return ret;	}	fb_set_suspend(info, 0);	release_console_sem();	return 0;}#else#define lxfb_suspend NULL#define lxfb_resume NULL#endifstatic int __init lxfb_probe(struct pci_dev *pdev,			     const struct pci_device_id *id){	struct lxfb_par *par;	struct fb_info *info;	int ret;	struct fb_videomode *modedb_ptr;	unsigned int modedb_size;	info = lxfb_init_fbinfo(&pdev->dev);	if (info == NULL)		return -ENOMEM;	par = info->par;	ret = lxfb_map_video_memory(info, pdev);	if (ret < 0) {		dev_err(&pdev->dev,			"failed to map frame buffer or controller registers\n");		goto err;	}	/* Set up the desired outputs */	par->output = 0;	par->output |= (nopanel) ? 0 : OUTPUT_PANEL;	par->output |= (nocrt) ? 0 : OUTPUT_CRT;	/* Set up the mode database */	get_modedb(&modedb_ptr, &modedb_size);	ret = fb_find_mode(&info->var, info, mode_option,			   modedb_ptr, modedb_size, NULL, 16);	if (ret == 0 || ret == 4) {		dev_err(&pdev->dev, "could not find valid video mode\n");		ret = -EINVAL;		goto err;	}	/* Clear the screen of garbage, unless noclear was specified,	 * in which case we assume the user knows what he is doing */	if (!noclear)		memset_io(info->screen_base, 0, info->fix.smem_len);	/* Set the mode */	lxfb_check_var(&info->var, info);	lxfb_set_par(info);	pm_set_vt_switch(vt_switch);	if (register_framebuffer(info) < 0) {		ret = -EINVAL;		goto err;	}	pci_set_drvdata(pdev, info);	printk(KERN_INFO "fb%d: %s frame buffer device\n",		info->node, info->fix.id);	return 0;err:	if (info->screen_base) {		iounmap(info->screen_base);		pci_release_region(pdev, 0);	}	if (par->gp_regs) {		iounmap(par->gp_regs);		pci_release_region(pdev, 1);	}	if (par->dc_regs) {		iounmap(par->dc_regs);		pci_release_region(pdev, 2);	}	if (par->vp_regs) {		iounmap(par->vp_regs);		pci_release_region(pdev, 3);	}	if (info) {		fb_dealloc_cmap(&info->cmap);		framebuffer_release(info);	}	return ret;}static void lxfb_remove(struct pci_dev *pdev){	struct fb_info *info = pci_get_drvdata(pdev);	struct lxfb_par *par = info->par;	unregister_framebuffer(info);	iounmap(info->screen_base);	pci_release_region(pdev, 0);	iounmap(par->gp_regs);	pci_release_region(pdev, 1);	iounmap(par->dc_regs);	pci_release_region(pdev, 2);	iounmap(par->vp_regs);	pci_release_region(pdev, 3);	fb_dealloc_cmap(&info->cmap);	pci_set_drvdata(pdev, NULL);	framebuffer_release(info);}static struct pci_device_id lxfb_id_table[] = {	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_LX_VIDEO) },	{ 0, }};MODULE_DEVICE_TABLE(pci, lxfb_id_table);static struct pci_driver lxfb_driver = {	.name		= "lxfb",	.id_table	= lxfb_id_table,	.probe		= lxfb_probe,	.remove		= lxfb_remove,	.suspend	= lxfb_suspend,	.resume		= lxfb_resume,};#ifndef MODULEstatic int __init lxfb_setup(char *options){	char *opt;	if (!options || !*options)		return 0;	while ((opt = strsep(&options, ",")) != NULL) {		if (!*opt)			continue;		if (!strcmp(opt, "noclear"))			noclear = 1;		else if (!strcmp(opt, "nopanel"))			nopanel = 1;		else if (!strcmp(opt, "nocrt"))			nocrt = 1;		else			mode_option = opt;	}	return 0;}#endifstatic int __init lxfb_init(void){#ifndef MODULE	char *option = NULL;	if (fb_get_options("lxfb", &option))		return -ENODEV;	lxfb_setup(option);#endif	return pci_register_driver(&lxfb_driver);}static void __exit lxfb_cleanup(void){	pci_unregister_driver(&lxfb_driver);}module_init(lxfb_init);module_exit(lxfb_cleanup);module_param(mode_option, charp, 0);MODULE_PARM_DESC(mode_option, "video mode (<x>x<y>[-<bpp>][@<refr>])");module_param(vram, int, 0);MODULE_PARM_DESC(vram, "video memory size");module_param(vt_switch, int, 0);MODULE_PARM_DESC(vt_switch, "enable VT switch during suspend/resume");MODULE_DESCRIPTION("Framebuffer driver for the AMD Geode LX");MODULE_LICENSE("GPL");

⌨️ 快捷键说明

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