📄 davincifb.c
字号:
dispc_reg_out(VENC_YCCCTL, 0x1); /* Enable output mode and PAL */ dispc_reg_out(VENC_VMOD, 0x1043); /* Enable all DACs */ dispc_reg_out(VENC_DACTST, 0); } else { /* Reset video encoder module */ dispc_reg_out(VENC_VMOD, 0); } DBGEXIT;}static void davincifb_pal_svideo_config(int on){ DBGENTER; if (on) { /* Reset video encoder module */ dispc_reg_out(VENC_VMOD, 0); /* Enable Composite output and start video encoder */ dispc_reg_out(VENC_VMOD, (VENC_VMOD_VIE | VENC_VMOD_VENC)); /* Set REC656 Mode */ dispc_reg_out(VENC_YCCCTL, 0x1); /* Enable output mode and PAL */ dispc_reg_out(VENC_VMOD, 0x1043); /* Enable S-Video Output; DAC B: S-Video Y, DAC C: S-Video C */ dispc_reg_out(VENC_DACSEL, 0x210); /* Enable all DACs */ dispc_reg_out(VENC_DACTST, 0); } else { /* Reset video encoder module */ dispc_reg_out(VENC_VMOD, 0); } DBGEXIT;}static void davincifb_pal_component_config(int on){ DBGENTER; if (on) { /* Reset video encoder module */ dispc_reg_out(VENC_VMOD, 0); /* Enable Composite output and start video encoder */ dispc_reg_out(VENC_VMOD, (VENC_VMOD_VIE | VENC_VMOD_VENC)); /* Set REC656 Mode */ dispc_reg_out(VENC_YCCCTL, 0x1); /* Enable output mode and PAL */ dispc_reg_out(VENC_VMOD, 0x1043); /* Enable Component output; DAC A: Y, DAC B: Pb, DAC C: Pr */ dispc_reg_out(VENC_DACSEL, 0x543); /* Enable all DACs */ dispc_reg_out(VENC_DACTST, 0); } else { /* Reset video encoder module */ dispc_reg_out(VENC_VMOD, 0); } DBGEXIT;}static inline void fix_default_var(struct dm_win_info *w, u32 xres, u32 yres, u32 xpos, u32 ypos, int n_buf){ struct fb_var_screeninfo *v = &w->info.var; v->xres = xres; v->yres = yres; v->xres_virtual = v->xres; v->yres_virtual = v->yres * n_buf; x_pos(w) = xpos; y_pos(w) = ypos;}/* * Cleanup */static int davincifb_remove(struct device *dev){ DBGENTER; free_irq(IRQ_VENCINT, &dm); /* Cleanup all framebuffers */ if (dm->osd0) { unregister_framebuffer(&dm->osd0->info); mem_release(dm->osd0); } if (dm->osd1) { unregister_framebuffer(&dm->osd1->info); mem_release(dm->osd1); } if (dm->vid0) { unregister_framebuffer(&dm->vid0->info); mem_release(dm->vid0); } if (dm->vid1) { unregister_framebuffer(&dm->vid1->info); mem_release(dm->vid1); } /* Turn OFF the output device */ dm->output_device_config(0); if (dm->mmio_base) iounmap((void *)dm->mmio_base); release_mem_region(dm->mmio_base_phys, dm->mmio_size); DBGEXIT; return 0;}/* * Initialization */static int davincifb_probe(struct device *dev){ struct platform_device *pdev; struct fb_info *info; DBGENTER; pdev = to_platform_device(dev); if (pdev->num_resources != 0) { dev_err(dev, "probed for an unknown device\n"); return -ENODEV; } if (dmparams.windows == 0) return 0; /* user disabled all windows through bootargs */ dm->dev = dev; dm->mmio_base_phys = OSD_REG_BASE; dm->mmio_size = OSD_REG_SIZE; if (!request_mem_region (dm->mmio_base_phys, dm->mmio_size, DAVINCIFB_DRIVER)) { dev_err(dev, ": cannot reserve MMIO region\n"); RETURN(-ENODEV); } /* map the regions */ dm->mmio_base = (unsigned long)ioremap(dm->mmio_base_phys, dm->mmio_size); if (!dm->mmio_base) { dev_err(dev, ": cannot map MMIO\n"); goto release_mmio; } /* initialize the vsync wait queue */ init_waitqueue_head(&dm->vsync_wait); dm->timeout = HZ / 5; if ((dmparams.output == NTSC) && (dmparams.format == COMPOSITE)) dm->output_device_config = davincifb_ntsc_composite_config; else if ((dmparams.output == NTSC) && (dmparams.format == SVIDEO)) dm->output_device_config = davincifb_ntsc_svideo_config; else if ((dmparams.output == NTSC) && (dmparams.format == COMPONENT)) dm->output_device_config = davincifb_ntsc_component_config; else if ((dmparams.output == PAL) && (dmparams.format == COMPOSITE)) dm->output_device_config = davincifb_pal_composite_config; else if ((dmparams.output == PAL) && (dmparams.format == SVIDEO)) dm->output_device_config = davincifb_pal_svideo_config; else if ((dmparams.output == PAL) && (dmparams.format == COMPONENT)) dm->output_device_config = davincifb_pal_component_config; /* Add support for other displays here */ else { printk(KERN_WARNING "Unsupported output device!\n"); dm->output_device_config = NULL; } printk("Setting Up Clocks for DM420 OSD\n"); /* Initialize the VPSS Clock Control register */ dispc_reg_out(VPSS_CLKCTL, 0x18); /* Set Base Pixel X and Base Pixel Y */ dispc_reg_out(OSD_BASEPX, BASEX); dispc_reg_out(OSD_BASEPY, BASEY); /* Reset OSD registers to default. */ dispc_reg_out(OSD_MODE, 0); dispc_reg_out(OSD_OSDWIN0MD, 0); /* Set blue background color */ set_bg_color(0, 162); /* Field Inversion Workaround */ dispc_reg_out(OSD_MODE, 0x200); /* Setup VID0 framebuffer */ if (!(dmparams.windows & (1 << VID0))) { printk(KERN_WARNING "No video/osd windows will be enabled " "because Video0 is disabled\n"); return 0; /* background will still be shown */ } /* Setup VID0 framebuffer */ if (!mem_alloc(&dm->vid0, VID0_FB_PHY, VID0_FB_SIZE, VID0_FBNAME)) { dm->vid0->dm = dm; fix_default_var(dm->vid0, dmparams.vid0_xres, dmparams.vid0_yres, dmparams.vid0_xpos, dmparams.vid0_ypos, TRIPLE_BUF); info = init_fb_info(dm->vid0, &vid0_default_var, VID0_FBNAME); if (davincifb_check_var(&info->var, info)) { dev_err(dev, ": invalid default video mode\n"); goto exit; } memset((void *)dm->vid0->fb_base, 0x88, dm->vid0->fb_size); } else goto exit; /* Setup OSD0 framebuffer */ if ((dmparams.windows & (1 << OSD0)) && (!mem_alloc(&dm->osd0, OSD0_FB_PHY, OSD0_FB_SIZE, OSD0_FBNAME))) { dm->osd0->dm = dm; fix_default_var(dm->osd0, dmparams.osd0_xres, dmparams.osd0_yres, dmparams.osd0_xpos, dmparams.osd0_ypos, DOUBLE_BUF); info = init_fb_info(dm->osd0, &osd0_default_var, OSD0_FBNAME); if (davincifb_check_var(&info->var, info)) { dev_err(dev, ": invalid default video mode\n"); mem_release(dm->osd0); } else memset((void *)dm->osd0->fb_base, 0, dm->osd0->fb_size); } /* Setup OSD1 framebuffer */ if ((dmparams.windows & (1 << OSD1)) && (!mem_alloc(&dm->osd1, OSD1_FB_PHY, OSD1_FB_SIZE, OSD1_FBNAME))) { dm->osd1->dm = dm; fix_default_var(dm->osd1, dmparams.osd1_xres, dmparams.osd1_yres, dmparams.osd1_xpos, dmparams.osd1_ypos, DOUBLE_BUF); info = init_fb_info(dm->osd1, &osd1_default_var, OSD1_FBNAME); if (davincifb_check_var(&info->var, info)) { dev_err(dev, ": invalid default video mode\n"); mem_release(dm->osd1); } else /* Set blend factor to show OSD windows */ memset((void *)dm->osd1->fb_base, 0xff, dm->osd1->fb_size); } /* Setup VID1 framebuffer */ if ((dmparams.windows & (1 << VID1)) && (!mem_alloc(&dm->vid1, VID1_FB_PHY, VID1_FB_SIZE, VID1_FBNAME))) { dm->vid1->dm = dm; fix_default_var(dm->vid1, dmparams.vid1_xres, dmparams.vid1_yres, dmparams.vid1_xpos, dmparams.vid1_ypos, TRIPLE_BUF); info = init_fb_info(dm->vid1, &vid1_default_var, VID1_FBNAME); if (davincifb_check_var(&info->var, info)) { dev_err(dev, VID1_FBNAME ": invalid default video mode\n"); mem_release(dm->vid1); } else memset((void *)dm->vid1->fb_base, 0x88, dm->vid1->fb_size); } /* Register OSD0 framebuffer */ if (dm->osd0) { info = &dm->osd0->info; if (register_framebuffer(info) < 0) { dev_err(dev, OSD0_FBNAME "Unable to register OSD0 framebuffer\n"); mem_release(dm->osd0); } else { printk(KERN_INFO "fb%d: %s frame buffer device\n", info->node, info->fix.id); davincifb_set_par(info); } } /* Register VID0 framebuffer */ info = &dm->vid0->info; if (register_framebuffer(info) < 0) { dev_err(dev, VID0_FBNAME "Unable to register VID0 framebuffer\n"); goto exit; } else { printk(KERN_INFO "fb%d: %s frame buffer device\n", info->node, info->fix.id); davincifb_set_par(info); } /* Register OSD1 framebuffer */ if (dm->osd1) { info = &dm->osd1->info; if (register_framebuffer(info) < 0) { dev_err(dev, OSD1_FBNAME "Unable to register OSD1 framebuffer\n"); mem_release(dm->osd1); } else { printk(KERN_INFO "fb%d: %s frame buffer device\n", info->node, info->fix.id); davincifb_set_par(info); } } /* Register VID1 framebuffer */ if (dm->vid1) { info = &dm->vid1->info; if (register_framebuffer(info) < 0) { mem_release(dm->vid1); dev_err(dev, VID1_FBNAME "Unable to register VID1 framebuffer\n"); mem_release(dm->vid1); } else { printk(KERN_INFO "fb%d: %s frame buffer device\n", info->node, info->fix.id); davincifb_set_par(info); } } /* install our interrupt service routine */ if (request_irq(IRQ_VENCINT, davincifb_isr, SA_SHIRQ, DAVINCIFB_DRIVER, dm)) { dev_err(dev, DAVINCIFB_DRIVER ": could not install interrupt service routine\n"); goto exit; } /* Turn ON the output device */ dm->output_device_config(1); RETURN(0); exit: davincifb_remove(dev); iounmap((void *)dm->mmio_base); release_mmio: release_mem_region(dm->mmio_base_phys, dm->mmio_size); RETURN(-ENODEV);}/* ------------------------------------------------------------------------- */ /* * Frame buffer operations */static struct fb_ops davincifb_ops = { .owner = THIS_MODULE, .fb_check_var = davincifb_check_var, .fb_set_par = davincifb_set_par, .fb_setcolreg = davincifb_setcolreg, .fb_blank = davincifb_blank, .fb_pan_display = davincifb_pan_display, .fb_fillrect = cfb_fillrect, .fb_copyarea = cfb_copyarea, .fb_imageblit = cfb_imageblit, .fb_cursor = soft_cursor, .fb_rotate = NULL, .fb_sync = NULL, .fb_ioctl = davincifb_ioctl,};static void davincifb_release_dev(struct device *dev){}static u64 davincifb_dmamask = ~(u32) 0;static struct platform_device davincifb_device = { .name = DAVINCIFB_DEVICE, .id = 0, .dev = { .release = davincifb_release_dev, .dma_mask = &davincifb_dmamask, .coherent_dma_mask = 0xffffffff, }, .num_resources = 0,};static struct device_driver davincifb_driver = { .name = DAVINCIFB_DRIVER, .bus = &platform_bus_type, .probe = davincifb_probe, .remove = davincifb_remove, .suspend = NULL, .resume = NULL,};/* Register both the driver and the device */int __init davincifb_init(void){ int r = 0; struct device *dev = &davincifb_device.dev; DBGENTER;#ifndef MODULE { /* handle options for "dm64xxfb" for backwards compatability */ char *option; char *names[] = { "davincifb", "dm64xxfb" }; int i, num_names = 2, done = 0; for (i = 0; i < num_names && !done; i++) { if (fb_get_options(names[i], &option)) { printk(DAVINCIFB_DRIVER ": Disabled on command-line.\n"); r = -ENODEV; goto exit; } else if (option) { davincifb_setup(option); done = 1; } } }#endif /* Register the device with LDM */ if (platform_device_register(&davincifb_device)) { dev_err(dev, "failed to register davincifb device\n"); r = -ENODEV; goto exit; } /* Register the driver with LDM */ if (driver_register(&davincifb_driver)) { dev_err(dev, "failed to register davincifb driver\n"); platform_device_unregister(&davincifb_device); r = -ENODEV; goto exit; } exit: DBGEXIT; return r;}static void __exit davincifb_cleanup(void){ DBGENTER; driver_unregister(&davincifb_driver); platform_device_unregister(&davincifb_device); DBGEXIT;}module_init(davincifb_init);module_exit(davincifb_cleanup);MODULE_DESCRIPTION("Framebuffer driver for TI DaVinci");MODULE_AUTHOR("Texas Instruments");MODULE_LICENSE("GPL");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -