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

📄 omapfb_main.c

📁 Linux环境下视频显示卡设备的驱动程序源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
{	struct fb_var_screeninfo	*var = &info->var;	struct fb_fix_screeninfo	*fix = &info->fix;	int				r = 0;	info->fbops = &omapfb_ops;	info->flags = FBINFO_FLAG_DEFAULT;	strncpy(fix->id, MODULE_NAME, sizeof(fix->id));	info->pseudo_palette = fbdev->pseudo_palette;	var->accel_flags  = def_accel ? FB_ACCELF_TEXT : 0;	var->xres = def_vxres;	var->yres = def_vyres;	var->xres_virtual = def_vxres;	var->yres_virtual = def_vyres;	var->rotate	  = def_rotate;	var->bits_per_pixel = fbdev->panel->bpp;	set_fb_var(info, var);	set_fb_fix(info);	r = fb_alloc_cmap(&info->cmap, 16, 0);	if (r != 0)		dev_err(fbdev->dev, "unable to allocate color map memory\n");	return r;}/* Release the fb_info object */static void fbinfo_cleanup(struct omapfb_device *fbdev, struct fb_info *fbi){	fb_dealloc_cmap(&fbi->cmap);}static void planes_cleanup(struct omapfb_device *fbdev){	int i;	for (i = 0; i < fbdev->mem_desc.region_cnt; i++) {		if (fbdev->fb_info[i] == NULL)			break;		fbinfo_cleanup(fbdev, fbdev->fb_info[i]);		framebuffer_release(fbdev->fb_info[i]);	}}static int planes_init(struct omapfb_device *fbdev){	struct fb_info *fbi;	int i;	int r;	for (i = 0; i < fbdev->mem_desc.region_cnt; i++) {		struct omapfb_plane_struct *plane;		fbi = framebuffer_alloc(sizeof(struct omapfb_plane_struct),					fbdev->dev);		if (fbi == NULL) {			dev_err(fbdev->dev,				"unable to allocate memory for plane info\n");			planes_cleanup(fbdev);			return -ENOMEM;		}		plane = fbi->par;		plane->idx = i;		plane->fbdev = fbdev;		plane->info.mirror = def_mirror;		fbdev->fb_info[i] = fbi;		if ((r = fbinfo_init(fbdev, fbi)) < 0) {			framebuffer_release(fbi);			planes_cleanup(fbdev);			return r;		}		plane->info.out_width = fbi->var.xres;		plane->info.out_height = fbi->var.yres;	}	return 0;}/* * Free driver resources. Can be called to rollback an aborted initialization * sequence. */static void omapfb_free_resources(struct omapfb_device *fbdev, int state){	int i;	switch (state) {	case OMAPFB_ACTIVE:		for (i = 0; i < fbdev->mem_desc.region_cnt; i++)			unregister_framebuffer(fbdev->fb_info[i]);	case 7:		omapfb_unregister_sysfs(fbdev);	case 6:		fbdev->panel->disable(fbdev->panel);	case 5:		omapfb_set_update_mode(fbdev, OMAPFB_UPDATE_DISABLED);	case 4:		planes_cleanup(fbdev);	case 3:		ctrl_cleanup(fbdev);	case 2:		fbdev->panel->cleanup(fbdev->panel);	case 1:		dev_set_drvdata(fbdev->dev, NULL);		kfree(fbdev);	case 0:		/* nothing to free */		break;	default:		BUG();	}}static int omapfb_find_ctrl(struct omapfb_device *fbdev){	struct omapfb_platform_data *conf;	char name[17];	int i;	conf = fbdev->dev->platform_data;	fbdev->ctrl = NULL;	strncpy(name, conf->lcd.ctrl_name, sizeof(name) - 1);	name[sizeof(name) - 1] = '\0';	if (strcmp(name, "internal") == 0) {		fbdev->ctrl = fbdev->int_ctrl;		return 0;	}	for (i = 0; i < ARRAY_SIZE(ctrls); i++) {		dev_dbg(fbdev->dev, "ctrl %s\n", ctrls[i]->name);		if (strcmp(ctrls[i]->name, name) == 0) {			fbdev->ctrl = ctrls[i];			break;		}	}	if (fbdev->ctrl == NULL) {		dev_dbg(fbdev->dev, "ctrl %s not supported\n", name);		return -1;	}	return 0;}static void check_required_callbacks(struct omapfb_device *fbdev){#define _C(x) (fbdev->ctrl->x != NULL)#define _P(x) (fbdev->panel->x != NULL)	BUG_ON(fbdev->ctrl == NULL || fbdev->panel == NULL);	BUG_ON(!(_C(init) && _C(cleanup) && _C(get_caps) &&		 _C(set_update_mode) && _C(setup_plane) && _C(enable_plane) &&		 _P(init) && _P(cleanup) && _P(enable) && _P(disable) &&		 _P(get_caps)));#undef _P#undef _C}/* * Called by LDM binding to probe and attach a new device. * Initialization sequence: *   1. allocate system omapfb_device structure *   2. select controller type according to platform configuration *      init LCD panel *   3. init LCD controller and LCD DMA *   4. init system fb_info structure for all planes *   5. setup video mode for first plane and enable it *   6. enable LCD panel *   7. register sysfs attributes *   OMAPFB_ACTIVE: register system fb_info structure for all planes */static int omapfb_do_probe(struct platform_device *pdev,				struct lcd_panel *panel){	struct omapfb_device	*fbdev = NULL;	int			init_state;	unsigned long		phz, hhz, vhz;	unsigned long		vram;	int			i;	int			r = 0;	init_state = 0;	if (pdev->num_resources != 0) {		dev_err(&pdev->dev, "probed for an unknown device\n");		r = -ENODEV;		goto cleanup;	}	if (pdev->dev.platform_data == NULL) {		dev_err(&pdev->dev, "missing platform data\n");		r = -ENOENT;		goto cleanup;	}	fbdev = kzalloc(sizeof(struct omapfb_device), GFP_KERNEL);	if (fbdev == NULL) {		dev_err(&pdev->dev,			"unable to allocate memory for device info\n");		r = -ENOMEM;		goto cleanup;	}	init_state++;	fbdev->dev = &pdev->dev;	fbdev->panel = panel;	platform_set_drvdata(pdev, fbdev);	mutex_init(&fbdev->rqueue_mutex);#ifdef CONFIG_ARCH_OMAP1	fbdev->int_ctrl = &omap1_int_ctrl;#ifdef CONFIG_FB_OMAP_LCDC_EXTERNAL	fbdev->ext_if = &omap1_ext_if;#endif#else	/* OMAP2 */	fbdev->int_ctrl = &omap2_int_ctrl;#ifdef CONFIG_FB_OMAP_LCDC_EXTERNAL	fbdev->ext_if = &omap2_ext_if;#endif#endif	if (omapfb_find_ctrl(fbdev) < 0) {		dev_err(fbdev->dev,			"LCD controller not found, board not supported\n");		r = -ENODEV;		goto cleanup;	}	r = fbdev->panel->init(fbdev->panel, fbdev);	if (r)		goto cleanup;	pr_info("omapfb: configured for panel %s\n", fbdev->panel->name);	def_vxres = def_vxres ? : fbdev->panel->x_res;	def_vyres = def_vyres ? : fbdev->panel->y_res;	init_state++;	r = ctrl_init(fbdev);	if (r)		goto cleanup;	if (fbdev->ctrl->mmap != NULL)		omapfb_ops.fb_mmap = omapfb_mmap;	init_state++;	check_required_callbacks(fbdev);	r = planes_init(fbdev);	if (r)		goto cleanup;	init_state++;#ifdef CONFIG_FB_OMAP_DMA_TUNE	/* Set DMA priority for EMIFF access to highest */	if (cpu_class_is_omap1())		omap_set_dma_priority(0, OMAP_DMA_PORT_EMIFF, 15);#endif	r = ctrl_change_mode(fbdev->fb_info[0]);	if (r) {		dev_err(fbdev->dev, "mode setting failed\n");		goto cleanup;	}	/* GFX plane is enabled by default */	r = fbdev->ctrl->enable_plane(OMAPFB_PLANE_GFX, 1);	if (r)		goto cleanup;	omapfb_set_update_mode(fbdev, manual_update ?				   OMAPFB_MANUAL_UPDATE : OMAPFB_AUTO_UPDATE);	init_state++;	r = fbdev->panel->enable(fbdev->panel);	if (r)		goto cleanup;	init_state++;	r = omapfb_register_sysfs(fbdev);	if (r)		goto cleanup;	init_state++;	vram = 0;	for (i = 0; i < fbdev->mem_desc.region_cnt; i++) {		r = register_framebuffer(fbdev->fb_info[i]);		if (r != 0) {			dev_err(fbdev->dev,				"registering framebuffer %d failed\n", i);			goto cleanup;		}		vram += fbdev->mem_desc.region[i].size;	}	fbdev->state = OMAPFB_ACTIVE;	panel = fbdev->panel;	phz = panel->pixel_clock * 1000;	hhz = phz * 10 / (panel->hfp + panel->x_res + panel->hbp + panel->hsw);	vhz = hhz / (panel->vfp + panel->y_res + panel->vbp + panel->vsw);	omapfb_dev = fbdev;	pr_info("omapfb: Framebuffer initialized. Total vram %lu planes %d\n",			vram, fbdev->mem_desc.region_cnt);	pr_info("omapfb: Pixclock %lu kHz hfreq %lu.%lu kHz "			"vfreq %lu.%lu Hz\n",			phz / 1000, hhz / 10000, hhz % 10, vhz / 10, vhz % 10);	return 0;cleanup:	omapfb_free_resources(fbdev, init_state);	return r;}static int omapfb_probe(struct platform_device *pdev){	BUG_ON(fbdev_pdev != NULL);	/* Delay actual initialization until the LCD is registered */	fbdev_pdev = pdev;	if (fbdev_panel != NULL)		omapfb_do_probe(fbdev_pdev, fbdev_panel);	return 0;}void omapfb_register_panel(struct lcd_panel *panel){	BUG_ON(fbdev_panel != NULL);	fbdev_panel = panel;	if (fbdev_pdev != NULL)		omapfb_do_probe(fbdev_pdev, fbdev_panel);}/* Called when the device is being detached from the driver */static int omapfb_remove(struct platform_device *pdev){	struct omapfb_device *fbdev = platform_get_drvdata(pdev);	enum omapfb_state saved_state = fbdev->state;	/* FIXME: wait till completion of pending events */	fbdev->state = OMAPFB_DISABLED;	omapfb_free_resources(fbdev, saved_state);	return 0;}/* PM suspend */static int omapfb_suspend(struct platform_device *pdev, pm_message_t mesg){	struct omapfb_device *fbdev = platform_get_drvdata(pdev);	omapfb_blank(VESA_POWERDOWN, fbdev->fb_info[0]);	return 0;}/* PM resume */static int omapfb_resume(struct platform_device *pdev){	struct omapfb_device *fbdev = platform_get_drvdata(pdev);	omapfb_blank(VESA_NO_BLANKING, fbdev->fb_info[0]);	return 0;}static struct platform_driver omapfb_driver = {	.probe		= omapfb_probe,	.remove		= omapfb_remove,	.suspend	= omapfb_suspend,	.resume		= omapfb_resume,	.driver		= {		.name	= MODULE_NAME,		.owner	= THIS_MODULE,	},};#ifndef MODULE/* Process kernel command line parameters */static int __init omapfb_setup(char *options){	char *this_opt = NULL;	int r = 0;	pr_debug("omapfb: options %s\n", options);	if (!options || !*options)		return 0;	while (!r && (this_opt = strsep(&options, ",")) != NULL) {		if (!strncmp(this_opt, "accel", 5))			def_accel = 1;		else if (!strncmp(this_opt, "vram:", 5)) {			char *suffix;			unsigned long vram;			vram = (simple_strtoul(this_opt + 5, &suffix, 0));			switch (suffix[0]) {			case '\0':				break;			case 'm':			case 'M':				vram *= 1024;				/* Fall through */			case 'k':			case 'K':				vram *= 1024;				break;			default:				pr_debug("omapfb: invalid vram suffix %c\n",					 suffix[0]);				r = -1;			}			def_vram[def_vram_cnt++] = vram;		}		else if (!strncmp(this_opt, "vxres:", 6))			def_vxres = simple_strtoul(this_opt + 6, NULL, 0);		else if (!strncmp(this_opt, "vyres:", 6))			def_vyres = simple_strtoul(this_opt + 6, NULL, 0);		else if (!strncmp(this_opt, "rotate:", 7))			def_rotate = (simple_strtoul(this_opt + 7, NULL, 0));		else if (!strncmp(this_opt, "mirror:", 7))			def_mirror = (simple_strtoul(this_opt + 7, NULL, 0));		else if (!strncmp(this_opt, "manual_update", 13))			manual_update = 1;		else {			pr_debug("omapfb: invalid option\n");			r = -1;		}	}	return r;}#endif/* Register both the driver and the device */static int __init omapfb_init(void){#ifndef MODULE	char *option;	if (fb_get_options("omapfb", &option))		return -ENODEV;	omapfb_setup(option);#endif	/* Register the driver with LDM */	if (platform_driver_register(&omapfb_driver)) {		pr_debug("failed to register omapfb driver\n");		return -ENODEV;	}	return 0;}static void __exit omapfb_cleanup(void){	platform_driver_unregister(&omapfb_driver);}module_param_named(accel, def_accel, uint, 0664);module_param_array_named(vram, def_vram, ulong, &def_vram_cnt, 0664);module_param_named(vxres, def_vxres, long, 0664);module_param_named(vyres, def_vyres, long, 0664);module_param_named(rotate, def_rotate, uint, 0664);module_param_named(mirror, def_mirror, uint, 0664);module_param_named(manual_update, manual_update, bool, 0664);module_init(omapfb_init);module_exit(omapfb_cleanup);MODULE_DESCRIPTION("TI OMAP framebuffer driver");MODULE_AUTHOR("Imre Deak <imre.deak@nokia.com>");MODULE_LICENSE("GPL");

⌨️ 快捷键说明

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