omapfb_main.c

来自「Linux Kernel 2.6.9 for OMAP1710」· C语言 代码 · 共 1,875 行 · 第 1/4 页

C
1,875
字号
 * --------------------------------------------------------------------------- * LDM callbacks * --------------------------------------------------------------------------- *//* Initialize system fb_info object and set the default video mode. * The frame buffer memory already allocated by lcddma_init */static int fbinfo_init(struct omapfb_device *fbdev){	struct fb_info			*info = fbdev->fb_info;	struct fb_var_screeninfo	*var = &info->var;	int				r = 0;	DBGENTER(1);	BUG_ON(!fbdev->lcddma_base);	info->fbops = &omapfb_ops;	info->flags = FBINFO_FLAG_DEFAULT;	info->screen_base = (char *) fbdev->lcddma_base + fbdev->frame0_org;	info->pseudo_palette = fbdev->pseudo_palette;	var->accel_flags  = def_accel ? FB_ACCELF_TEXT : 0;	var->xres_virtual = def_vxres;	var->yres_virtual = def_vyres;	var->rotate	  = def_rotate;	fbdev->mirror = def_mirror;	set_fb_var(fbdev, var);	set_fb_fix(fbdev);	r = fb_alloc_cmap(&info->cmap, 16, 0);	if (r != 0)		PRNERR("unable to allocate color map memory\n");	DBGLEAVE(1);	return r;}/* Release the fb_info object */static void fbinfo_cleanup(struct omapfb_device *fbdev){	DBGENTER(1);	fb_dealloc_cmap(&fbdev->fb_info->cmap);	DBGLEAVE(1);}static int omapfb_activate(struct omapfb_device *fbdev){	int r;	r = fbdev->panel->enable(fbdev->panel);	if (r)		return r;	fbdev->ctrl->start(fbdev);	fbdev->state = OMAPFB_ACTIVE;	return 0;}static void omapfb_deactivate(struct omapfb_device *fbdev){	fbdev->ctrl->stop(fbdev);	fbdev->panel->disable(fbdev->panel);	fbdev->state = OMAPFB_DEACTIVATED;}/* Free driver resources. Can be called to rollback an aborted initialization * sequence. */static void omapfb_free_resources(struct omapfb_device *fbdev, int state){	switch (state) {	case OMAPFB_ACTIVE:	case OMAPFB_MODE_CHANGE:		omapfb_deactivate(fbdev);	case OMAPFB_DEACTIVATED:	case 6:		unregister_framebuffer(fbdev->fb_info);	case 5:		gfxdma_cleanup(&fbdev->gfx);	case 4:		fbinfo_cleanup(fbdev);	case 3:		ctrl_cleanup(fbdev);	case 2:		fbdev->panel->cleanup(fbdev->panel);	case 1:		dev_set_drvdata(fbdev->dev, NULL);		framebuffer_release(fbdev->fb_info);	case 0:		/* nothing to free */		break;	default:		BUG();	}}static int omapfb_find_panel(struct omapfb_device *fbdev){	const struct omap_lcd_config *cfg;	char name[17];	int i;	fbdev->panel = NULL;	cfg = omap_get_config(OMAP_TAG_LCD, struct omap_lcd_config);	if (cfg == NULL) {		const char *def_name = NULL;		if (machine_is_omap_h2())			def_name = "h2";		if (machine_is_omap_h3())			def_name = "h3";		if (machine_is_omap_osk())			def_name = "osk";		if (machine_is_omap_innovator() && cpu_is_omap1610())			def_name = "inn1610";		if (machine_is_omap_innovator() && cpu_is_omap1510())			def_name = "inn1510";		if (def_name == NULL)			return -1;		strncpy(name, def_name, sizeof(name) - 1);	} else		strncpy(name, cfg->panel_name, sizeof(name) - 1);	name[sizeof(name) - 1] = 0;	for (i = 0; i < ARRAY_SIZE(panels); i++) {		if (strcmp(panels[i]->name, name) == 0) {			fbdev->panel = panels[i];			break;		}	}	if (fbdev->panel == NULL)		return -1; 	return 0;}static int omapfb_find_ctrl(struct omapfb_device *fbdev){	const struct omap_lcd_config *cfg;	char name[17];	int i;	fbdev->ctrl = NULL;	cfg = omap_get_config(OMAP_TAG_LCD, struct omap_lcd_config);	if (cfg == NULL) {		strcpy(name, "internal");	} else		strncpy(name, cfg->ctrl_name, sizeof(name) - 1);	name[sizeof(name) - 1] = 0;	for (i = 0; i < ARRAY_SIZE(ctrls); i++) {		if (strcmp(ctrls[i]->name, name) == 0) {			fbdev->ctrl = ctrls[i];			break;		}	}	if (fbdev->ctrl == NULL)		return -1;	return 0;}/* Called by LDM binding to probe and attach a new device. * Initialization sequence: *   1. allocate system fb_info structure *      select panel type according to machine type *   2. init LCD panel *   3. init LCD controller and LCD DMA *   4. init system fb_info structure *   5. init gfx DMA *   6. enable LCD panel *      start LCD frame transfer *   7. register system fb_info structure */static int omapfb_probe(struct device *dev){	struct platform_device	*pdev;	struct omapfb_device	*fbdev = NULL;	struct fb_info		*fbi;	int			init_state;	int 			r = 0;	DBGENTER(1);	init_state = 0;	pdev = to_platform_device(dev);	if (pdev->num_resources != 0) {		PRNERR("probed for an unknown device\n");		r = -ENODEV;		goto cleanup;	}	fbi = framebuffer_alloc(sizeof(struct omapfb_device), dev);	if (!fbi) {		PRNERR("unable to allocate memory for device info\n");		r = -ENOMEM;		goto cleanup;	}	fbdev = (struct omapfb_device *)fbi->par;	fbdev->fb_info = fbi;	fbdev->dev = dev;	dev_set_drvdata(dev, fbdev);	init_state++;	if (omapfb_find_ctrl(fbdev) < 0) {		PRNERR("LCD controller not found, board not supported\n");		r = -ENODEV;		goto cleanup;	}			if (omapfb_find_panel(fbdev) < 0) {		PRNERR("LCD panel not found, board not supported\n");		r = -ENODEV;		goto cleanup;	}	printk(KERN_INFO OMAPFB_DRIVER ": configured for panel %s\n",	       fbdev->panel->name);	r = fbdev->panel->init(fbdev->panel);	if (r)		goto cleanup;	init_state++;	r = ctrl_init(fbdev);	if (r)		goto cleanup;	init_state++;	r = fbinfo_init(fbdev);	if (r)		goto cleanup;	init_state++;	r = gfxdma_init(&fbdev->gfx);	if (r)		goto cleanup;	init_state++;	r = register_framebuffer(fbdev->fb_info);	if (r != 0) {		PRNERR("register_framebuffer failed\n");		goto cleanup;	}	init_state++;#ifdef CONFIG_FB_OMAP_DMA_TUNE	/* Set DMA priority for EMIFF access to highest */	omap_set_dma_priority(OMAP_DMA_PORT_EMIFF, 15);#endif	/* Check if someone wants to activate the display on his own	 * with OMAPFB_LATE_ACTIVATE ioctl call	 */	if (!late_activate) {		r = omapfb_activate(fbdev);		if (r)			goto cleanup;	} else {		printk(KERN_INFO "omapfb: Deferring panel activation\n");		fbdev->state = OMAPFB_DEACTIVATED;	}	init_state++;	printk(KERN_INFO "OMAP framebuffer initialized. vram=%lu\n",			fbdev->lcddma_mem_size);	DBGLEAVE(1);	return 0;cleanup:	omapfb_free_resources(fbdev, init_state);	DBGLEAVE(1);	return r;}/* Called when the device is being detached from the driver */static int omapfb_remove(struct device *dev){	struct omapfb_device *fbdev = dev_get_drvdata(dev);	int state = fbdev->state;	DBGENTER(1);	/* FIXME: wait till completion of pending events */	fbdev->state = OMAPFB_DISABLED;	omapfb_free_resources(fbdev, state);	DBGLEAVE(1);	return 0;}/* PM suspend */static int omapfb_suspend(struct device *dev, u32 state, u32 level){	struct omapfb_device *fbdev = dev_get_drvdata(dev);	DBGENTER(1);	if (fbdev->ctrl->suspend)		fbdev->ctrl->suspend(fbdev);	fbdev->panel->disable(fbdev->panel);	DBGLEAVE(1);	return 0;}/* PM resume */static int omapfb_resume(struct device *dev, u32 level){	struct omapfb_device *fbdev = dev_get_drvdata(dev);	DBGENTER(1);	fbdev->panel->enable(fbdev->panel);	if (fbdev->ctrl->resume)		fbdev->ctrl->resume(fbdev);	DBGLEAVE(1);	return 0;}static void omapfb_release_dev(struct device *dev){	DBGENTER(1);	DBGLEAVE(1);}static u64 omapfb_dmamask = ~(u32)0;static struct platform_device omapfb_device = {	.name		= OMAPFB_DEVICE,	.id		= 0,	.dev = {		.release  = omapfb_release_dev,		.dma_mask = &omapfb_dmamask,		.coherent_dma_mask = 0xffffffff,	},	.num_resources = 0,};static struct device_driver omapfb_driver = {	.name   	= OMAPFB_DRIVER,	.bus		= &platform_bus_type,	.probe          = omapfb_probe,	.remove         = omapfb_remove,	.suspend	= omapfb_suspend,	.resume		= omapfb_resume};#ifndef MODULE/* Process kernel command line parameters */int __init omapfb_setup(char *options){	char *this_opt = NULL;	int r = 0;	DBGENTER(1);	if (!options || !*options)		goto exit;	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;			def_vram = (simple_strtoul(this_opt + 5, &suffix, 0));			switch (suffix[0]) {			case 'm':			case 'M':				def_vram *= 1024 * 1024;				break;			case 'k':			case 'K':				def_vram *= 1024;				break;			default:				PRNERR("invalid vram suffix\n");				r = -1;			}		}		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, "late_activate", 13))			late_activate = 1;		else {			PRNERR("invalid option\n");			r = -1;		}	}exit:	DBGLEAVE(1);	return r;}#endif/* Register both the driver and the device */int __init omapfb_init(void){	int r = 0;	DBGENTER(1);#ifndef MODULE	{		char *option;				if (fb_get_options("omapfb", &option)) {			r = -ENODEV;			goto exit;		}		omapfb_setup(option);	}#endif	/* Register the device with LDM */	if (platform_device_register(&omapfb_device)) {		PRNERR("failed to register omapfb device\n");		r = -ENODEV;		goto exit;	}	/* Register the driver with LDM */	if (driver_register(&omapfb_driver)) {		PRNERR("failed to register omapfb driver\n");		platform_device_unregister(&omapfb_device);		r = -ENODEV;		goto exit;	}exit:	DBGLEAVE(1);	return r;}static void __exit omapfb_cleanup(void){	DBGENTER(1);	driver_unregister(&omapfb_driver);	platform_device_unregister(&omapfb_device);	DBGLEAVE(1);}module_param_named(accel, def_accel, uint, 0664);module_param_named(vram, def_vram, ulong, 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(late_activate, late_activate, 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 + =
减小字号Ctrl + -
显示快捷键?