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 + -
显示快捷键?