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

📄 imxfb.c

📁 Linux环境下视频显示卡设备的驱动程序源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
	if (fbi->backlight_power)		fbi->backlight_power(1);	if (fbi->lcd_power)		fbi->lcd_power(1);}static void imxfb_disable_controller(struct imxfb_info *fbi){	pr_debug("Disabling LCD controller\n");	if (fbi->backlight_power)		fbi->backlight_power(0);	if (fbi->lcd_power)		fbi->lcd_power(0);	writel(0, fbi->regs + LCDC_RMCR);}static int imxfb_blank(int blank, struct fb_info *info){	struct imxfb_info *fbi = info->par;	pr_debug("imxfb_blank: blank=%d\n", blank);	switch (blank) {	case FB_BLANK_POWERDOWN:	case FB_BLANK_VSYNC_SUSPEND:	case FB_BLANK_HSYNC_SUSPEND:	case FB_BLANK_NORMAL:		imxfb_disable_controller(fbi);		break;	case FB_BLANK_UNBLANK:		imxfb_enable_controller(fbi);		break;	}	return 0;}static struct fb_ops imxfb_ops = {	.owner		= THIS_MODULE,	.fb_check_var	= imxfb_check_var,	.fb_set_par	= imxfb_set_par,	.fb_setcolreg	= imxfb_setcolreg,	.fb_fillrect	= cfb_fillrect,	.fb_copyarea	= cfb_copyarea,	.fb_imageblit	= cfb_imageblit,	.fb_blank	= imxfb_blank,};/* * imxfb_activate_var(): *	Configures LCD Controller based on entries in var parameter.  Settings are *	only written to the controller if changes were made. */static int imxfb_activate_var(struct fb_var_screeninfo *var, struct fb_info *info){	struct imxfb_info *fbi = info->par;	pr_debug("var: xres=%d hslen=%d lm=%d rm=%d\n",		var->xres, var->hsync_len,		var->left_margin, var->right_margin);	pr_debug("var: yres=%d vslen=%d um=%d bm=%d\n",		var->yres, var->vsync_len,		var->upper_margin, var->lower_margin);#if DEBUG_VAR	if (var->xres < 16        || var->xres > 1024)		printk(KERN_ERR "%s: invalid xres %d\n",			info->fix.id, var->xres);	if (var->hsync_len < 1    || var->hsync_len > 64)		printk(KERN_ERR "%s: invalid hsync_len %d\n",			info->fix.id, var->hsync_len);	if (var->left_margin > 255)		printk(KERN_ERR "%s: invalid left_margin %d\n",			info->fix.id, var->left_margin);	if (var->right_margin > 255)		printk(KERN_ERR "%s: invalid right_margin %d\n",			info->fix.id, var->right_margin);	if (var->yres < 1 || var->yres > 511)		printk(KERN_ERR "%s: invalid yres %d\n",			info->fix.id, var->yres);	if (var->vsync_len > 100)		printk(KERN_ERR "%s: invalid vsync_len %d\n",			info->fix.id, var->vsync_len);	if (var->upper_margin > 63)		printk(KERN_ERR "%s: invalid upper_margin %d\n",			info->fix.id, var->upper_margin);	if (var->lower_margin > 255)		printk(KERN_ERR "%s: invalid lower_margin %d\n",			info->fix.id, var->lower_margin);#endif	writel(HCR_H_WIDTH(var->hsync_len) |		HCR_H_WAIT_1(var->right_margin) |		HCR_H_WAIT_2(var->left_margin),		fbi->regs + LCDC_HCR);	writel(VCR_V_WIDTH(var->vsync_len) |		VCR_V_WAIT_1(var->lower_margin) |		VCR_V_WAIT_2(var->upper_margin),		fbi->regs + LCDC_VCR);	writel(SIZE_XMAX(var->xres) | SIZE_YMAX(var->yres),			fbi->regs + LCDC_SIZE);	writel(fbi->pcr, fbi->regs + LCDC_PCR);	writel(fbi->pwmr, fbi->regs + LCDC_PWMR);	writel(fbi->lscr1, fbi->regs + LCDC_LSCR1);	writel(fbi->dmacr, fbi->regs + LCDC_DMACR);	return 0;}#ifdef CONFIG_PM/* * Power management hooks.  Note that we won't be called from IRQ context, * unlike the blank functions above, so we may sleep. */static int imxfb_suspend(struct platform_device *dev, pm_message_t state){	struct imxfb_info *fbi = platform_get_drvdata(dev);	pr_debug("%s\n", __func__);	imxfb_disable_controller(fbi);	return 0;}static int imxfb_resume(struct platform_device *dev){	struct imxfb_info *fbi = platform_get_drvdata(dev);	pr_debug("%s\n", __func__);	imxfb_enable_controller(fbi);	return 0;}#else#define imxfb_suspend	NULL#define imxfb_resume	NULL#endifstatic int __init imxfb_init_fbinfo(struct platform_device *pdev){	struct imx_fb_platform_data *pdata = pdev->dev.platform_data;	struct fb_info *info = dev_get_drvdata(&pdev->dev);	struct imxfb_info *fbi = info->par;	pr_debug("%s\n",__func__);	info->pseudo_palette = kmalloc(sizeof(u32) * 16, GFP_KERNEL);	if (!info->pseudo_palette)		return -ENOMEM;	memset(fbi, 0, sizeof(struct imxfb_info));	strlcpy(info->fix.id, IMX_NAME, sizeof(info->fix.id));	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			= &imxfb_ops;	info->flags			= FBINFO_FLAG_DEFAULT |					  FBINFO_READS_FAST;	fbi->max_xres			= pdata->xres;	info->var.xres			= pdata->xres;	info->var.xres_virtual		= pdata->xres;	fbi->max_yres			= pdata->yres;	info->var.yres			= pdata->yres;	info->var.yres_virtual		= pdata->yres;	fbi->max_bpp			= pdata->bpp;	info->var.bits_per_pixel	= pdata->bpp;	info->var.nonstd		= pdata->nonstd;	info->var.pixclock		= pdata->pixclock;	info->var.hsync_len		= pdata->hsync_len;	info->var.left_margin		= pdata->left_margin;	info->var.right_margin		= pdata->right_margin;	info->var.vsync_len		= pdata->vsync_len;	info->var.upper_margin		= pdata->upper_margin;	info->var.lower_margin		= pdata->lower_margin;	info->var.sync			= pdata->sync;	info->var.grayscale		= pdata->cmap_greyscale;	fbi->cmap_inverse		= pdata->cmap_inverse;	fbi->cmap_static		= pdata->cmap_static;	fbi->pcr			= pdata->pcr;	fbi->lscr1			= pdata->lscr1;	fbi->dmacr			= pdata->dmacr;	fbi->pwmr			= pdata->pwmr;	fbi->lcd_power			= pdata->lcd_power;	fbi->backlight_power		= pdata->backlight_power;	info->fix.smem_len		= fbi->max_xres * fbi->max_yres *					  fbi->max_bpp / 8;	return 0;}static int __init imxfb_probe(struct platform_device *pdev){	struct imxfb_info *fbi;	struct fb_info *info;	struct imx_fb_platform_data *pdata;	struct resource *res;	int ret;	printk("i.MX Framebuffer driver\n");	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);	if (!res)		return -ENODEV;	pdata = pdev->dev.platform_data;	if (!pdata) {		dev_err(&pdev->dev,"No platform_data available\n");		return -ENOMEM;	}	info = framebuffer_alloc(sizeof(struct imxfb_info), &pdev->dev);	if (!info)		return -ENOMEM;	fbi = info->par;	platform_set_drvdata(pdev, info);	ret = imxfb_init_fbinfo(pdev);	if (ret < 0)		goto failed_init;	res = request_mem_region(res->start, resource_size(res),				DRIVER_NAME);	if (!res) {		ret = -EBUSY;		goto failed_req;	}	fbi->regs = ioremap(res->start, resource_size(res));	if (fbi->regs == NULL) {		printk(KERN_ERR"Cannot map frame buffer registers\n");		goto failed_ioremap;	}	if (!pdata->fixed_screen_cpu) {		fbi->map_size = PAGE_ALIGN(info->fix.smem_len);		fbi->map_cpu = dma_alloc_writecombine(&pdev->dev,				fbi->map_size, &fbi->map_dma, GFP_KERNEL);		if (!fbi->map_cpu) {			dev_err(&pdev->dev, "Failed to allocate video RAM: %d\n", ret);			ret = -ENOMEM;			goto failed_map;		}		info->screen_base = fbi->map_cpu;		fbi->screen_cpu = fbi->map_cpu;		fbi->screen_dma = fbi->map_dma;		info->fix.smem_start = fbi->screen_dma;	} else {		/* Fixed framebuffer mapping enables location of the screen in eSRAM */		fbi->map_cpu = pdata->fixed_screen_cpu;		fbi->map_dma = pdata->fixed_screen_dma;		info->screen_base = fbi->map_cpu;		fbi->screen_cpu = fbi->map_cpu;		fbi->screen_dma = fbi->map_dma;		info->fix.smem_start = fbi->screen_dma;	}	/*	 * This makes sure that our colour bitfield	 * descriptors are correctly initialised.	 */	imxfb_check_var(&info->var, info);	ret = fb_alloc_cmap(&info->cmap, 1 << info->var.bits_per_pixel, 0);	if (ret < 0)		goto failed_cmap;	imxfb_set_par(info);	ret = register_framebuffer(info);	if (ret < 0) {		dev_err(&pdev->dev, "failed to register framebuffer\n");		goto failed_register;	}	imxfb_enable_controller(fbi);	return 0;failed_register:	fb_dealloc_cmap(&info->cmap);failed_cmap:	if (!pdata->fixed_screen_cpu)		dma_free_writecombine(&pdev->dev,fbi->map_size,fbi->map_cpu,			fbi->map_dma);failed_map:	iounmap(fbi->regs);failed_ioremap:	release_mem_region(res->start, res->end - res->start);failed_req:	kfree(info->pseudo_palette);failed_init:	platform_set_drvdata(pdev, NULL);	framebuffer_release(info);	return ret;}static int __devexit imxfb_remove(struct platform_device *pdev){	struct fb_info *info = platform_get_drvdata(pdev);	struct imxfb_info *fbi = info->par;	struct resource *res;	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);	imxfb_disable_controller(fbi);	unregister_framebuffer(info);	fb_dealloc_cmap(&info->cmap);	kfree(info->pseudo_palette);	framebuffer_release(info);	iounmap(fbi->regs);	release_mem_region(res->start, res->end - res->start + 1);	platform_set_drvdata(pdev, NULL);	return 0;}void  imxfb_shutdown(struct platform_device * dev){	struct fb_info *info = platform_get_drvdata(dev);	struct imxfb_info *fbi = info->par;	imxfb_disable_controller(fbi);}static struct platform_driver imxfb_driver = {	.suspend	= imxfb_suspend,	.resume		= imxfb_resume,	.remove		= __devexit_p(imxfb_remove),	.shutdown	= imxfb_shutdown,	.driver		= {		.name	= DRIVER_NAME,	},};int __init imxfb_init(void){	return platform_driver_probe(&imxfb_driver, imxfb_probe);}static void __exit imxfb_cleanup(void){	platform_driver_unregister(&imxfb_driver);}module_init(imxfb_init);module_exit(imxfb_cleanup);MODULE_DESCRIPTION("Motorola i.MX framebuffer driver");MODULE_AUTHOR("Sascha Hauer, Pengutronix");MODULE_LICENSE("GPL");

⌨️ 快捷键说明

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