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

📄 s1d13xxxfb.c

📁 Linux环境下视频显示卡设备的驱动程序源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
	{4, 8, 16, -1},	{9, 12, 18, -1},};/** *      s1d13xxxfb_fetch_hw_state - Configure the framebuffer according to *	hardware setup. *      @info: frame buffer structure * *	We setup the framebuffer structures according to the current *	hardware setup. On some machines, the BIOS will have filled *	the chip registers with such info, on others, these values will *	have been written in some init procedure. In any case, the *	software values needs to match the hardware ones. This is what *	this function ensures. * *	Note: some of the hardcoded values here might need some love to *	work on various chips, and might need to no longer be hardcoded. */static void __devinits1d13xxxfb_fetch_hw_state(struct fb_info *info){	struct fb_var_screeninfo *var = &info->var;	struct fb_fix_screeninfo *fix = &info->fix;	struct s1d13xxxfb_par *par = info->par;	u8 panel, display;	u16 offset;	u32 xres, yres;	u32 xres_virtual, yres_virtual;	int bpp, lcd_bpp;	int is_color, is_dual, is_tft;	int lcd_enabled, crt_enabled;	fix->type = FB_TYPE_PACKED_PIXELS;	/* general info */	par->display = s1d13xxxfb_readreg(par, S1DREG_COM_DISP_MODE);	crt_enabled = (par->display & 0x02) != 0;	lcd_enabled = (par->display & 0x01) != 0;	if (lcd_enabled && crt_enabled)		printk(KERN_WARNING PFX "Warning: LCD and CRT detected, using LCD\n");	if (lcd_enabled)		display = s1d13xxxfb_readreg(par, S1DREG_LCD_DISP_MODE);	else	/* CRT */		display = s1d13xxxfb_readreg(par, S1DREG_CRT_DISP_MODE);	bpp = display & 0x07;	switch (bpp) {		case 2:	/* 4 bpp */		case 3:	/* 8 bpp */			var->bits_per_pixel = 8;			var->red.offset = var->green.offset = var->blue.offset = 0;			var->red.length = var->green.length = var->blue.length = 8;			break;		case 5:	/* 16 bpp */			s1d13xxxfb_setup_truecolour(info);			break;		default:			dbg("bpp: %i\n", bpp);	}	fb_alloc_cmap(&info->cmap, 256, 0);	/* LCD info */	panel = s1d13xxxfb_readreg(par, S1DREG_PANEL_TYPE);	is_color = (panel & 0x04) != 0;	is_dual = (panel & 0x02) != 0;	is_tft = (panel & 0x01) != 0;	lcd_bpp = s1d13xxxfb_width_tab[is_tft][(panel >> 4) & 3];	if (lcd_enabled) {		xres = (s1d13xxxfb_readreg(par, S1DREG_LCD_DISP_HWIDTH) + 1) * 8;		yres = (s1d13xxxfb_readreg(par, S1DREG_LCD_DISP_VHEIGHT0) +			((s1d13xxxfb_readreg(par, S1DREG_LCD_DISP_VHEIGHT1) & 0x03) << 8) + 1);		offset = (s1d13xxxfb_readreg(par, S1DREG_LCD_MEM_OFF0) +			((s1d13xxxfb_readreg(par, S1DREG_LCD_MEM_OFF1) & 0x7) << 8));	} else { /* crt */		xres = (s1d13xxxfb_readreg(par, S1DREG_CRT_DISP_HWIDTH) + 1) * 8;		yres = (s1d13xxxfb_readreg(par, S1DREG_CRT_DISP_VHEIGHT0) +			((s1d13xxxfb_readreg(par, S1DREG_CRT_DISP_VHEIGHT1) & 0x03) << 8) + 1);		offset = (s1d13xxxfb_readreg(par, S1DREG_CRT_MEM_OFF0) +			((s1d13xxxfb_readreg(par, S1DREG_CRT_MEM_OFF1) & 0x7) << 8));	}	xres_virtual = offset * 16 / var->bits_per_pixel;	yres_virtual = fix->smem_len / (offset * 2);	var->xres		= xres;	var->yres		= yres;	var->xres_virtual	= xres_virtual;	var->yres_virtual	= yres_virtual;	var->xoffset		= var->yoffset = 0;	fix->line_length	= offset * 2;	var->grayscale		= !is_color;	var->activate		= FB_ACTIVATE_NOW;	dbg(PFX "bpp=%d, lcd_bpp=%d, "		"crt_enabled=%d, lcd_enabled=%d\n",		var->bits_per_pixel, lcd_bpp, crt_enabled, lcd_enabled);	dbg(PFX "xres=%d, yres=%d, vxres=%d, vyres=%d "		"is_color=%d, is_dual=%d, is_tft=%d\n",		xres, yres, xres_virtual, yres_virtual, is_color, is_dual, is_tft);}static ints1d13xxxfb_remove(struct platform_device *pdev){	struct fb_info *info = platform_get_drvdata(pdev);	struct s1d13xxxfb_par *par = NULL;	if (info) {		par = info->par;		if (par && par->regs) {			/* disable output & enable powersave */			s1d13xxxfb_writereg(par, S1DREG_COM_DISP_MODE, 0x00);			s1d13xxxfb_writereg(par, S1DREG_PS_CNF, 0x11);			iounmap(par->regs);		}		fb_dealloc_cmap(&info->cmap);		if (info->screen_base)			iounmap(info->screen_base);		framebuffer_release(info);	}	release_mem_region(pdev->resource[0].start,			pdev->resource[0].end - pdev->resource[0].start +1);	release_mem_region(pdev->resource[1].start,			pdev->resource[1].end - pdev->resource[1].start +1);	return 0;}static int __devinits1d13xxxfb_probe(struct platform_device *pdev){	struct s1d13xxxfb_par *default_par;	struct fb_info *info;	struct s1d13xxxfb_pdata *pdata = NULL;	int ret = 0;	int i;	u8 revision;	dbg("probe called: device is %p\n", pdev);	printk(KERN_INFO "Epson S1D13XXX FB Driver\n");	/* enable platform-dependent hardware glue, if any */	if (pdev->dev.platform_data)		pdata = pdev->dev.platform_data;	if (pdata && pdata->platform_init_video)		pdata->platform_init_video();	if (pdev->num_resources != 2) {		dev_err(&pdev->dev, "invalid num_resources: %i\n",		       pdev->num_resources);		ret = -ENODEV;		goto bail;	}	/* resource[0] is VRAM, resource[1] is registers */	if (pdev->resource[0].flags != IORESOURCE_MEM			|| pdev->resource[1].flags != IORESOURCE_MEM) {		dev_err(&pdev->dev, "invalid resource type\n");		ret = -ENODEV;		goto bail;	}	if (!request_mem_region(pdev->resource[0].start,		pdev->resource[0].end - pdev->resource[0].start +1, "s1d13xxxfb mem")) {		dev_dbg(&pdev->dev, "request_mem_region failed\n");		ret = -EBUSY;		goto bail;	}	if (!request_mem_region(pdev->resource[1].start,		pdev->resource[1].end - pdev->resource[1].start +1, "s1d13xxxfb regs")) {		dev_dbg(&pdev->dev, "request_mem_region failed\n");		ret = -EBUSY;		goto bail;	}	info = framebuffer_alloc(sizeof(struct s1d13xxxfb_par) + sizeof(u32) * 256, &pdev->dev);	if (!info) {		ret = -ENOMEM;		goto bail;	}	platform_set_drvdata(pdev, info);	default_par = info->par;	default_par->regs = ioremap_nocache(pdev->resource[1].start,			pdev->resource[1].end - pdev->resource[1].start +1);	if (!default_par->regs) {		printk(KERN_ERR PFX "unable to map registers\n");		ret = -ENOMEM;		goto bail;	}	info->pseudo_palette = default_par->pseudo_palette;	info->screen_base = ioremap_nocache(pdev->resource[0].start,			pdev->resource[0].end - pdev->resource[0].start +1);	if (!info->screen_base) {		printk(KERN_ERR PFX "unable to map framebuffer\n");		ret = -ENOMEM;		goto bail;	}	revision = s1d13xxxfb_readreg(default_par, S1DREG_REV_CODE) >> 2;	ret = -ENODEV;	for (i = 0; i < ARRAY_SIZE(s1d13xxxfb_revisions); i++) {		if (revision == s1d13xxxfb_revisions[i])			ret = 0;	}	if (!ret)		printk(KERN_INFO PFX "chip revision %i\n", revision);	else {		printk(KERN_INFO PFX "unknown chip revision %i\n", revision);		goto bail;	}	info->fix = s1d13xxxfb_fix;	info->fix.mmio_start = pdev->resource[1].start;	info->fix.mmio_len = pdev->resource[1].end - pdev->resource[1].start +1;	info->fix.smem_start = pdev->resource[0].start;	info->fix.smem_len = pdev->resource[0].end - pdev->resource[0].start +1;	printk(KERN_INFO PFX "regs mapped at 0x%p, fb %d KiB mapped at 0x%p\n",	       default_par->regs, info->fix.smem_len / 1024, info->screen_base);	info->par = default_par;	info->fbops = &s1d13xxxfb_fbops;	info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN;	/* perform "manual" chip initialization, if needed */	if (pdata && pdata->initregs)		s1d13xxxfb_runinit(info->par, pdata->initregs, pdata->initregssize);	s1d13xxxfb_fetch_hw_state(info);	if (register_framebuffer(info) < 0) {		ret = -EINVAL;		goto bail;	}	printk(KERN_INFO "fb%d: %s frame buffer device\n",	       info->node, info->fix.id);	return 0;bail:	s1d13xxxfb_remove(pdev);	return ret;}#ifdef CONFIG_PMstatic int s1d13xxxfb_suspend(struct platform_device *dev, pm_message_t state){	struct fb_info *info = platform_get_drvdata(dev);	struct s1d13xxxfb_par *s1dfb = info->par;	struct s1d13xxxfb_pdata *pdata = NULL;	/* disable display */	lcd_enable(s1dfb, 0);	crt_enable(s1dfb, 0);	if (dev->dev.platform_data)		pdata = dev->dev.platform_data;#if 0	if (!s1dfb->disp_save)		s1dfb->disp_save = kmalloc(info->fix.smem_len, GFP_KERNEL);	if (!s1dfb->disp_save) {		printk(KERN_ERR PFX "no memory to save screen");		return -ENOMEM;	}	memcpy_fromio(s1dfb->disp_save, info->screen_base, info->fix.smem_len);#else	s1dfb->disp_save = NULL;#endif	if (!s1dfb->regs_save)		s1dfb->regs_save = kmalloc(info->fix.mmio_len, GFP_KERNEL);	if (!s1dfb->regs_save) {		printk(KERN_ERR PFX "no memory to save registers");		return -ENOMEM;	}	/* backup all registers */	memcpy_fromio(s1dfb->regs_save, s1dfb->regs, info->fix.mmio_len);	/* now activate power save mode */	s1d13xxxfb_writereg(s1dfb, S1DREG_PS_CNF, 0x11);	if (pdata && pdata->platform_suspend_video)		return pdata->platform_suspend_video();	else		return 0;}static int s1d13xxxfb_resume(struct platform_device *dev){	struct fb_info *info = platform_get_drvdata(dev);	struct s1d13xxxfb_par *s1dfb = info->par;	struct s1d13xxxfb_pdata *pdata = NULL;	/* awaken the chip */	s1d13xxxfb_writereg(s1dfb, S1DREG_PS_CNF, 0x10);	/* do not let go until SDRAM "wakes up" */	while ((s1d13xxxfb_readreg(s1dfb, S1DREG_PS_STATUS) & 0x01))		udelay(10);	if (dev->dev.platform_data)		pdata = dev->dev.platform_data;	if (s1dfb->regs_save) {		/* will write RO regs, *should* get away with it :) */		memcpy_toio(s1dfb->regs, s1dfb->regs_save, info->fix.mmio_len);		kfree(s1dfb->regs_save);	}	if (s1dfb->disp_save) {		memcpy_toio(info->screen_base, s1dfb->disp_save,				info->fix.smem_len);		kfree(s1dfb->disp_save);	/* XXX kmalloc()'d when? */	}	if ((s1dfb->display & 0x01) != 0)		lcd_enable(s1dfb, 1);	if ((s1dfb->display & 0x02) != 0)		crt_enable(s1dfb, 1);	if (pdata && pdata->platform_resume_video)		return pdata->platform_resume_video();	else		return 0;}#endif /* CONFIG_PM */static struct platform_driver s1d13xxxfb_driver = {	.probe		= s1d13xxxfb_probe,	.remove		= s1d13xxxfb_remove,#ifdef CONFIG_PM	.suspend	= s1d13xxxfb_suspend,	.resume		= s1d13xxxfb_resume,#endif	.driver		= {		.name	= S1D_DEVICENAME,	},};static int __inits1d13xxxfb_init(void){#ifndef MODULE	if (fb_get_options("s1d13xxxfb", NULL))		return -ENODEV;#endif	return platform_driver_register(&s1d13xxxfb_driver);}static void __exits1d13xxxfb_exit(void){	platform_driver_unregister(&s1d13xxxfb_driver);}module_init(s1d13xxxfb_init);module_exit(s1d13xxxfb_exit);MODULE_LICENSE("GPL");MODULE_DESCRIPTION("Framebuffer driver for S1D13xxx devices");MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>, Thibaut VARENE <varenet@parisc-linux.org>");

⌨️ 快捷键说明

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